JSON for Modern C++  3.9.1
json.hpp
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.9.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48 
49 // #include <nlohmann/adl_serializer.hpp>
50 
51 
52 #include <utility>
53 
54 // #include <nlohmann/detail/conversions/from_json.hpp>
55 
56 
57 #include <algorithm> // transform
58 #include <array> // array
59 #include <forward_list> // forward_list
60 #include <iterator> // inserter, front_inserter, end
61 #include <map> // map
62 #include <string> // string
63 #include <tuple> // tuple, make_tuple
64 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65 #include <unordered_map> // unordered_map
66 #include <utility> // pair, declval
67 #include <valarray> // valarray
68 
69 // #include <nlohmann/detail/exceptions.hpp>
70 
71 
72 #include <exception> // exception
73 #include <stdexcept> // runtime_error
74 #include <string> // to_string
75 
76 // #include <nlohmann/detail/input/position_t.hpp>
77 
78 
79 #include <cstddef> // size_t
80 
81 namespace nlohmann
82 {
83 namespace detail
84 {
86 struct position_t
87 {
89  std::size_t chars_read_total = 0;
91  std::size_t chars_read_current_line = 0;
93  std::size_t lines_read = 0;
94 
96  constexpr operator size_t() const
97  {
98  return chars_read_total;
99  }
100 };
101 
102 } // namespace detail
103 } // namespace nlohmann
104 
105 // #include <nlohmann/detail/macro_scope.hpp>
106 
107 
108 #include <utility> // pair
109 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
110 /* Hedley - https://nemequ.github.io/hedley
111  * Created by Evan Nemerson <evan@nemerson.com>
112  *
113  * To the extent possible under law, the author(s) have dedicated all
114  * copyright and related and neighboring rights to this software to
115  * the public domain worldwide. This software is distributed without
116  * any warranty.
117  *
118  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
119  * SPDX-License-Identifier: CC0-1.0
120  */
121 
122 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
123 #if defined(JSON_HEDLEY_VERSION)
124  #undef JSON_HEDLEY_VERSION
125 #endif
126 #define JSON_HEDLEY_VERSION 13
127 
128 #if defined(JSON_HEDLEY_STRINGIFY_EX)
129  #undef JSON_HEDLEY_STRINGIFY_EX
130 #endif
131 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
132 
133 #if defined(JSON_HEDLEY_STRINGIFY)
134  #undef JSON_HEDLEY_STRINGIFY
135 #endif
136 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
137 
138 #if defined(JSON_HEDLEY_CONCAT_EX)
139  #undef JSON_HEDLEY_CONCAT_EX
140 #endif
141 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
142 
143 #if defined(JSON_HEDLEY_CONCAT)
144  #undef JSON_HEDLEY_CONCAT
145 #endif
146 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
147 
148 #if defined(JSON_HEDLEY_CONCAT3_EX)
149  #undef JSON_HEDLEY_CONCAT3_EX
150 #endif
151 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
152 
153 #if defined(JSON_HEDLEY_CONCAT3)
154  #undef JSON_HEDLEY_CONCAT3
155 #endif
156 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
157 
158 #if defined(JSON_HEDLEY_VERSION_ENCODE)
159  #undef JSON_HEDLEY_VERSION_ENCODE
160 #endif
161 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
162 
163 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
164  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
165 #endif
166 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
167 
168 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
169  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
170 #endif
171 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
172 
173 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
174  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
175 #endif
176 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
177 
178 #if defined(JSON_HEDLEY_GNUC_VERSION)
179  #undef JSON_HEDLEY_GNUC_VERSION
180 #endif
181 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
182  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
183 #elif defined(__GNUC__)
184  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
185 #endif
186 
187 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
188  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
189 #endif
190 #if defined(JSON_HEDLEY_GNUC_VERSION)
191  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
192 #else
193  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
194 #endif
195 
196 #if defined(JSON_HEDLEY_MSVC_VERSION)
197  #undef JSON_HEDLEY_MSVC_VERSION
198 #endif
199 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
200  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
201 #elif defined(_MSC_FULL_VER)
202  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
203 #elif defined(_MSC_VER)
204  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
205 #endif
206 
207 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
208  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
209 #endif
210 #if !defined(_MSC_VER)
211  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
212 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
213  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
214 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
215  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
216 #else
217  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
218 #endif
219 
220 #if defined(JSON_HEDLEY_INTEL_VERSION)
221  #undef JSON_HEDLEY_INTEL_VERSION
222 #endif
223 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
224  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
225 #elif defined(__INTEL_COMPILER)
226  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
227 #endif
228 
229 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
230  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
231 #endif
232 #if defined(JSON_HEDLEY_INTEL_VERSION)
233  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
234 #else
235  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
236 #endif
237 
238 #if defined(JSON_HEDLEY_PGI_VERSION)
239  #undef JSON_HEDLEY_PGI_VERSION
240 #endif
241 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
242  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
243 #endif
244 
245 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
246  #undef JSON_HEDLEY_PGI_VERSION_CHECK
247 #endif
248 #if defined(JSON_HEDLEY_PGI_VERSION)
249  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
250 #else
251  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
252 #endif
253 
254 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
255  #undef JSON_HEDLEY_SUNPRO_VERSION
256 #endif
257 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
258  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
259 #elif defined(__SUNPRO_C)
260  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
261 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
262  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
263 #elif defined(__SUNPRO_CC)
264  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
265 #endif
266 
267 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
268  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
269 #endif
270 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
271  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
272 #else
273  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
274 #endif
275 
276 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
277  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
278 #endif
279 #if defined(__EMSCRIPTEN__)
280  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
281 #endif
282 
283 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
284  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
285 #endif
286 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
287  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
288 #else
289  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
290 #endif
291 
292 #if defined(JSON_HEDLEY_ARM_VERSION)
293  #undef JSON_HEDLEY_ARM_VERSION
294 #endif
295 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
296  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
297 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
298  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
299 #endif
300 
301 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
302  #undef JSON_HEDLEY_ARM_VERSION_CHECK
303 #endif
304 #if defined(JSON_HEDLEY_ARM_VERSION)
305  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
306 #else
307  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
308 #endif
309 
310 #if defined(JSON_HEDLEY_IBM_VERSION)
311  #undef JSON_HEDLEY_IBM_VERSION
312 #endif
313 #if defined(__ibmxl__)
314  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
315 #elif defined(__xlC__) && defined(__xlC_ver__)
316  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
317 #elif defined(__xlC__)
318  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
319 #endif
320 
321 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
322  #undef JSON_HEDLEY_IBM_VERSION_CHECK
323 #endif
324 #if defined(JSON_HEDLEY_IBM_VERSION)
325  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
326 #else
327  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
328 #endif
329 
330 #if defined(JSON_HEDLEY_TI_VERSION)
331  #undef JSON_HEDLEY_TI_VERSION
332 #endif
333 #if \
334  defined(__TI_COMPILER_VERSION__) && \
335  ( \
336  defined(__TMS470__) || defined(__TI_ARM__) || \
337  defined(__MSP430__) || \
338  defined(__TMS320C2000__) \
339  )
340 #if (__TI_COMPILER_VERSION__ >= 16000000)
341  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
342 #endif
343 #endif
344 
345 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
346  #undef JSON_HEDLEY_TI_VERSION_CHECK
347 #endif
348 #if defined(JSON_HEDLEY_TI_VERSION)
349  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
350 #else
351  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
352 #endif
353 
354 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
355  #undef JSON_HEDLEY_TI_CL2000_VERSION
356 #endif
357 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
358  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
359 #endif
360 
361 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
362  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
363 #endif
364 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
365  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366 #else
367  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
368 #endif
369 
370 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
371  #undef JSON_HEDLEY_TI_CL430_VERSION
372 #endif
373 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
374  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
375 #endif
376 
377 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
378  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
379 #endif
380 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
381  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
382 #else
383  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
384 #endif
385 
386 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
387  #undef JSON_HEDLEY_TI_ARMCL_VERSION
388 #endif
389 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
390  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
391 #endif
392 
393 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
394  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
395 #endif
396 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
397  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
398 #else
399  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
400 #endif
401 
402 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
403  #undef JSON_HEDLEY_TI_CL6X_VERSION
404 #endif
405 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
406  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
407 #endif
408 
409 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
410  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
411 #endif
412 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
413  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
414 #else
415  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
416 #endif
417 
418 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
419  #undef JSON_HEDLEY_TI_CL7X_VERSION
420 #endif
421 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
422  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
423 #endif
424 
425 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
426  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
427 #endif
428 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
429  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430 #else
431  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
432 #endif
433 
434 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
435  #undef JSON_HEDLEY_TI_CLPRU_VERSION
436 #endif
437 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
438  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439 #endif
440 
441 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
442  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
445  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_CRAY_VERSION)
451  #undef JSON_HEDLEY_CRAY_VERSION
452 #endif
453 #if defined(_CRAYC)
454  #if defined(_RELEASE_PATCHLEVEL)
455  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
456  #else
457  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
458  #endif
459 #endif
460 
461 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
462  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
463 #endif
464 #if defined(JSON_HEDLEY_CRAY_VERSION)
465  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
466 #else
467  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
468 #endif
469 
470 #if defined(JSON_HEDLEY_IAR_VERSION)
471  #undef JSON_HEDLEY_IAR_VERSION
472 #endif
473 #if defined(__IAR_SYSTEMS_ICC__)
474  #if __VER__ > 1000
475  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
476  #else
477  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
478  #endif
479 #endif
480 
481 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
482  #undef JSON_HEDLEY_IAR_VERSION_CHECK
483 #endif
484 #if defined(JSON_HEDLEY_IAR_VERSION)
485  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
486 #else
487  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
488 #endif
489 
490 #if defined(JSON_HEDLEY_TINYC_VERSION)
491  #undef JSON_HEDLEY_TINYC_VERSION
492 #endif
493 #if defined(__TINYC__)
494  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
495 #endif
496 
497 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
498  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
499 #endif
500 #if defined(JSON_HEDLEY_TINYC_VERSION)
501  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
502 #else
503  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
504 #endif
505 
506 #if defined(JSON_HEDLEY_DMC_VERSION)
507  #undef JSON_HEDLEY_DMC_VERSION
508 #endif
509 #if defined(__DMC__)
510  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
511 #endif
512 
513 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
514  #undef JSON_HEDLEY_DMC_VERSION_CHECK
515 #endif
516 #if defined(JSON_HEDLEY_DMC_VERSION)
517  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
518 #else
519  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
520 #endif
521 
522 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
523  #undef JSON_HEDLEY_COMPCERT_VERSION
524 #endif
525 #if defined(__COMPCERT_VERSION__)
526  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
527 #endif
528 
529 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
530  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
533  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537 
538 #if defined(JSON_HEDLEY_PELLES_VERSION)
539  #undef JSON_HEDLEY_PELLES_VERSION
540 #endif
541 #if defined(__POCC__)
542  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
543 #endif
544 
545 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
546  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
547 #endif
548 #if defined(JSON_HEDLEY_PELLES_VERSION)
549  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
550 #else
551  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
552 #endif
553 
554 #if defined(JSON_HEDLEY_GCC_VERSION)
555  #undef JSON_HEDLEY_GCC_VERSION
556 #endif
557 #if \
558  defined(JSON_HEDLEY_GNUC_VERSION) && \
559  !defined(__clang__) && \
560  !defined(JSON_HEDLEY_INTEL_VERSION) && \
561  !defined(JSON_HEDLEY_PGI_VERSION) && \
562  !defined(JSON_HEDLEY_ARM_VERSION) && \
563  !defined(JSON_HEDLEY_TI_VERSION) && \
564  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
565  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
566  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
567  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
568  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
569  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
570  !defined(__COMPCERT__)
571  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
572 #endif
573 
574 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
575  #undef JSON_HEDLEY_GCC_VERSION_CHECK
576 #endif
577 #if defined(JSON_HEDLEY_GCC_VERSION)
578  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
579 #else
580  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
581 #endif
582 
583 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
584  #undef JSON_HEDLEY_HAS_ATTRIBUTE
585 #endif
586 #if defined(__has_attribute)
587  #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
588 #else
589  #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
590 #endif
591 
592 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
593  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
594 #endif
595 #if defined(__has_attribute)
596  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
597 #else
598  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
599 #endif
600 
601 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
602  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
603 #endif
604 #if defined(__has_attribute)
605  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
606 #else
607  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
608 #endif
609 
610 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
611  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
612 #endif
613 #if \
614  defined(__has_cpp_attribute) && \
615  defined(__cplusplus) && \
616  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
617  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
618 #else
619  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
620 #endif
621 
622 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
623  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
624 #endif
625 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
626  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
627 #elif \
628  !defined(JSON_HEDLEY_PGI_VERSION) && \
629  !defined(JSON_HEDLEY_IAR_VERSION) && \
630  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
631  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
632  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
633 #else
634  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
635 #endif
636 
637 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
638  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
639 #endif
640 #if defined(__has_cpp_attribute) && defined(__cplusplus)
641  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
642 #else
643  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
644 #endif
645 
646 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
647  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
648 #endif
649 #if defined(__has_cpp_attribute) && defined(__cplusplus)
650  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
651 #else
652  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
653 #endif
654 
655 #if defined(JSON_HEDLEY_HAS_BUILTIN)
656  #undef JSON_HEDLEY_HAS_BUILTIN
657 #endif
658 #if defined(__has_builtin)
659  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
660 #else
661  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
662 #endif
663 
664 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
665  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
666 #endif
667 #if defined(__has_builtin)
668  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
669 #else
670  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
671 #endif
672 
673 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
674  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
675 #endif
676 #if defined(__has_builtin)
677  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
678 #else
679  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
680 #endif
681 
682 #if defined(JSON_HEDLEY_HAS_FEATURE)
683  #undef JSON_HEDLEY_HAS_FEATURE
684 #endif
685 #if defined(__has_feature)
686  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
687 #else
688  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
689 #endif
690 
691 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
692  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
693 #endif
694 #if defined(__has_feature)
695  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
696 #else
697  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
698 #endif
699 
700 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
701  #undef JSON_HEDLEY_GCC_HAS_FEATURE
702 #endif
703 #if defined(__has_feature)
704  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
705 #else
706  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
707 #endif
708 
709 #if defined(JSON_HEDLEY_HAS_EXTENSION)
710  #undef JSON_HEDLEY_HAS_EXTENSION
711 #endif
712 #if defined(__has_extension)
713  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
714 #else
715  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
716 #endif
717 
718 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
719  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
720 #endif
721 #if defined(__has_extension)
722  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
723 #else
724  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
725 #endif
726 
727 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
728  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
729 #endif
730 #if defined(__has_extension)
731  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
732 #else
733  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
734 #endif
735 
736 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
737  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
738 #endif
739 #if defined(__has_declspec_attribute)
740  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
741 #else
742  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
743 #endif
744 
745 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
746  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
747 #endif
748 #if defined(__has_declspec_attribute)
749  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
750 #else
751  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
752 #endif
753 
754 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
755  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
756 #endif
757 #if defined(__has_declspec_attribute)
758  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
759 #else
760  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
761 #endif
762 
763 #if defined(JSON_HEDLEY_HAS_WARNING)
764  #undef JSON_HEDLEY_HAS_WARNING
765 #endif
766 #if defined(__has_warning)
767  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
768 #else
769  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
770 #endif
771 
772 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
773  #undef JSON_HEDLEY_GNUC_HAS_WARNING
774 #endif
775 #if defined(__has_warning)
776  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
777 #else
778  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
779 #endif
780 
781 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
782  #undef JSON_HEDLEY_GCC_HAS_WARNING
783 #endif
784 #if defined(__has_warning)
785  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
786 #else
787  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
788 #endif
789 
790 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
791  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
792 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
793  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
794 #endif
795 #if defined(__cplusplus)
796 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
797 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
798 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
799  JSON_HEDLEY_DIAGNOSTIC_PUSH \
800  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
801  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
802  xpr \
803  JSON_HEDLEY_DIAGNOSTIC_POP
804 # else
805 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
806  JSON_HEDLEY_DIAGNOSTIC_PUSH \
807  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
808  xpr \
809  JSON_HEDLEY_DIAGNOSTIC_POP
810 # endif
811 # endif
812 #endif
813 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
814  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
815 #endif
816 
817 #if defined(JSON_HEDLEY_CONST_CAST)
818  #undef JSON_HEDLEY_CONST_CAST
819 #endif
820 #if defined(__cplusplus)
821 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
822 #elif \
823  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
824  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
825  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
826 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
827  JSON_HEDLEY_DIAGNOSTIC_PUSH \
828  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
829  ((T) (expr)); \
830  JSON_HEDLEY_DIAGNOSTIC_POP \
831  }))
832 #else
833 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
834 #endif
835 
836 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
837  #undef JSON_HEDLEY_REINTERPRET_CAST
838 #endif
839 #if defined(__cplusplus)
840  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
841 #else
842  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
843 #endif
844 
845 #if defined(JSON_HEDLEY_STATIC_CAST)
846  #undef JSON_HEDLEY_STATIC_CAST
847 #endif
848 #if defined(__cplusplus)
849  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
850 #else
851  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
852 #endif
853 
854 #if defined(JSON_HEDLEY_CPP_CAST)
855  #undef JSON_HEDLEY_CPP_CAST
856 #endif
857 #if defined(__cplusplus)
858 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
859 # define JSON_HEDLEY_CPP_CAST(T, expr) \
860  JSON_HEDLEY_DIAGNOSTIC_PUSH \
861  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
862  ((T) (expr)) \
863  JSON_HEDLEY_DIAGNOSTIC_POP
864 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
865 # define JSON_HEDLEY_CPP_CAST(T, expr) \
866  JSON_HEDLEY_DIAGNOSTIC_PUSH \
867  _Pragma("diag_suppress=Pe137") \
868  JSON_HEDLEY_DIAGNOSTIC_POP \
869 # else
870 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
871 # endif
872 #else
873 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
874 #endif
875 
876 #if \
877  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
878  defined(__clang__) || \
879  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
880  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
881  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
882  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
883  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
884  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
885  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
886  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
887  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
888  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
889  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
890  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
891  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
892  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
893  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
894  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
895  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
896 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
897  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
898 #else
899  #define JSON_HEDLEY_PRAGMA(value)
900 #endif
901 
902 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
903  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
904 #endif
905 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
906  #undef JSON_HEDLEY_DIAGNOSTIC_POP
907 #endif
908 #if defined(__clang__)
909  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
910  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
911 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
912  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
913  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
914 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
915  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
916  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
917 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
918  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
919  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
920 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
921  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
922  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
923 #elif \
924  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
925  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
926  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
927  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
928  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
929  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
930  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
931  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
932 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
933  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
934  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
935 #else
936  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
937  #define JSON_HEDLEY_DIAGNOSTIC_POP
938 #endif
939 
940 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
941  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
942 #endif
943 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
944  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
945 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
946  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
947 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
948  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
949 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
950  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
951 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
952  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
953 #elif \
954  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
955  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
956  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
957  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
958  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
959  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
960  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
961  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
962  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
963  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
964  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
965  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
966 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
967  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
968 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
969  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
970 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
971  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
972 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
973  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
974 #else
975  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
976 #endif
977 
978 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
979  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
980 #endif
981 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
982  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
983 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
984  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
985 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
986  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
987 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
988  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
989 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
990  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
991 #elif \
992  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
993  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
994  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
995  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
996  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
997 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
998  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
999 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1000  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1001 #else
1002  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1003 #endif
1004 
1005 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1006  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1007 #endif
1008 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1009  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1010 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1011  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1012 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1013  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1014 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1015  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1016 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1017  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1018 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1019  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1020 #elif \
1021  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1022  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1023  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1024  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1025 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1026  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1027 #else
1028  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1029 #endif
1030 
1031 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1032  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1033 #endif
1034 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1035  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1036 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1037  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1038 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1039  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1040 #else
1041  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1042 #endif
1043 
1044 #if defined(JSON_HEDLEY_DEPRECATED)
1045  #undef JSON_HEDLEY_DEPRECATED
1046 #endif
1047 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1048  #undef JSON_HEDLEY_DEPRECATED_FOR
1049 #endif
1050 #if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
1051  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1052  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1053 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1054  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1055  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1056 #elif \
1057  JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1058  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1059  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1060  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1061  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1062  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1063  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1064  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1065  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1066  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1067  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1068  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1069  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1070 #elif \
1071  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1072  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1073  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1074  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1086  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1087 #elif \
1088  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1089  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
1090  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1091  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1092 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1093  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1094  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1095 #else
1096  #define JSON_HEDLEY_DEPRECATED(since)
1097  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1098 #endif
1099 
1100 #if defined(JSON_HEDLEY_UNAVAILABLE)
1101  #undef JSON_HEDLEY_UNAVAILABLE
1102 #endif
1103 #if \
1104  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1105  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1106  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1107  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1108 #else
1109  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1110 #endif
1111 
1112 #if defined()
1113  #undef
1114 #endif
1115 #if defined(_MSG)
1116  #undef _MSG
1117 #endif
1118 #if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1119  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1120  #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1121 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1122  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1123  #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1124 #elif \
1125  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1126  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1127  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1128  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1129  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1130  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1131  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1132  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1133  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1134  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1135  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1136  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1137  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1138  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1139  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1140  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1141  #define __attribute__((__warn_unused_result__))
1142  #define _MSG(msg) __attribute__((__warn_unused_result__))
1143 #elif defined(_Check_return_) /* SAL */
1144  #define _Check_return_
1145  #define _MSG(msg) _Check_return_
1146 #else
1147  #define
1148  #define _MSG(msg)
1149 #endif
1150 
1151 #if defined(JSON_HEDLEY_SENTINEL)
1152  #undef JSON_HEDLEY_SENTINEL
1153 #endif
1154 #if \
1155  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1156  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1157  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1158  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1159  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1160 #else
1161  #define JSON_HEDLEY_SENTINEL(position)
1162 #endif
1163 
1164 #if defined(JSON_HEDLEY_NO_RETURN)
1165  #undef JSON_HEDLEY_NO_RETURN
1166 #endif
1167 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1168  #define JSON_HEDLEY_NO_RETURN __noreturn
1169 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1170  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1171 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1172  #define JSON_HEDLEY_NO_RETURN _Noreturn
1173 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1174  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1175 #elif \
1176  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1177  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1178  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1179  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1180  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1181  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1182  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1183  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1184  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1185  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1186  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1187  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1188  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1189  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1190  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1191  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1192  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1193 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1194  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1195 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1196  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1197 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1198  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1199 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1200  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1201 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1202  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1203 #else
1204  #define JSON_HEDLEY_NO_RETURN
1205 #endif
1206 
1207 #if defined(JSON_HEDLEY_NO_ESCAPE)
1208  #undef JSON_HEDLEY_NO_ESCAPE
1209 #endif
1210 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1211  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1212 #else
1213  #define JSON_HEDLEY_NO_ESCAPE
1214 #endif
1215 
1216 #if defined(JSON_HEDLEY_UNREACHABLE)
1217  #undef JSON_HEDLEY_UNREACHABLE
1218 #endif
1219 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1220  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1221 #endif
1222 #if defined(JSON_HEDLEY_ASSUME)
1223  #undef JSON_HEDLEY_ASSUME
1224 #endif
1225 #if \
1226  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1227  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1228  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1229 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1230  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1231 #elif \
1232  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1233  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1234  #if defined(__cplusplus)
1235  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1236  #else
1237  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1238  #endif
1239 #endif
1240 #if \
1241  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1242  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1243  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1244  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1245  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1246  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1247 #elif defined(JSON_HEDLEY_ASSUME)
1248  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1249 #endif
1250 #if !defined(JSON_HEDLEY_ASSUME)
1251  #if defined(JSON_HEDLEY_UNREACHABLE)
1252  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1253  #else
1254  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1255  #endif
1256 #endif
1257 #if defined(JSON_HEDLEY_UNREACHABLE)
1258  #if \
1259  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1260  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1261  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1262  #else
1263  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1264  #endif
1265 #else
1266  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1267 #endif
1268 #if !defined(JSON_HEDLEY_UNREACHABLE)
1269  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1270 #endif
1271 
1272 JSON_HEDLEY_DIAGNOSTIC_PUSH
1273 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1274  #pragma clang diagnostic ignored "-Wpedantic"
1275 #endif
1276 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1277  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1278 #endif
1279 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1280  #if defined(__clang__)
1281  #pragma clang diagnostic ignored "-Wvariadic-macros"
1282  #elif defined(JSON_HEDLEY_GCC_VERSION)
1283  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1284  #endif
1285 #endif
1286 #if defined(JSON_HEDLEY_NON_NULL)
1287  #undef JSON_HEDLEY_NON_NULL
1288 #endif
1289 #if \
1290  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1291  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1292  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1293  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1294  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1295 #else
1296  #define JSON_HEDLEY_NON_NULL(...)
1297 #endif
1298 JSON_HEDLEY_DIAGNOSTIC_POP
1299 
1300 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1301  #undef JSON_HEDLEY_PRINTF_FORMAT
1302 #endif
1303 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1304  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1305 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1306  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1307 #elif \
1308  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1309  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1310  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1312  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1313  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1314  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1315  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1316  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1317  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1318  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1319  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1320  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1321  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1322  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1323  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1324  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1325 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1326  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1327 #else
1328  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1329 #endif
1330 
1331 #if defined(JSON_HEDLEY_CONSTEXPR)
1332  #undef JSON_HEDLEY_CONSTEXPR
1333 #endif
1334 #if defined(__cplusplus)
1335  #if __cplusplus >= 201103L
1336  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1337  #endif
1338 #endif
1339 #if !defined(JSON_HEDLEY_CONSTEXPR)
1340  #define JSON_HEDLEY_CONSTEXPR
1341 #endif
1342 
1343 #if defined(JSON_HEDLEY_PREDICT)
1344  #undef JSON_HEDLEY_PREDICT
1345 #endif
1346 #if defined(JSON_HEDLEY_LIKELY)
1347  #undef JSON_HEDLEY_LIKELY
1348 #endif
1349 #if defined(JSON_HEDLEY_UNLIKELY)
1350  #undef JSON_HEDLEY_UNLIKELY
1351 #endif
1352 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1353  #undef JSON_HEDLEY_UNPREDICTABLE
1354 #endif
1355 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1356  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1357 #endif
1358 #if \
1359  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1360  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1361 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1362 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1363 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1364 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1365 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1366 #elif \
1367  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1368  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1369  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1370  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1371  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1372  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1373  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1374  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1375  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1376  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1377  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1378  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1379  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1380  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1381  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1382 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1383  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1384 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1385  (__extension__ ({ \
1386  double hedley_probability_ = (probability); \
1387  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1388  }))
1389 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1390  (__extension__ ({ \
1391  double hedley_probability_ = (probability); \
1392  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1393  }))
1394 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1395 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1396 #else
1397 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1398 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1399 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1400 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1401 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1402 #endif
1403 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1404  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1405 #endif
1406 
1407 #if defined(JSON_HEDLEY_MALLOC)
1408  #undef JSON_HEDLEY_MALLOC
1409 #endif
1410 #if \
1411  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1412  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1413  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1415  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1416  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1417  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1418  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1419  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1420  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1421  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1422  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1423  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1424  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1425  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1426  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1427  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1428  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1429 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1430  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1431 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1432  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1433 #else
1434  #define JSON_HEDLEY_MALLOC
1435 #endif
1436 
1437 #if defined(JSON_HEDLEY_PURE)
1438  #undef JSON_HEDLEY_PURE
1439 #endif
1440 #if \
1441  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1442  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1443  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1444  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1445  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1446  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1447  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1448  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1449  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1450  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1451  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1452  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1453  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1454  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1455  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1456  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1457  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1458  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1459 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1460 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1461 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1462 #elif defined(__cplusplus) && \
1463  ( \
1464  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1465  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1466  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1467  )
1468 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1469 #else
1470 # define JSON_HEDLEY_PURE
1471 #endif
1472 
1473 #if defined(JSON_HEDLEY_CONST)
1474  #undef JSON_HEDLEY_CONST
1475 #endif
1476 #if \
1477  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1478  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1479  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1480  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1481  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1482  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1483  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1484  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1485  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1486  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1488  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1490  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1492  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1493  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1494  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1495  #define JSON_HEDLEY_CONST __attribute__((__const__))
1496 #elif \
1497  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1498  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1499 #else
1500  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1501 #endif
1502 
1503 #if defined(JSON_HEDLEY_RESTRICT)
1504  #undef JSON_HEDLEY_RESTRICT
1505 #endif
1506 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1507  #define JSON_HEDLEY_RESTRICT restrict
1508 #elif \
1509  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1510  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1511  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1512  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1513  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1514  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1515  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1516  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1517  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1518  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1519  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1520  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1521  defined(__clang__)
1522  #define JSON_HEDLEY_RESTRICT __restrict
1523 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1524  #define JSON_HEDLEY_RESTRICT _Restrict
1525 #else
1526  #define JSON_HEDLEY_RESTRICT
1527 #endif
1528 
1529 #if defined(JSON_HEDLEY_INLINE)
1530  #undef JSON_HEDLEY_INLINE
1531 #endif
1532 #if \
1533  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1534  (defined(__cplusplus) && (__cplusplus >= 199711L))
1535  #define JSON_HEDLEY_INLINE inline
1536 #elif \
1537  defined(JSON_HEDLEY_GCC_VERSION) || \
1538  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1539  #define JSON_HEDLEY_INLINE __inline__
1540 #elif \
1541  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1542  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1543  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1544  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1545  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1546  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1547  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1548  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1549  #define JSON_HEDLEY_INLINE __inline
1550 #else
1551  #define JSON_HEDLEY_INLINE
1552 #endif
1553 
1554 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1555  #undef JSON_HEDLEY_ALWAYS_INLINE
1556 #endif
1557 #if \
1558  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1559  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1560  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1561  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1562  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1563  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1564  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1565  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1566  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1567  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1568  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1569  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1570  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1571  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1572  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1573  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1574  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1575 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1576 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1577 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1578 #elif defined(__cplusplus) && \
1579  ( \
1580  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1581  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1582  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1583  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1584  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1585  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1586  )
1587 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1588 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1589 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1590 #else
1591 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1592 #endif
1593 
1594 #if defined(JSON_HEDLEY_NEVER_INLINE)
1595  #undef JSON_HEDLEY_NEVER_INLINE
1596 #endif
1597 #if \
1598  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1599  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1600  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1601  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1602  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1603  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1604  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1605  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1606  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1607  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1608  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1609  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1610  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1611  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1612  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1613  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1614  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1615  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1616 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1617  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1618 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1619  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1620 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1621  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1622 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1623  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1624 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1625  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1626 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1627  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1628 #else
1629  #define JSON_HEDLEY_NEVER_INLINE
1630 #endif
1631 
1632 #if defined(JSON_HEDLEY_PRIVATE)
1633  #undef JSON_HEDLEY_PRIVATE
1634 #endif
1635 #if defined(JSON_HEDLEY_PUBLIC)
1636  #undef JSON_HEDLEY_PUBLIC
1637 #endif
1638 #if defined(JSON_HEDLEY_IMPORT)
1639  #undef JSON_HEDLEY_IMPORT
1640 #endif
1641 #if defined(_WIN32) || defined(__CYGWIN__)
1642 # define JSON_HEDLEY_PRIVATE
1643 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1644 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1645 #else
1646 # if \
1647  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1648  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1649  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1651  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1652  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1653  ( \
1654  defined(__TI_EABI__) && \
1655  ( \
1656  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1657  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1658  ) \
1659  )
1660 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1661 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1662 # else
1663 # define JSON_HEDLEY_PRIVATE
1664 # define JSON_HEDLEY_PUBLIC
1665 # endif
1666 # define JSON_HEDLEY_IMPORT extern
1667 #endif
1668 
1669 #if defined(JSON_HEDLEY_NO_THROW)
1670  #undef JSON_HEDLEY_NO_THROW
1671 #endif
1672 #if \
1673  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1674  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1675  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1676  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1677 #elif \
1678  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1679  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1680  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1681 #else
1682  #define JSON_HEDLEY_NO_THROW
1683 #endif
1684 
1685 #if defined(JSON_HEDLEY_FALL_THROUGH)
1686  #undef JSON_HEDLEY_FALL_THROUGH
1687 #endif
1688 #if \
1689  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1690  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1691  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1692 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1693  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1694 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1695  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1696 #elif defined(__fallthrough) /* SAL */
1697  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1698 #else
1699  #define JSON_HEDLEY_FALL_THROUGH
1700 #endif
1701 
1702 #if defined()
1703  #undef
1704 #endif
1705 #if \
1706  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1707  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1708  #define __attribute__((__returns_nonnull__))
1709 #elif defined(_Ret_notnull_) /* SAL */
1710  #define _Ret_notnull_
1711 #else
1712  #define
1713 #endif
1714 
1715 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1716  #undef JSON_HEDLEY_ARRAY_PARAM
1717 #endif
1718 #if \
1719  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1720  !defined(__STDC_NO_VLA__) && \
1721  !defined(__cplusplus) && \
1722  !defined(JSON_HEDLEY_PGI_VERSION) && \
1723  !defined(JSON_HEDLEY_TINYC_VERSION)
1724  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1725 #else
1726  #define JSON_HEDLEY_ARRAY_PARAM(name)
1727 #endif
1728 
1729 #if defined(JSON_HEDLEY_IS_CONSTANT)
1730  #undef JSON_HEDLEY_IS_CONSTANT
1731 #endif
1732 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1733  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1734 #endif
1735 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1736  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1737 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1738  #undef JSON_HEDLEY_IS_CONSTEXPR_
1739 #endif
1740 #if \
1741  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1742  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1743  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1744  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1745  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1746  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1747  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1748  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1749  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1750  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1751 #endif
1752 #if !defined(__cplusplus)
1753 # if \
1754  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1755  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1756  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1757  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1758  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1759  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1760  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1761 #if defined(__INTPTR_TYPE__)
1762  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1763 #else
1764  #include <stdint.h>
1765  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1766 #endif
1767 # elif \
1768  ( \
1769  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1770  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1771  !defined(JSON_HEDLEY_PGI_VERSION) && \
1772  !defined(JSON_HEDLEY_IAR_VERSION)) || \
1773  JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1774  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1775  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1776  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1777  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1778 #if defined(__INTPTR_TYPE__)
1779  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1780 #else
1781  #include <stdint.h>
1782  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1783 #endif
1784 # elif \
1785  defined(JSON_HEDLEY_GCC_VERSION) || \
1786  defined(JSON_HEDLEY_INTEL_VERSION) || \
1787  defined(JSON_HEDLEY_TINYC_VERSION) || \
1788  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1789  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1790  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1791  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1792  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1793  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1794  defined(__clang__)
1795 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1796  sizeof(void) != \
1797  sizeof(*( \
1798  1 ? \
1799  ((void*) ((expr) * 0L) ) : \
1800 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1801  ) \
1802  ) \
1803  )
1804 # endif
1805 #endif
1806 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1807  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1808  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1809  #endif
1810  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1811 #else
1812  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1813  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1814  #endif
1815  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1816 #endif
1817 
1818 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1819  #undef JSON_HEDLEY_BEGIN_C_DECLS
1820 #endif
1821 #if defined(JSON_HEDLEY_END_C_DECLS)
1822  #undef JSON_HEDLEY_END_C_DECLS
1823 #endif
1824 #if defined(JSON_HEDLEY_C_DECL)
1825  #undef JSON_HEDLEY_C_DECL
1826 #endif
1827 #if defined(__cplusplus)
1828  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1829  #define JSON_HEDLEY_END_C_DECLS }
1830  #define JSON_HEDLEY_C_DECL extern "C"
1831 #else
1832  #define JSON_HEDLEY_BEGIN_C_DECLS
1833  #define JSON_HEDLEY_END_C_DECLS
1834  #define JSON_HEDLEY_C_DECL
1835 #endif
1836 
1837 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1838  #undef JSON_HEDLEY_STATIC_ASSERT
1839 #endif
1840 #if \
1841  !defined(__cplusplus) && ( \
1842  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1843  JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1844  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1845  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1846  defined(_Static_assert) \
1847  )
1848 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1849 #elif \
1850  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1851  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
1852 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1853 #else
1854 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1855 #endif
1856 
1857 #if defined(JSON_HEDLEY_NULL)
1858  #undef JSON_HEDLEY_NULL
1859 #endif
1860 #if defined(__cplusplus)
1861  #if __cplusplus >= 201103L
1862  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1863  #elif defined(NULL)
1864  #define JSON_HEDLEY_NULL NULL
1865  #else
1866  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1867  #endif
1868 #elif defined(NULL)
1869  #define JSON_HEDLEY_NULL NULL
1870 #else
1871  #define JSON_HEDLEY_NULL ((void*) 0)
1872 #endif
1873 
1874 #if defined(JSON_HEDLEY_MESSAGE)
1875  #undef JSON_HEDLEY_MESSAGE
1876 #endif
1877 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1878 # define JSON_HEDLEY_MESSAGE(msg) \
1879  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1880  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1881  JSON_HEDLEY_PRAGMA(message msg) \
1882  JSON_HEDLEY_DIAGNOSTIC_POP
1883 #elif \
1884  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1885  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1886 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1887 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1888 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1889 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1890 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1891 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1892 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1893 #else
1894 # define JSON_HEDLEY_MESSAGE(msg)
1895 #endif
1896 
1897 #if defined(JSON_HEDLEY_WARNING)
1898  #undef JSON_HEDLEY_WARNING
1899 #endif
1900 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1901 # define JSON_HEDLEY_WARNING(msg) \
1902  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1903  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1904  JSON_HEDLEY_PRAGMA(clang warning msg) \
1905  JSON_HEDLEY_DIAGNOSTIC_POP
1906 #elif \
1907  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1908  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1909  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1910 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1911 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1912 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1913 #else
1914 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1915 #endif
1916 
1917 #if defined(JSON_HEDLEY_REQUIRE)
1918  #undef JSON_HEDLEY_REQUIRE
1919 #endif
1920 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1921  #undef JSON_HEDLEY_REQUIRE_MSG
1922 #endif
1923 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1924 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1925 # define JSON_HEDLEY_REQUIRE(expr) \
1926  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1927  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1928  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1929  JSON_HEDLEY_DIAGNOSTIC_POP
1930 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1931  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1932  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1933  __attribute__((diagnose_if(!(expr), msg, "error"))) \
1934  JSON_HEDLEY_DIAGNOSTIC_POP
1935 # else
1936 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1937 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1938 # endif
1939 #else
1940 # define JSON_HEDLEY_REQUIRE(expr)
1941 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1942 #endif
1943 
1944 #if defined(JSON_HEDLEY_FLAGS)
1945  #undef JSON_HEDLEY_FLAGS
1946 #endif
1947 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1948  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1949 #endif
1950 
1951 #if defined(JSON_HEDLEY_FLAGS_CAST)
1952  #undef JSON_HEDLEY_FLAGS_CAST
1953 #endif
1954 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1955 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1956  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1957  _Pragma("warning(disable:188)") \
1958  ((T) (expr)); \
1959  JSON_HEDLEY_DIAGNOSTIC_POP \
1960  }))
1961 #else
1962 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1963 #endif
1964 
1965 #if defined(JSON_HEDLEY_EMPTY_BASES)
1966  #undef JSON_HEDLEY_EMPTY_BASES
1967 #endif
1968 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1969  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1970 #else
1971  #define JSON_HEDLEY_EMPTY_BASES
1972 #endif
1973 
1974 /* Remaining macros are deprecated. */
1975 
1976 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1977  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1978 #endif
1979 #if defined(__clang__)
1980  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1981 #else
1982  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1983 #endif
1984 
1985 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1986  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1987 #endif
1988 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
1989 
1990 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
1991  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
1992 #endif
1993 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
1994 
1995 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
1996  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
1997 #endif
1998 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
1999 
2000 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2001  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2002 #endif
2003 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2004 
2005 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2006  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2007 #endif
2008 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2009 
2010 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2011  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2012 #endif
2013 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2014 
2015 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2016  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2017 #endif
2018 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2019 
2020 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2021 
2022 
2023 // This file contains all internal macro definitions
2024 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2025 
2026 // exclude unsupported compilers
2027 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2028  #if defined(__clang__)
2029  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2030  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2031  #endif
2032  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2033  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2034  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2035  #endif
2036  #endif
2037 #endif
2038 
2039 // C++ language standard detection
2040 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2041  #define JSON_HAS_CPP_20
2042  #define JSON_HAS_CPP_17
2043  #define JSON_HAS_CPP_14
2044 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2045  #define JSON_HAS_CPP_17
2046  #define JSON_HAS_CPP_14
2047 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2048  #define JSON_HAS_CPP_14
2049 #endif
2050 
2051 // disable float-equal warnings on GCC/clang
2052 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2053  #pragma GCC diagnostic push
2054  #pragma GCC diagnostic ignored "-Wfloat-equal"
2055 #endif
2056 
2057 // disable documentation warnings on clang
2058 #if defined(__clang__)
2059  #pragma GCC diagnostic push
2060  #pragma GCC diagnostic ignored "-Wdocumentation"
2061 #endif
2062 
2063 // allow to disable exceptions
2064 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2065  #define JSON_THROW(exception) throw exception
2066  #define JSON_TRY try
2067  #define JSON_CATCH(exception) catch(exception)
2068  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2069 #else
2070  #include <cstdlib>
2071  #define JSON_THROW(exception) std::abort()
2072  #define JSON_TRY if(true)
2073  #define JSON_CATCH(exception) if(false)
2074  #define JSON_INTERNAL_CATCH(exception) if(false)
2075 #endif
2076 
2077 // override exception macros
2078 #if defined(JSON_THROW_USER)
2079  #undef JSON_THROW
2080  #define JSON_THROW JSON_THROW_USER
2081 #endif
2082 #if defined(JSON_TRY_USER)
2083  #undef JSON_TRY
2084  #define JSON_TRY JSON_TRY_USER
2085 #endif
2086 #if defined(JSON_CATCH_USER)
2087  #undef JSON_CATCH
2088  #define JSON_CATCH JSON_CATCH_USER
2089  #undef JSON_INTERNAL_CATCH
2090  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2091 #endif
2092 #if defined(JSON_INTERNAL_CATCH_USER)
2093  #undef JSON_INTERNAL_CATCH
2094  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2095 #endif
2096 
2097 // allow to override assert
2098 #if !defined(JSON_ASSERT)
2099  #include <cassert> // assert
2100  #define JSON_ASSERT(x) assert(x)
2101 #endif
2102 
2103 // allow to access some private functions (needed by the test suite)
2104 #if defined(JSON_TESTS_PRIVATE)
2105  #define JSON_PRIVATE_UNLESS_TESTED public
2106 #else
2107  #define JSON_PRIVATE_UNLESS_TESTED private
2108 #endif
2109 
2115 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2116  template<typename BasicJsonType> \
2117  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2118  { \
2119  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2120  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2121  auto it = std::find_if(std::begin(m), std::end(m), \
2122  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2123  { \
2124  return ej_pair.first == e; \
2125  }); \
2126  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2127  } \
2128  template<typename BasicJsonType> \
2129  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2130  { \
2131  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2132  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2133  auto it = std::find_if(std::begin(m), std::end(m), \
2134  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2135  { \
2136  return ej_pair.second == j; \
2137  }); \
2138  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2139  }
2140 
2141 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2142 // may be removed in the future once the class is split.
2143 
2144 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2145  template<template<typename, typename, typename...> class ObjectType, \
2146  template<typename, typename...> class ArrayType, \
2147  class StringType, class BooleanType, class NumberIntegerType, \
2148  class NumberUnsignedType, class NumberFloatType, \
2149  template<typename> class AllocatorType, \
2150  template<typename, typename = void> class JSONSerializer, \
2151  class BinaryType>
2152 
2153 #define NLOHMANN_BASIC_JSON_TPL \
2154  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2155  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2156  AllocatorType, JSONSerializer, BinaryType>
2157 
2158 // Macros to simplify conversion from/to types
2159 
2160 #define NLOHMANN_JSON_EXPAND( x ) x
2161 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2162 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2163  NLOHMANN_JSON_PASTE64, \
2164  NLOHMANN_JSON_PASTE63, \
2165  NLOHMANN_JSON_PASTE62, \
2166  NLOHMANN_JSON_PASTE61, \
2167  NLOHMANN_JSON_PASTE60, \
2168  NLOHMANN_JSON_PASTE59, \
2169  NLOHMANN_JSON_PASTE58, \
2170  NLOHMANN_JSON_PASTE57, \
2171  NLOHMANN_JSON_PASTE56, \
2172  NLOHMANN_JSON_PASTE55, \
2173  NLOHMANN_JSON_PASTE54, \
2174  NLOHMANN_JSON_PASTE53, \
2175  NLOHMANN_JSON_PASTE52, \
2176  NLOHMANN_JSON_PASTE51, \
2177  NLOHMANN_JSON_PASTE50, \
2178  NLOHMANN_JSON_PASTE49, \
2179  NLOHMANN_JSON_PASTE48, \
2180  NLOHMANN_JSON_PASTE47, \
2181  NLOHMANN_JSON_PASTE46, \
2182  NLOHMANN_JSON_PASTE45, \
2183  NLOHMANN_JSON_PASTE44, \
2184  NLOHMANN_JSON_PASTE43, \
2185  NLOHMANN_JSON_PASTE42, \
2186  NLOHMANN_JSON_PASTE41, \
2187  NLOHMANN_JSON_PASTE40, \
2188  NLOHMANN_JSON_PASTE39, \
2189  NLOHMANN_JSON_PASTE38, \
2190  NLOHMANN_JSON_PASTE37, \
2191  NLOHMANN_JSON_PASTE36, \
2192  NLOHMANN_JSON_PASTE35, \
2193  NLOHMANN_JSON_PASTE34, \
2194  NLOHMANN_JSON_PASTE33, \
2195  NLOHMANN_JSON_PASTE32, \
2196  NLOHMANN_JSON_PASTE31, \
2197  NLOHMANN_JSON_PASTE30, \
2198  NLOHMANN_JSON_PASTE29, \
2199  NLOHMANN_JSON_PASTE28, \
2200  NLOHMANN_JSON_PASTE27, \
2201  NLOHMANN_JSON_PASTE26, \
2202  NLOHMANN_JSON_PASTE25, \
2203  NLOHMANN_JSON_PASTE24, \
2204  NLOHMANN_JSON_PASTE23, \
2205  NLOHMANN_JSON_PASTE22, \
2206  NLOHMANN_JSON_PASTE21, \
2207  NLOHMANN_JSON_PASTE20, \
2208  NLOHMANN_JSON_PASTE19, \
2209  NLOHMANN_JSON_PASTE18, \
2210  NLOHMANN_JSON_PASTE17, \
2211  NLOHMANN_JSON_PASTE16, \
2212  NLOHMANN_JSON_PASTE15, \
2213  NLOHMANN_JSON_PASTE14, \
2214  NLOHMANN_JSON_PASTE13, \
2215  NLOHMANN_JSON_PASTE12, \
2216  NLOHMANN_JSON_PASTE11, \
2217  NLOHMANN_JSON_PASTE10, \
2218  NLOHMANN_JSON_PASTE9, \
2219  NLOHMANN_JSON_PASTE8, \
2220  NLOHMANN_JSON_PASTE7, \
2221  NLOHMANN_JSON_PASTE6, \
2222  NLOHMANN_JSON_PASTE5, \
2223  NLOHMANN_JSON_PASTE4, \
2224  NLOHMANN_JSON_PASTE3, \
2225  NLOHMANN_JSON_PASTE2, \
2226  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2227 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2228 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2229 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2230 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2231 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2232 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2233 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2234 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2235 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2236 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2237 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2238 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2239 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2240 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2241 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2242 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2243 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2244 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2245 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2246 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2247 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2248 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2249 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2250 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2251 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2252 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2253 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2254 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2255 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2256 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2257 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2258 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2259 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2260 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2261 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2262 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2263 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2264 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2265 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2266 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2267 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2268 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2269 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2270 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2271 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2272 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2273 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2274 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2275 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2276 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2277 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2278 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2279 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2280 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2281 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2282 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2283 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2284 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2285 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2286 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2287 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2288 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2289 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2290 
2291 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2292 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2293 
2299 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2300  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2301  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2302 
2308 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2309  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2310  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2311 
2312 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2313  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2314 #endif
2315 
2316 #if JSON_USE_IMPLICIT_CONVERSIONS
2317  #define JSON_EXPLICIT
2318 #else
2319  #define JSON_EXPLICIT explicit
2320 #endif
2321 
2322 
2323 namespace nlohmann
2324 {
2325 namespace detail
2326 {
2328 // exceptions //
2330 
2359 class exception : public std::exception
2360 {
2361  public:
2363 
2364  const char* what() const noexcept override
2365  {
2366  return m.what();
2367  }
2368 
2370  const int id;
2371 
2372  protected:
2373  JSON_HEDLEY_NON_NULL(3)
2374  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2375 
2376  static std::string name(const std::string& ename, int id_)
2377  {
2378  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2379  }
2380 
2381  private:
2383  std::runtime_error m;
2384 };
2385 
2431 class parse_error : public exception
2432 {
2433  public:
2443  static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2444  {
2445  std::string w = exception::name("parse_error", id_) + "parse error" +
2446  position_string(pos) + ": " + what_arg;
2447  return parse_error(id_, pos.chars_read_total, w.c_str());
2448  }
2449 
2450  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2451  {
2452  std::string w = exception::name("parse_error", id_) + "parse error" +
2453  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2454  ": " + what_arg;
2455  return parse_error(id_, byte_, w.c_str());
2456  }
2457 
2467  const std::size_t byte;
2468 
2469  private:
2470  parse_error(int id_, std::size_t byte_, const char* what_arg)
2471  : exception(id_, what_arg), byte(byte_) {}
2472 
2473  static std::string position_string(const position_t& pos)
2474  {
2475  return " at line " + std::to_string(pos.lines_read + 1) +
2476  ", column " + std::to_string(pos.chars_read_current_line);
2477  }
2478 };
2479 
2517 class invalid_iterator : public exception
2518 {
2519  public:
2520  static invalid_iterator create(int id_, const std::string& what_arg)
2521  {
2522  std::string w = exception::name("invalid_iterator", id_) + what_arg;
2523  return invalid_iterator(id_, w.c_str());
2524  }
2525 
2526  private:
2527  JSON_HEDLEY_NON_NULL(3)
2528  invalid_iterator(int id_, const char* what_arg)
2529  : exception(id_, what_arg) {}
2530 };
2531 
2571 class type_error : public exception
2572 {
2573  public:
2574  static type_error create(int id_, const std::string& what_arg)
2575  {
2576  std::string w = exception::name("type_error", id_) + what_arg;
2577  return type_error(id_, w.c_str());
2578  }
2579 
2580  private:
2581  JSON_HEDLEY_NON_NULL(3)
2582  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2583 };
2584 
2618 class out_of_range : public exception
2619 {
2620  public:
2621  static out_of_range create(int id_, const std::string& what_arg)
2622  {
2623  std::string w = exception::name("out_of_range", id_) + what_arg;
2624  return out_of_range(id_, w.c_str());
2625  }
2626 
2627  private:
2628  JSON_HEDLEY_NON_NULL(3)
2629  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2630 };
2631 
2656 class other_error : public exception
2657 {
2658  public:
2659  static other_error create(int id_, const std::string& what_arg)
2660  {
2661  std::string w = exception::name("other_error", id_) + what_arg;
2662  return other_error(id_, w.c_str());
2663  }
2664 
2665  private:
2666  JSON_HEDLEY_NON_NULL(3)
2667  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2668 };
2669 } // namespace detail
2670 } // namespace nlohmann
2671 
2672 // #include <nlohmann/detail/macro_scope.hpp>
2673 
2674 // #include <nlohmann/detail/meta/cpp_future.hpp>
2675 
2676 
2677 #include <cstddef> // size_t
2678 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2679 
2680 namespace nlohmann
2681 {
2682 namespace detail
2683 {
2684 // alias templates to reduce boilerplate
2685 template<bool B, typename T = void>
2686 using enable_if_t = typename std::enable_if<B, T>::type;
2687 
2688 template<typename T>
2689 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2690 
2691 // implementation of C++14 index_sequence and affiliates
2692 // source: https://stackoverflow.com/a/32223343
2693 template<std::size_t... Ints>
2694 struct index_sequence
2695 {
2696  using type = index_sequence;
2697  using value_type = std::size_t;
2698  static constexpr std::size_t size() noexcept
2699  {
2700  return sizeof...(Ints);
2701  }
2702 };
2703 
2704 template<class Sequence1, class Sequence2>
2705 struct merge_and_renumber;
2706 
2707 template<std::size_t... I1, std::size_t... I2>
2708 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2709  : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2710 
2711 template<std::size_t N>
2712 struct make_index_sequence
2713  : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2714  typename make_index_sequence < N - N / 2 >::type > {};
2715 
2716 template<> struct make_index_sequence<0> : index_sequence<> {};
2717 template<> struct make_index_sequence<1> : index_sequence<0> {};
2718 
2719 template<typename... Ts>
2720 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2721 
2722 // dispatch utility (taken from ranges-v3)
2723 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2724 template<> struct priority_tag<0> {};
2725 
2726 // taken from ranges-v3
2727 template<typename T>
2728 struct static_const
2729 {
2730  static constexpr T value{};
2731 };
2732 
2733 template<typename T>
2734 constexpr T static_const<T>::value;
2735 } // namespace detail
2736 } // namespace nlohmann
2737 
2738 // #include <nlohmann/detail/meta/type_traits.hpp>
2739 
2740 
2741 #include <limits> // numeric_limits
2742 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2743 #include <utility> // declval
2744 
2745 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2746 
2747 
2748 #include <iterator> // random_access_iterator_tag
2749 
2750 // #include <nlohmann/detail/meta/void_t.hpp>
2751 
2752 
2753 namespace nlohmann
2754 {
2755 namespace detail
2756 {
2757 template<typename ...Ts> struct make_void
2758 {
2759  using type = void;
2760 };
2761 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2762 } // namespace detail
2763 } // namespace nlohmann
2764 
2765 // #include <nlohmann/detail/meta/cpp_future.hpp>
2766 
2767 
2768 namespace nlohmann
2769 {
2770 namespace detail
2771 {
2772 template<typename It, typename = void>
2773 struct iterator_types {};
2774 
2775 template<typename It>
2776 struct iterator_types <
2777  It,
2778  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2779  typename It::reference, typename It::iterator_category >>
2780 {
2781  using difference_type = typename It::difference_type;
2782  using value_type = typename It::value_type;
2783  using pointer = typename It::pointer;
2784  using reference = typename It::reference;
2785  using iterator_category = typename It::iterator_category;
2786 };
2787 
2788 // This is required as some compilers implement std::iterator_traits in a way that
2789 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2790 template<typename T, typename = void>
2791 struct iterator_traits
2792 {
2793 };
2794 
2795 template<typename T>
2796 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2797  : iterator_types<T>
2798 {
2799 };
2800 
2801 template<typename T>
2802 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2803 {
2804  using iterator_category = std::random_access_iterator_tag;
2805  using value_type = T;
2806  using difference_type = ptrdiff_t;
2807  using pointer = T*;
2808  using reference = T&;
2809 };
2810 } // namespace detail
2811 } // namespace nlohmann
2812 
2813 // #include <nlohmann/detail/macro_scope.hpp>
2814 
2815 // #include <nlohmann/detail/meta/cpp_future.hpp>
2816 
2817 // #include <nlohmann/detail/meta/detected.hpp>
2818 
2819 
2820 #include <type_traits>
2821 
2822 // #include <nlohmann/detail/meta/void_t.hpp>
2823 
2824 
2825 // https://en.cppreference.com/w/cpp/experimental/is_detected
2826 namespace nlohmann
2827 {
2828 namespace detail
2829 {
2830 struct nonesuch
2831 {
2832  nonesuch() = delete;
2833  ~nonesuch() = delete;
2834  nonesuch(nonesuch const&) = delete;
2835  nonesuch(nonesuch const&&) = delete;
2836  void operator=(nonesuch const&) = delete;
2837  void operator=(nonesuch&&) = delete;
2838 };
2839 
2840 template<class Default,
2841  class AlwaysVoid,
2842  template<class...> class Op,
2843  class... Args>
2844 struct detector
2845 {
2846  using value_t = std::false_type;
2847  using type = Default;
2848 };
2849 
2850 template<class Default, template<class...> class Op, class... Args>
2851 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2852 {
2853  using value_t = std::true_type;
2854  using type = Op<Args...>;
2855 };
2856 
2857 template<template<class...> class Op, class... Args>
2858 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2859 
2860 template<template<class...> class Op, class... Args>
2861 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2862 
2863 template<class Default, template<class...> class Op, class... Args>
2864 using detected_or = detector<Default, void, Op, Args...>;
2865 
2866 template<class Default, template<class...> class Op, class... Args>
2867 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2868 
2869 template<class Expected, template<class...> class Op, class... Args>
2870 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2871 
2872 template<class To, template<class...> class Op, class... Args>
2873 using is_detected_convertible =
2874  std::is_convertible<detected_t<Op, Args...>, To>;
2875 } // namespace detail
2876 } // namespace nlohmann
2877 
2878 // #include <nlohmann/json_fwd.hpp>
2879 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2880 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2881 
2882 #include <cstdint> // int64_t, uint64_t
2883 #include <map> // map
2884 #include <memory> // allocator
2885 #include <string> // string
2886 #include <vector> // vector
2887 
2893 namespace nlohmann
2894 {
2902 template<typename T = void, typename SFINAE = void>
2903 struct adl_serializer;
2904 
2905 template<template<typename U, typename V, typename... Args> class ObjectType =
2906  std::map,
2907  template<typename U, typename... Args> class ArrayType = std::vector,
2908  class StringType = std::string, class BooleanType = bool,
2909  class NumberIntegerType = std::int64_t,
2910  class NumberUnsignedType = std::uint64_t,
2911  class NumberFloatType = double,
2912  template<typename U> class AllocatorType = std::allocator,
2913  template<typename T, typename SFINAE = void> class JSONSerializer =
2914  adl_serializer,
2915  class BinaryType = std::vector<std::uint8_t>>
2916 class basic_json;
2917 
2929 template<typename BasicJsonType>
2930 class json_pointer;
2931 
2941 
2942 template<class Key, class T, class IgnoredLess, class Allocator>
2943 struct ordered_map;
2944 
2953 
2954 } // namespace nlohmann
2955 
2956 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2957 
2958 
2959 namespace nlohmann
2960 {
2969 namespace detail
2970 {
2972 // helpers //
2974 
2975 // Note to maintainers:
2976 //
2977 // Every trait in this file expects a non CV-qualified type.
2978 // The only exceptions are in the 'aliases for detected' section
2979 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2980 //
2981 // In this case, T has to be properly CV-qualified to constraint the function arguments
2982 // (e.g. to_json(BasicJsonType&, const T&))
2983 
2984 template<typename> struct is_basic_json : std::false_type {};
2985 
2986 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2987 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2988 
2990 // json_ref helpers //
2992 
2993 template<typename>
2994 class json_ref;
2995 
2996 template<typename>
2997 struct is_json_ref : std::false_type {};
2998 
2999 template<typename T>
3000 struct is_json_ref<json_ref<T>> : std::true_type {};
3001 
3003 // aliases for detected //
3005 
3006 template<typename T>
3007 using mapped_type_t = typename T::mapped_type;
3008 
3009 template<typename T>
3010 using key_type_t = typename T::key_type;
3011 
3012 template<typename T>
3013 using value_type_t = typename T::value_type;
3014 
3015 template<typename T>
3016 using difference_type_t = typename T::difference_type;
3017 
3018 template<typename T>
3019 using pointer_t = typename T::pointer;
3020 
3021 template<typename T>
3022 using reference_t = typename T::reference;
3023 
3024 template<typename T>
3025 using iterator_category_t = typename T::iterator_category;
3026 
3027 template<typename T>
3028 using iterator_t = typename T::iterator;
3029 
3030 template<typename T, typename... Args>
3031 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3032 
3033 template<typename T, typename... Args>
3034 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3035 
3036 template<typename T, typename U>
3037 using get_template_function = decltype(std::declval<T>().template get<U>());
3038 
3039 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3040 template<typename BasicJsonType, typename T, typename = void>
3041 struct has_from_json : std::false_type {};
3042 
3043 // trait checking if j.get<T> is valid
3044 // use this trait instead of std::is_constructible or std::is_convertible,
3045 // both rely on, or make use of implicit conversions, and thus fail when T
3046 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3047 template <typename BasicJsonType, typename T>
3048 struct is_getable
3049 {
3050  static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3051 };
3052 
3053 template<typename BasicJsonType, typename T>
3054 struct has_from_json < BasicJsonType, T,
3055  enable_if_t < !is_basic_json<T>::value >>
3056 {
3057  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3058 
3059  static constexpr bool value =
3060  is_detected_exact<void, from_json_function, serializer,
3061  const BasicJsonType&, T&>::value;
3062 };
3063 
3064 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3065 // this overload is used for non-default-constructible user-defined-types
3066 template<typename BasicJsonType, typename T, typename = void>
3067 struct has_non_default_from_json : std::false_type {};
3068 
3069 template<typename BasicJsonType, typename T>
3070 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3071 {
3072  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3073 
3074  static constexpr bool value =
3075  is_detected_exact<T, from_json_function, serializer,
3076  const BasicJsonType&>::value;
3077 };
3078 
3079 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3080 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3081 template<typename BasicJsonType, typename T, typename = void>
3082 struct has_to_json : std::false_type {};
3083 
3084 template<typename BasicJsonType, typename T>
3085 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3086 {
3087  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3088 
3089  static constexpr bool value =
3090  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3091  T>::value;
3092 };
3093 
3094 
3096 // is_ functions //
3098 
3099 template<typename T, typename = void>
3100 struct is_iterator_traits : std::false_type {};
3101 
3102 template<typename T>
3103 struct is_iterator_traits<iterator_traits<T>>
3104 {
3105  private:
3106  using traits = iterator_traits<T>;
3107 
3108  public:
3109  static constexpr auto value =
3110  is_detected<value_type_t, traits>::value &&
3111  is_detected<difference_type_t, traits>::value &&
3112  is_detected<pointer_t, traits>::value &&
3113  is_detected<iterator_category_t, traits>::value &&
3114  is_detected<reference_t, traits>::value;
3115 };
3116 
3117 // source: https://stackoverflow.com/a/37193089/4116453
3118 
3119 template<typename T, typename = void>
3120 struct is_complete_type : std::false_type {};
3121 
3122 template<typename T>
3123 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3124 
3125 template<typename BasicJsonType, typename CompatibleObjectType,
3126  typename = void>
3127 struct is_compatible_object_type_impl : std::false_type {};
3128 
3129 template<typename BasicJsonType, typename CompatibleObjectType>
3130 struct is_compatible_object_type_impl <
3131  BasicJsonType, CompatibleObjectType,
3132  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3133  is_detected<key_type_t, CompatibleObjectType>::value >>
3134 {
3135 
3136  using object_t = typename BasicJsonType::object_t;
3137 
3138  // macOS's is_constructible does not play well with nonesuch...
3139  static constexpr bool value =
3140  std::is_constructible<typename object_t::key_type,
3141  typename CompatibleObjectType::key_type>::value &&
3142  std::is_constructible<typename object_t::mapped_type,
3143  typename CompatibleObjectType::mapped_type>::value;
3144 };
3145 
3146 template<typename BasicJsonType, typename CompatibleObjectType>
3147 struct is_compatible_object_type
3148  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3149 
3150 template<typename BasicJsonType, typename ConstructibleObjectType,
3151  typename = void>
3152 struct is_constructible_object_type_impl : std::false_type {};
3153 
3154 template<typename BasicJsonType, typename ConstructibleObjectType>
3155 struct is_constructible_object_type_impl <
3156  BasicJsonType, ConstructibleObjectType,
3157  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3158  is_detected<key_type_t, ConstructibleObjectType>::value >>
3159 {
3160  using object_t = typename BasicJsonType::object_t;
3161 
3162  static constexpr bool value =
3163  (std::is_default_constructible<ConstructibleObjectType>::value &&
3164  (std::is_move_assignable<ConstructibleObjectType>::value ||
3165  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3166  (std::is_constructible<typename ConstructibleObjectType::key_type,
3167  typename object_t::key_type>::value &&
3168  std::is_same <
3169  typename object_t::mapped_type,
3170  typename ConstructibleObjectType::mapped_type >::value)) ||
3171  (has_from_json<BasicJsonType,
3172  typename ConstructibleObjectType::mapped_type>::value ||
3173  has_non_default_from_json <
3174  BasicJsonType,
3175  typename ConstructibleObjectType::mapped_type >::value);
3176 };
3177 
3178 template<typename BasicJsonType, typename ConstructibleObjectType>
3179 struct is_constructible_object_type
3180  : is_constructible_object_type_impl<BasicJsonType,
3181  ConstructibleObjectType> {};
3182 
3183 template<typename BasicJsonType, typename CompatibleStringType,
3184  typename = void>
3185 struct is_compatible_string_type_impl : std::false_type {};
3186 
3187 template<typename BasicJsonType, typename CompatibleStringType>
3188 struct is_compatible_string_type_impl <
3189  BasicJsonType, CompatibleStringType,
3190  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3191  value_type_t, CompatibleStringType>::value >>
3192 {
3193  static constexpr auto value =
3194  std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3195 };
3196 
3197 template<typename BasicJsonType, typename ConstructibleStringType>
3198 struct is_compatible_string_type
3199  : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3200 
3201 template<typename BasicJsonType, typename ConstructibleStringType,
3202  typename = void>
3203 struct is_constructible_string_type_impl : std::false_type {};
3204 
3205 template<typename BasicJsonType, typename ConstructibleStringType>
3206 struct is_constructible_string_type_impl <
3207  BasicJsonType, ConstructibleStringType,
3208  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3209  value_type_t, ConstructibleStringType>::value >>
3210 {
3211  static constexpr auto value =
3212  std::is_constructible<ConstructibleStringType,
3213  typename BasicJsonType::string_t>::value;
3214 };
3215 
3216 template<typename BasicJsonType, typename ConstructibleStringType>
3217 struct is_constructible_string_type
3218  : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3219 
3220 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3221 struct is_compatible_array_type_impl : std::false_type {};
3222 
3223 template<typename BasicJsonType, typename CompatibleArrayType>
3224 struct is_compatible_array_type_impl <
3225  BasicJsonType, CompatibleArrayType,
3226  enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3227  is_detected<iterator_t, CompatibleArrayType>::value&&
3228 // This is needed because json_reverse_iterator has a ::iterator type...
3229 // Therefore it is detected as a CompatibleArrayType.
3230 // The real fix would be to have an Iterable concept.
3231  !is_iterator_traits <
3232  iterator_traits<CompatibleArrayType >>::value >>
3233 {
3234  static constexpr bool value =
3235  std::is_constructible<BasicJsonType,
3236  typename CompatibleArrayType::value_type>::value;
3237 };
3238 
3239 template<typename BasicJsonType, typename CompatibleArrayType>
3240 struct is_compatible_array_type
3241  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3242 
3243 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3244 struct is_constructible_array_type_impl : std::false_type {};
3245 
3246 template<typename BasicJsonType, typename ConstructibleArrayType>
3247 struct is_constructible_array_type_impl <
3248  BasicJsonType, ConstructibleArrayType,
3249  enable_if_t<std::is_same<ConstructibleArrayType,
3250  typename BasicJsonType::value_type>::value >>
3251  : std::true_type {};
3252 
3253 template<typename BasicJsonType, typename ConstructibleArrayType>
3254 struct is_constructible_array_type_impl <
3255  BasicJsonType, ConstructibleArrayType,
3256  enable_if_t < !std::is_same<ConstructibleArrayType,
3257  typename BasicJsonType::value_type>::value&&
3258  std::is_default_constructible<ConstructibleArrayType>::value&&
3259 (std::is_move_assignable<ConstructibleArrayType>::value ||
3260  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3261 is_detected<value_type_t, ConstructibleArrayType>::value&&
3262 is_detected<iterator_t, ConstructibleArrayType>::value&&
3263 is_complete_type <
3264 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3265 {
3266  static constexpr bool value =
3267  // This is needed because json_reverse_iterator has a ::iterator type,
3268  // furthermore, std::back_insert_iterator (and other iterators) have a
3269  // base class `iterator`... Therefore it is detected as a
3270  // ConstructibleArrayType. The real fix would be to have an Iterable
3271  // concept.
3272  !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3273 
3274  (std::is_same<typename ConstructibleArrayType::value_type,
3275  typename BasicJsonType::array_t::value_type>::value ||
3276  has_from_json<BasicJsonType,
3277  typename ConstructibleArrayType::value_type>::value ||
3278  has_non_default_from_json <
3279  BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3280 };
3281 
3282 template<typename BasicJsonType, typename ConstructibleArrayType>
3283 struct is_constructible_array_type
3284  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3285 
3286 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3287  typename = void>
3288 struct is_compatible_integer_type_impl : std::false_type {};
3289 
3290 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3291 struct is_compatible_integer_type_impl <
3292  RealIntegerType, CompatibleNumberIntegerType,
3293  enable_if_t < std::is_integral<RealIntegerType>::value&&
3294  std::is_integral<CompatibleNumberIntegerType>::value&&
3295  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3296 {
3297  // is there an assert somewhere on overflows?
3298  using RealLimits = std::numeric_limits<RealIntegerType>;
3299  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3300 
3301  static constexpr auto value =
3302  std::is_constructible<RealIntegerType,
3303  CompatibleNumberIntegerType>::value &&
3304  CompatibleLimits::is_integer &&
3305  RealLimits::is_signed == CompatibleLimits::is_signed;
3306 };
3307 
3308 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3309 struct is_compatible_integer_type
3310  : is_compatible_integer_type_impl<RealIntegerType,
3311  CompatibleNumberIntegerType> {};
3312 
3313 template<typename BasicJsonType, typename CompatibleType, typename = void>
3314 struct is_compatible_type_impl: std::false_type {};
3315 
3316 template<typename BasicJsonType, typename CompatibleType>
3317 struct is_compatible_type_impl <
3318  BasicJsonType, CompatibleType,
3319  enable_if_t<is_complete_type<CompatibleType>::value >>
3320 {
3321  static constexpr bool value =
3322  has_to_json<BasicJsonType, CompatibleType>::value;
3323 };
3324 
3325 template<typename BasicJsonType, typename CompatibleType>
3326 struct is_compatible_type
3327  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3328 
3329 // https://en.cppreference.com/w/cpp/types/conjunction
3330 template<class...> struct conjunction : std::true_type { };
3331 template<class B1> struct conjunction<B1> : B1 { };
3332 template<class B1, class... Bn>
3333 struct conjunction<B1, Bn...>
3334 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3335 
3336 template<typename T1, typename T2>
3337 struct is_constructible_tuple : std::false_type {};
3338 
3339 template<typename T1, typename... Args>
3340 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3341 } // namespace detail
3342 } // namespace nlohmann
3343 
3344 // #include <nlohmann/detail/value_t.hpp>
3345 
3346 
3347 #include <array> // array
3348 #include <cstddef> // size_t
3349 #include <cstdint> // uint8_t
3350 #include <string> // string
3351 
3352 namespace nlohmann
3353 {
3354 namespace detail
3355 {
3357 // JSON type enumeration //
3359 
3384 enum class value_t : std::uint8_t
3385 {
3386  null,
3387  object,
3388  array,
3389  string,
3390  boolean,
3391  number_integer,
3392  number_unsigned,
3393  number_float,
3394  binary,
3395  discarded
3396 };
3397 
3411 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3412 {
3413  static constexpr std::array<std::uint8_t, 9> order = {{
3414  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3415  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3416  6 /* binary */
3417  }
3418  };
3419 
3420  const auto l_index = static_cast<std::size_t>(lhs);
3421  const auto r_index = static_cast<std::size_t>(rhs);
3422  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3423 }
3424 } // namespace detail
3425 } // namespace nlohmann
3426 
3427 
3428 namespace nlohmann
3429 {
3430 namespace detail
3431 {
3432 template<typename BasicJsonType>
3433 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3434 {
3435  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3436  {
3437  JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3438  }
3439  n = nullptr;
3440 }
3441 
3442 // overloads for basic_json template parameters
3443 template < typename BasicJsonType, typename ArithmeticType,
3444  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3445  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3446  int > = 0 >
3447 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3448 {
3449  switch (static_cast<value_t>(j))
3450  {
3451  case value_t::number_unsigned:
3452  {
3453  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3454  break;
3455  }
3456  case value_t::number_integer:
3457  {
3458  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3459  break;
3460  }
3461  case value_t::number_float:
3462  {
3463  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3464  break;
3465  }
3466 
3467  default:
3468  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3469  }
3470 }
3471 
3472 template<typename BasicJsonType>
3473 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3474 {
3475  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3476  {
3477  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3478  }
3479  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3480 }
3481 
3482 template<typename BasicJsonType>
3483 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3484 {
3485  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3486  {
3487  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3488  }
3489  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3490 }
3491 
3492 template <
3493  typename BasicJsonType, typename ConstructibleStringType,
3494  enable_if_t <
3495  is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3496  !std::is_same<typename BasicJsonType::string_t,
3497  ConstructibleStringType>::value,
3498  int > = 0 >
3499 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3500 {
3501  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3502  {
3503  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3504  }
3505 
3506  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3507 }
3508 
3509 template<typename BasicJsonType>
3510 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3511 {
3512  get_arithmetic_value(j, val);
3513 }
3514 
3515 template<typename BasicJsonType>
3516 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3517 {
3518  get_arithmetic_value(j, val);
3519 }
3520 
3521 template<typename BasicJsonType>
3522 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3523 {
3524  get_arithmetic_value(j, val);
3525 }
3526 
3527 template<typename BasicJsonType, typename EnumType,
3528  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3529 void from_json(const BasicJsonType& j, EnumType& e)
3530 {
3531  typename std::underlying_type<EnumType>::type val;
3532  get_arithmetic_value(j, val);
3533  e = static_cast<EnumType>(val);
3534 }
3535 
3536 // forward_list doesn't have an insert method
3537 template<typename BasicJsonType, typename T, typename Allocator,
3538  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3539 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3540 {
3541  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3542  {
3543  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3544  }
3545  l.clear();
3546  std::transform(j.rbegin(), j.rend(),
3547  std::front_inserter(l), [](const BasicJsonType & i)
3548  {
3549  return i.template get<T>();
3550  });
3551 }
3552 
3553 // valarray doesn't have an insert method
3554 template<typename BasicJsonType, typename T,
3555  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3556 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3557 {
3558  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3559  {
3560  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3561  }
3562  l.resize(j.size());
3563  std::transform(j.begin(), j.end(), std::begin(l),
3564  [](const BasicJsonType & elem)
3565  {
3566  return elem.template get<T>();
3567  });
3568 }
3569 
3570 template<typename BasicJsonType, typename T, std::size_t N>
3571 auto from_json(const BasicJsonType& j, T (&arr)[N])
3572 -> decltype(j.template get<T>(), void())
3573 {
3574  for (std::size_t i = 0; i < N; ++i)
3575  {
3576  arr[i] = j.at(i).template get<T>();
3577  }
3578 }
3579 
3580 template<typename BasicJsonType>
3581 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3582 {
3583  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3584 }
3585 
3586 template<typename BasicJsonType, typename T, std::size_t N>
3587 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3588  priority_tag<2> /*unused*/)
3589 -> decltype(j.template get<T>(), void())
3590 {
3591  for (std::size_t i = 0; i < N; ++i)
3592  {
3593  arr[i] = j.at(i).template get<T>();
3594  }
3595 }
3596 
3597 template<typename BasicJsonType, typename ConstructibleArrayType>
3598 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3599 -> decltype(
3600  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3601  j.template get<typename ConstructibleArrayType::value_type>(),
3602  void())
3603 {
3604  using std::end;
3605 
3606  ConstructibleArrayType ret;
3607  ret.reserve(j.size());
3608  std::transform(j.begin(), j.end(),
3609  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3610  {
3611  // get<BasicJsonType>() returns *this, this won't call a from_json
3612  // method when value_type is BasicJsonType
3613  return i.template get<typename ConstructibleArrayType::value_type>();
3614  });
3615  arr = std::move(ret);
3616 }
3617 
3618 template<typename BasicJsonType, typename ConstructibleArrayType>
3619 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3620  priority_tag<0> /*unused*/)
3621 {
3622  using std::end;
3623 
3624  ConstructibleArrayType ret;
3625  std::transform(
3626  j.begin(), j.end(), std::inserter(ret, end(ret)),
3627  [](const BasicJsonType & i)
3628  {
3629  // get<BasicJsonType>() returns *this, this won't call a from_json
3630  // method when value_type is BasicJsonType
3631  return i.template get<typename ConstructibleArrayType::value_type>();
3632  });
3633  arr = std::move(ret);
3634 }
3635 
3636 template < typename BasicJsonType, typename ConstructibleArrayType,
3637  enable_if_t <
3638  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3639  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3640  !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3641  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3642  !is_basic_json<ConstructibleArrayType>::value,
3643  int > = 0 >
3644 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3645 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3646 j.template get<typename ConstructibleArrayType::value_type>(),
3647 void())
3648 {
3649  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3650  {
3651  JSON_THROW(type_error::create(302, "type must be array, but is " +
3652  std::string(j.type_name())));
3653  }
3654 
3655  from_json_array_impl(j, arr, priority_tag<3> {});
3656 }
3657 
3658 template<typename BasicJsonType>
3659 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3660 {
3661  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3662  {
3663  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3664  }
3665 
3666  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3667 }
3668 
3669 template<typename BasicJsonType, typename ConstructibleObjectType,
3670  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3671 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3672 {
3673  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3674  {
3675  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3676  }
3677 
3678  ConstructibleObjectType ret;
3679  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3680  using value_type = typename ConstructibleObjectType::value_type;
3681  std::transform(
3682  inner_object->begin(), inner_object->end(),
3683  std::inserter(ret, ret.begin()),
3684  [](typename BasicJsonType::object_t::value_type const & p)
3685  {
3686  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3687  });
3688  obj = std::move(ret);
3689 }
3690 
3691 // overload for arithmetic types, not chosen for basic_json template arguments
3692 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3693 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3694 // an arithmetic type?
3695 template < typename BasicJsonType, typename ArithmeticType,
3696  enable_if_t <
3697  std::is_arithmetic<ArithmeticType>::value&&
3698  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3699  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3700  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3701  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3702  int > = 0 >
3703 void from_json(const BasicJsonType& j, ArithmeticType& val)
3704 {
3705  switch (static_cast<value_t>(j))
3706  {
3707  case value_t::number_unsigned:
3708  {
3709  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3710  break;
3711  }
3712  case value_t::number_integer:
3713  {
3714  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3715  break;
3716  }
3717  case value_t::number_float:
3718  {
3719  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3720  break;
3721  }
3722  case value_t::boolean:
3723  {
3724  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3725  break;
3726  }
3727 
3728  default:
3729  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3730  }
3731 }
3732 
3733 template<typename BasicJsonType, typename A1, typename A2>
3734 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3735 {
3736  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3737 }
3738 
3739 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3740 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3741 {
3742  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3743 }
3744 
3745 template<typename BasicJsonType, typename... Args>
3746 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3747 {
3748  from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3749 }
3750 
3751 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3752  typename = enable_if_t < !std::is_constructible <
3753  typename BasicJsonType::string_t, Key >::value >>
3754 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3755 {
3756  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3757  {
3758  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3759  }
3760  m.clear();
3761  for (const auto& p : j)
3762  {
3763  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3764  {
3765  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3766  }
3767  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3768  }
3769 }
3770 
3771 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3772  typename = enable_if_t < !std::is_constructible <
3773  typename BasicJsonType::string_t, Key >::value >>
3774 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3775 {
3776  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3777  {
3778  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3779  }
3780  m.clear();
3781  for (const auto& p : j)
3782  {
3783  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3784  {
3785  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3786  }
3787  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3788  }
3789 }
3790 
3791 struct from_json_fn
3792 {
3793  template<typename BasicJsonType, typename T>
3794  auto operator()(const BasicJsonType& j, T& val) const
3795  noexcept(noexcept(from_json(j, val)))
3796  -> decltype(from_json(j, val), void())
3797  {
3798  return from_json(j, val);
3799  }
3800 };
3801 } // namespace detail
3802 
3806 namespace
3807 {
3808 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3809 } // namespace
3810 } // namespace nlohmann
3811 
3812 // #include <nlohmann/detail/conversions/to_json.hpp>
3813 
3814 
3815 #include <algorithm> // copy
3816 #include <iterator> // begin, end
3817 #include <string> // string
3818 #include <tuple> // tuple, get
3819 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3820 #include <utility> // move, forward, declval, pair
3821 #include <valarray> // valarray
3822 #include <vector> // vector
3823 
3824 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3825 
3826 
3827 #include <cstddef> // size_t
3828 #include <iterator> // input_iterator_tag
3829 #include <string> // string, to_string
3830 #include <tuple> // tuple_size, get, tuple_element
3831 
3832 // #include <nlohmann/detail/meta/type_traits.hpp>
3833 
3834 // #include <nlohmann/detail/value_t.hpp>
3835 
3836 
3837 namespace nlohmann
3838 {
3839 namespace detail
3840 {
3841 template<typename string_type>
3842 void int_to_string( string_type& target, std::size_t value )
3843 {
3844  // For ADL
3845  using std::to_string;
3846  target = to_string(value);
3847 }
3848 template<typename IteratorType> class iteration_proxy_value
3849 {
3850  public:
3851  using difference_type = std::ptrdiff_t;
3852  using value_type = iteration_proxy_value;
3853  using pointer = value_type * ;
3854  using reference = value_type & ;
3855  using iterator_category = std::input_iterator_tag;
3856  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3857 
3858  private:
3860  IteratorType anchor;
3862  std::size_t array_index = 0;
3864  mutable std::size_t array_index_last = 0;
3866  mutable string_type array_index_str = "0";
3868  const string_type empty_str = "";
3869 
3870  public:
3871  explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3872 
3874  iteration_proxy_value& operator*()
3875  {
3876  return *this;
3877  }
3878 
3880  iteration_proxy_value& operator++()
3881  {
3882  ++anchor;
3883  ++array_index;
3884 
3885  return *this;
3886  }
3887 
3889  bool operator==(const iteration_proxy_value& o) const
3890  {
3891  return anchor == o.anchor;
3892  }
3893 
3895  bool operator!=(const iteration_proxy_value& o) const
3896  {
3897  return anchor != o.anchor;
3898  }
3899 
3901  const string_type& key() const
3902  {
3903  JSON_ASSERT(anchor.m_object != nullptr);
3904 
3905  switch (anchor.m_object->type())
3906  {
3907  // use integer array index as key
3908  case value_t::array:
3909  {
3910  if (array_index != array_index_last)
3911  {
3912  int_to_string( array_index_str, array_index );
3913  array_index_last = array_index;
3914  }
3915  return array_index_str;
3916  }
3917 
3918  // use key from the object
3919  case value_t::object:
3920  return anchor.key();
3921 
3922  // use an empty key for all primitive types
3923  default:
3924  return empty_str;
3925  }
3926  }
3927 
3929  typename IteratorType::reference value() const
3930  {
3931  return anchor.value();
3932  }
3933 };
3934 
3936 template<typename IteratorType> class iteration_proxy
3937 {
3938  private:
3940  typename IteratorType::reference container;
3941 
3942  public:
3944  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3945  : container(cont) {}
3946 
3948  iteration_proxy_value<IteratorType> begin() noexcept
3949  {
3950  return iteration_proxy_value<IteratorType>(container.begin());
3951  }
3952 
3954  iteration_proxy_value<IteratorType> end() noexcept
3955  {
3956  return iteration_proxy_value<IteratorType>(container.end());
3957  }
3958 };
3959 // Structured Bindings Support
3960 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3961 // And see https://github.com/nlohmann/json/pull/1391
3962 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3963 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3964 {
3965  return i.key();
3966 }
3967 // Structured Bindings Support
3968 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3969 // And see https://github.com/nlohmann/json/pull/1391
3970 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3971 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3972 {
3973  return i.value();
3974 }
3975 } // namespace detail
3976 } // namespace nlohmann
3977 
3978 // The Addition to the STD Namespace is required to add
3979 // Structured Bindings Support to the iteration_proxy_value class
3980 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3981 // And see https://github.com/nlohmann/json/pull/1391
3982 namespace std
3983 {
3984 #if defined(__clang__)
3985  // Fix: https://github.com/nlohmann/json/issues/1401
3986  #pragma clang diagnostic push
3987  #pragma clang diagnostic ignored "-Wmismatched-tags"
3988 #endif
3989 template<typename IteratorType>
3990 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3991  : public std::integral_constant<std::size_t, 2> {};
3992 
3993 template<std::size_t N, typename IteratorType>
3994 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3995 {
3996  public:
3997  using type = decltype(
3998  get<N>(std::declval <
3999  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4000 };
4001 #if defined(__clang__)
4002  #pragma clang diagnostic pop
4003 #endif
4004 } // namespace std
4005 
4006 // #include <nlohmann/detail/meta/cpp_future.hpp>
4007 
4008 // #include <nlohmann/detail/meta/type_traits.hpp>
4009 
4010 // #include <nlohmann/detail/value_t.hpp>
4011 
4012 
4013 namespace nlohmann
4014 {
4015 namespace detail
4016 {
4018 // constructors //
4020 
4021 template<value_t> struct external_constructor;
4022 
4023 template<>
4024 struct external_constructor<value_t::boolean>
4025 {
4026  template<typename BasicJsonType>
4027  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4028  {
4029  j.m_type = value_t::boolean;
4030  j.m_value = b;
4031  j.assert_invariant();
4032  }
4033 };
4034 
4035 template<>
4036 struct external_constructor<value_t::string>
4037 {
4038  template<typename BasicJsonType>
4039  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4040  {
4041  j.m_type = value_t::string;
4042  j.m_value = s;
4043  j.assert_invariant();
4044  }
4045 
4046  template<typename BasicJsonType>
4047  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4048  {
4049  j.m_type = value_t::string;
4050  j.m_value = std::move(s);
4051  j.assert_invariant();
4052  }
4053 
4054  template < typename BasicJsonType, typename CompatibleStringType,
4055  enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4056  int > = 0 >
4057  static void construct(BasicJsonType& j, const CompatibleStringType& str)
4058  {
4059  j.m_type = value_t::string;
4060  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4061  j.assert_invariant();
4062  }
4063 };
4064 
4065 template<>
4066 struct external_constructor<value_t::binary>
4067 {
4068  template<typename BasicJsonType>
4069  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4070  {
4071  j.m_type = value_t::binary;
4072  typename BasicJsonType::binary_t value{b};
4073  j.m_value = value;
4074  j.assert_invariant();
4075  }
4076 
4077  template<typename BasicJsonType>
4078  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4079  {
4080  j.m_type = value_t::binary;
4081  typename BasicJsonType::binary_t value{std::move(b)};
4082  j.m_value = value;
4083  j.assert_invariant();
4084  }
4085 };
4086 
4087 template<>
4088 struct external_constructor<value_t::number_float>
4089 {
4090  template<typename BasicJsonType>
4091  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4092  {
4093  j.m_type = value_t::number_float;
4094  j.m_value = val;
4095  j.assert_invariant();
4096  }
4097 };
4098 
4099 template<>
4100 struct external_constructor<value_t::number_unsigned>
4101 {
4102  template<typename BasicJsonType>
4103  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4104  {
4105  j.m_type = value_t::number_unsigned;
4106  j.m_value = val;
4107  j.assert_invariant();
4108  }
4109 };
4110 
4111 template<>
4112 struct external_constructor<value_t::number_integer>
4113 {
4114  template<typename BasicJsonType>
4115  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4116  {
4117  j.m_type = value_t::number_integer;
4118  j.m_value = val;
4119  j.assert_invariant();
4120  }
4121 };
4122 
4123 template<>
4124 struct external_constructor<value_t::array>
4125 {
4126  template<typename BasicJsonType>
4127  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4128  {
4129  j.m_type = value_t::array;
4130  j.m_value = arr;
4131  j.assert_invariant();
4132  }
4133 
4134  template<typename BasicJsonType>
4135  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4136  {
4137  j.m_type = value_t::array;
4138  j.m_value = std::move(arr);
4139  j.assert_invariant();
4140  }
4141 
4142  template < typename BasicJsonType, typename CompatibleArrayType,
4143  enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4144  int > = 0 >
4145  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4146  {
4147  using std::begin;
4148  using std::end;
4149  j.m_type = value_t::array;
4150  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4151  j.assert_invariant();
4152  }
4153 
4154  template<typename BasicJsonType>
4155  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4156  {
4157  j.m_type = value_t::array;
4158  j.m_value = value_t::array;
4159  j.m_value.array->reserve(arr.size());
4160  for (const bool x : arr)
4161  {
4162  j.m_value.array->push_back(x);
4163  }
4164  j.assert_invariant();
4165  }
4166 
4167  template<typename BasicJsonType, typename T,
4168  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4169  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4170  {
4171  j.m_type = value_t::array;
4172  j.m_value = value_t::array;
4173  j.m_value.array->resize(arr.size());
4174  if (arr.size() > 0)
4175  {
4176  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4177  }
4178  j.assert_invariant();
4179  }
4180 };
4181 
4182 template<>
4183 struct external_constructor<value_t::object>
4184 {
4185  template<typename BasicJsonType>
4186  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4187  {
4188  j.m_type = value_t::object;
4189  j.m_value = obj;
4190  j.assert_invariant();
4191  }
4192 
4193  template<typename BasicJsonType>
4194  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4195  {
4196  j.m_type = value_t::object;
4197  j.m_value = std::move(obj);
4198  j.assert_invariant();
4199  }
4200 
4201  template < typename BasicJsonType, typename CompatibleObjectType,
4202  enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4203  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4204  {
4205  using std::begin;
4206  using std::end;
4207 
4208  j.m_type = value_t::object;
4209  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4210  j.assert_invariant();
4211  }
4212 };
4213 
4215 // to_json //
4217 
4218 template<typename BasicJsonType, typename T,
4219  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4220 void to_json(BasicJsonType& j, T b) noexcept
4221 {
4222  external_constructor<value_t::boolean>::construct(j, b);
4223 }
4224 
4225 template<typename BasicJsonType, typename CompatibleString,
4226  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4227 void to_json(BasicJsonType& j, const CompatibleString& s)
4228 {
4229  external_constructor<value_t::string>::construct(j, s);
4230 }
4231 
4232 template<typename BasicJsonType>
4233 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4234 {
4235  external_constructor<value_t::string>::construct(j, std::move(s));
4236 }
4237 
4238 template<typename BasicJsonType, typename FloatType,
4239  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4240 void to_json(BasicJsonType& j, FloatType val) noexcept
4241 {
4242  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4243 }
4244 
4245 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4246  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4247 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4248 {
4249  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4250 }
4251 
4252 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4253  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4254 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4255 {
4256  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4257 }
4258 
4259 template<typename BasicJsonType, typename EnumType,
4260  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4261 void to_json(BasicJsonType& j, EnumType e) noexcept
4262 {
4263  using underlying_type = typename std::underlying_type<EnumType>::type;
4264  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4265 }
4266 
4267 template<typename BasicJsonType>
4268 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4269 {
4270  external_constructor<value_t::array>::construct(j, e);
4271 }
4272 
4273 template < typename BasicJsonType, typename CompatibleArrayType,
4274  enable_if_t < is_compatible_array_type<BasicJsonType,
4275  CompatibleArrayType>::value&&
4276  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4277  !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4278  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4279  !is_basic_json<CompatibleArrayType>::value,
4280  int > = 0 >
4281 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4282 {
4283  external_constructor<value_t::array>::construct(j, arr);
4284 }
4285 
4286 template<typename BasicJsonType>
4287 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4288 {
4289  external_constructor<value_t::binary>::construct(j, bin);
4290 }
4291 
4292 template<typename BasicJsonType, typename T,
4293  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4294 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4295 {
4296  external_constructor<value_t::array>::construct(j, std::move(arr));
4297 }
4298 
4299 template<typename BasicJsonType>
4300 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4301 {
4302  external_constructor<value_t::array>::construct(j, std::move(arr));
4303 }
4304 
4305 template < typename BasicJsonType, typename CompatibleObjectType,
4306  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4307 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4308 {
4309  external_constructor<value_t::object>::construct(j, obj);
4310 }
4311 
4312 template<typename BasicJsonType>
4313 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4314 {
4315  external_constructor<value_t::object>::construct(j, std::move(obj));
4316 }
4317 
4318 template <
4319  typename BasicJsonType, typename T, std::size_t N,
4320  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4321  const T(&)[N]>::value,
4322  int > = 0 >
4323 void to_json(BasicJsonType& j, const T(&arr)[N])
4324 {
4325  external_constructor<value_t::array>::construct(j, arr);
4326 }
4327 
4328 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4329 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4330 {
4331  j = { p.first, p.second };
4332 }
4333 
4334 // for https://github.com/nlohmann/json/pull/1134
4335 template<typename BasicJsonType, typename T,
4336  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4337 void to_json(BasicJsonType& j, const T& b)
4338 {
4339  j = { {b.key(), b.value()} };
4340 }
4341 
4342 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4343 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4344 {
4345  j = { std::get<Idx>(t)... };
4346 }
4347 
4348 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4349 void to_json(BasicJsonType& j, const T& t)
4350 {
4351  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4352 }
4353 
4354 struct to_json_fn
4355 {
4356  template<typename BasicJsonType, typename T>
4357  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4358  -> decltype(to_json(j, std::forward<T>(val)), void())
4359  {
4360  return to_json(j, std::forward<T>(val));
4361  }
4362 };
4363 } // namespace detail
4364 
4366 namespace
4367 {
4368 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4369 } // namespace
4370 } // namespace nlohmann
4371 
4372 
4373 namespace nlohmann
4374 {
4375 
4376 template<typename, typename>
4378 {
4388  template<typename BasicJsonType, typename ValueType>
4389  static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4390  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4391  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4392  {
4393  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4394  }
4395 
4405  template<typename BasicJsonType, typename ValueType>
4406  static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4407  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4408  -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4409  {
4410  ::nlohmann::to_json(j, std::forward<ValueType>(val));
4411  }
4412 };
4413 
4414 } // namespace nlohmann
4415 
4416 // #include <nlohmann/byte_container_with_subtype.hpp>
4417 
4418 
4419 #include <cstdint> // uint8_t
4420 #include <tuple> // tie
4421 #include <utility> // move
4422 
4423 namespace nlohmann
4424 {
4425 
4439 template<typename BinaryType>
4440 class byte_container_with_subtype : public BinaryType
4441 {
4442  public:
4444  using container_type = BinaryType;
4445 
4447  : container_type()
4448  {}
4449 
4451  : container_type(b)
4452  {}
4453 
4454  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4455  : container_type(std::move(b))
4456  {}
4457 
4458  byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4459  : container_type(b)
4460  , m_subtype(subtype)
4461  , m_has_subtype(true)
4462  {}
4463 
4464  byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4465  : container_type(std::move(b))
4466  , m_subtype(subtype)
4467  , m_has_subtype(true)
4468  {}
4469 
4471  {
4472  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4473  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4474  }
4475 
4477  {
4478  return !(rhs == *this);
4479  }
4480 
4499  void set_subtype(std::uint8_t subtype) noexcept
4500  {
4501  m_subtype = subtype;
4502  m_has_subtype = true;
4503  }
4504 
4526  constexpr std::uint8_t subtype() const noexcept
4527  {
4528  return m_subtype;
4529  }
4530 
4547  constexpr bool has_subtype() const noexcept
4548  {
4549  return m_has_subtype;
4550  }
4551 
4571  void clear_subtype() noexcept
4572  {
4573  m_subtype = 0;
4574  m_has_subtype = false;
4575  }
4576 
4577  private:
4578  std::uint8_t m_subtype = 0;
4579  bool m_has_subtype = false;
4580 };
4581 
4582 } // namespace nlohmann
4583 
4584 // #include <nlohmann/detail/conversions/from_json.hpp>
4585 
4586 // #include <nlohmann/detail/conversions/to_json.hpp>
4587 
4588 // #include <nlohmann/detail/exceptions.hpp>
4589 
4590 // #include <nlohmann/detail/hash.hpp>
4591 
4592 
4593 #include <cstddef> // size_t, uint8_t
4594 #include <functional> // hash
4595 
4596 namespace nlohmann
4597 {
4598 namespace detail
4599 {
4600 
4601 // boost::hash_combine
4602 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4603 {
4604  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4605  return seed;
4606 }
4607 
4619 template<typename BasicJsonType>
4620 std::size_t hash(const BasicJsonType& j)
4621 {
4622  using string_t = typename BasicJsonType::string_t;
4623  using number_integer_t = typename BasicJsonType::number_integer_t;
4624  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4625  using number_float_t = typename BasicJsonType::number_float_t;
4626 
4627  const auto type = static_cast<std::size_t>(j.type());
4628  switch (j.type())
4629  {
4630  case BasicJsonType::value_t::null:
4631  case BasicJsonType::value_t::discarded:
4632  {
4633  return combine(type, 0);
4634  }
4635 
4636  case BasicJsonType::value_t::object:
4637  {
4638  auto seed = combine(type, j.size());
4639  for (const auto& element : j.items())
4640  {
4641  const auto h = std::hash<string_t> {}(element.key());
4642  seed = combine(seed, h);
4643  seed = combine(seed, hash(element.value()));
4644  }
4645  return seed;
4646  }
4647 
4648  case BasicJsonType::value_t::array:
4649  {
4650  auto seed = combine(type, j.size());
4651  for (const auto& element : j)
4652  {
4653  seed = combine(seed, hash(element));
4654  }
4655  return seed;
4656  }
4657 
4658  case BasicJsonType::value_t::string:
4659  {
4660  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4661  return combine(type, h);
4662  }
4663 
4664  case BasicJsonType::value_t::boolean:
4665  {
4666  const auto h = std::hash<bool> {}(j.template get<bool>());
4667  return combine(type, h);
4668  }
4669 
4670  case BasicJsonType::value_t::number_integer:
4671  {
4672  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4673  return combine(type, h);
4674  }
4675 
4676  case BasicJsonType::value_t::number_unsigned:
4677  {
4678  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4679  return combine(type, h);
4680  }
4681 
4682  case BasicJsonType::value_t::number_float:
4683  {
4684  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4685  return combine(type, h);
4686  }
4687 
4688  case BasicJsonType::value_t::binary:
4689  {
4690  auto seed = combine(type, j.get_binary().size());
4691  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4692  seed = combine(seed, h);
4693  seed = combine(seed, j.get_binary().subtype());
4694  for (const auto byte : j.get_binary())
4695  {
4696  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4697  }
4698  return seed;
4699  }
4700 
4701  default: // LCOV_EXCL_LINE
4702  JSON_ASSERT(false); // LCOV_EXCL_LINE
4703  return 0; // LCOV_EXCL_LINE
4704  }
4705 }
4706 
4707 } // namespace detail
4708 } // namespace nlohmann
4709 
4710 // #include <nlohmann/detail/input/binary_reader.hpp>
4711 
4712 
4713 #include <algorithm> // generate_n
4714 #include <array> // array
4715 #include <cmath> // ldexp
4716 #include <cstddef> // size_t
4717 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4718 #include <cstdio> // snprintf
4719 #include <cstring> // memcpy
4720 #include <iterator> // back_inserter
4721 #include <limits> // numeric_limits
4722 #include <string> // char_traits, string
4723 #include <utility> // make_pair, move
4724 
4725 // #include <nlohmann/detail/exceptions.hpp>
4726 
4727 // #include <nlohmann/detail/input/input_adapters.hpp>
4728 
4729 
4730 #include <array> // array
4731 #include <cstddef> // size_t
4732 #include <cstdio> //FILE *
4733 #include <cstring> // strlen
4734 #include <istream> // istream
4735 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4736 #include <memory> // shared_ptr, make_shared, addressof
4737 #include <numeric> // accumulate
4738 #include <string> // string, char_traits
4739 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4740 #include <utility> // pair, declval
4741 
4742 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4743 
4744 // #include <nlohmann/detail/macro_scope.hpp>
4745 
4746 
4747 namespace nlohmann
4748 {
4749 namespace detail
4750 {
4752 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4753 
4755 // input adapters //
4757 
4762 class file_input_adapter
4763 {
4764  public:
4765  using char_type = char;
4766 
4767  JSON_HEDLEY_NON_NULL(2)
4768  explicit file_input_adapter(std::FILE* f) noexcept
4769  : m_file(f)
4770  {}
4771 
4772  // make class move-only
4773  file_input_adapter(const file_input_adapter&) = delete;
4774  file_input_adapter(file_input_adapter&&) = default;
4775  file_input_adapter& operator=(const file_input_adapter&) = delete;
4776  file_input_adapter& operator=(file_input_adapter&&) = delete;
4777 
4778  std::char_traits<char>::int_type get_character() noexcept
4779  {
4780  return std::fgetc(m_file);
4781  }
4782 
4783  private:
4785  std::FILE* m_file;
4786 };
4787 
4788 
4798 class input_stream_adapter
4799 {
4800  public:
4801  using char_type = char;
4802 
4803  ~input_stream_adapter()
4804  {
4805  // clear stream flags; we use underlying streambuf I/O, do not
4806  // maintain ifstream flags, except eof
4807  if (is != nullptr)
4808  {
4809  is->clear(is->rdstate() & std::ios::eofbit);
4810  }
4811  }
4812 
4813  explicit input_stream_adapter(std::istream& i)
4814  : is(&i), sb(i.rdbuf())
4815  {}
4816 
4817  // delete because of pointer members
4818  input_stream_adapter(const input_stream_adapter&) = delete;
4819  input_stream_adapter& operator=(input_stream_adapter&) = delete;
4820  input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4821 
4822  input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4823  {
4824  rhs.is = nullptr;
4825  rhs.sb = nullptr;
4826  }
4827 
4828  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4829  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4830  // end up as the same value, eg. 0xFFFFFFFF.
4831  std::char_traits<char>::int_type get_character()
4832  {
4833  auto res = sb->sbumpc();
4834  // set eof manually, as we don't use the istream interface.
4835  if (JSON_HEDLEY_UNLIKELY(res == EOF))
4836  {
4837  is->clear(is->rdstate() | std::ios::eofbit);
4838  }
4839  return res;
4840  }
4841 
4842  private:
4844  std::istream* is = nullptr;
4845  std::streambuf* sb = nullptr;
4846 };
4847 
4848 // General-purpose iterator-based adapter. It might not be as fast as
4849 // theoretically possible for some containers, but it is extremely versatile.
4850 template<typename IteratorType>
4851 class iterator_input_adapter
4852 {
4853  public:
4854  using char_type = typename std::iterator_traits<IteratorType>::value_type;
4855 
4856  iterator_input_adapter(IteratorType first, IteratorType last)
4857  : current(std::move(first)), end(std::move(last)) {}
4858 
4859  typename std::char_traits<char_type>::int_type get_character()
4860  {
4861  if (JSON_HEDLEY_LIKELY(current != end))
4862  {
4863  auto result = std::char_traits<char_type>::to_int_type(*current);
4864  std::advance(current, 1);
4865  return result;
4866  }
4867  else
4868  {
4869  return std::char_traits<char_type>::eof();
4870  }
4871  }
4872 
4873  private:
4874  IteratorType current;
4875  IteratorType end;
4876 
4877  template<typename BaseInputAdapter, size_t T>
4878  friend struct wide_string_input_helper;
4879 
4880  bool empty() const
4881  {
4882  return current == end;
4883  }
4884 
4885 };
4886 
4887 
4888 template<typename BaseInputAdapter, size_t T>
4889 struct wide_string_input_helper;
4890 
4891 template<typename BaseInputAdapter>
4892 struct wide_string_input_helper<BaseInputAdapter, 4>
4893 {
4894  // UTF-32
4895  static void fill_buffer(BaseInputAdapter& input,
4896  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4897  size_t& utf8_bytes_index,
4898  size_t& utf8_bytes_filled)
4899  {
4900  utf8_bytes_index = 0;
4901 
4902  if (JSON_HEDLEY_UNLIKELY(input.empty()))
4903  {
4904  utf8_bytes[0] = std::char_traits<char>::eof();
4905  utf8_bytes_filled = 1;
4906  }
4907  else
4908  {
4909  // get the current character
4910  const auto wc = input.get_character();
4911 
4912  // UTF-32 to UTF-8 encoding
4913  if (wc < 0x80)
4914  {
4915  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4916  utf8_bytes_filled = 1;
4917  }
4918  else if (wc <= 0x7FF)
4919  {
4920  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4921  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4922  utf8_bytes_filled = 2;
4923  }
4924  else if (wc <= 0xFFFF)
4925  {
4926  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4927  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4928  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4929  utf8_bytes_filled = 3;
4930  }
4931  else if (wc <= 0x10FFFF)
4932  {
4933  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4934  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4935  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4936  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4937  utf8_bytes_filled = 4;
4938  }
4939  else
4940  {
4941  // unknown character
4942  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4943  utf8_bytes_filled = 1;
4944  }
4945  }
4946  }
4947 };
4948 
4949 template<typename BaseInputAdapter>
4950 struct wide_string_input_helper<BaseInputAdapter, 2>
4951 {
4952  // UTF-16
4953  static void fill_buffer(BaseInputAdapter& input,
4954  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4955  size_t& utf8_bytes_index,
4956  size_t& utf8_bytes_filled)
4957  {
4958  utf8_bytes_index = 0;
4959 
4960  if (JSON_HEDLEY_UNLIKELY(input.empty()))
4961  {
4962  utf8_bytes[0] = std::char_traits<char>::eof();
4963  utf8_bytes_filled = 1;
4964  }
4965  else
4966  {
4967  // get the current character
4968  const auto wc = input.get_character();
4969 
4970  // UTF-16 to UTF-8 encoding
4971  if (wc < 0x80)
4972  {
4973  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4974  utf8_bytes_filled = 1;
4975  }
4976  else if (wc <= 0x7FF)
4977  {
4978  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
4979  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4980  utf8_bytes_filled = 2;
4981  }
4982  else if (0xD800 > wc || wc >= 0xE000)
4983  {
4984  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
4985  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4986  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4987  utf8_bytes_filled = 3;
4988  }
4989  else
4990  {
4991  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
4992  {
4993  const auto wc2 = static_cast<unsigned int>(input.get_character());
4994  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4995  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4996  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4997  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4998  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4999  utf8_bytes_filled = 4;
5000  }
5001  else
5002  {
5003  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5004  utf8_bytes_filled = 1;
5005  }
5006  }
5007  }
5008  }
5009 };
5010 
5011 // Wraps another input apdater to convert wide character types into individual bytes.
5012 template<typename BaseInputAdapter, typename WideCharType>
5013 class wide_string_input_adapter
5014 {
5015  public:
5016  using char_type = char;
5017 
5018  wide_string_input_adapter(BaseInputAdapter base)
5019  : base_adapter(base) {}
5020 
5021  typename std::char_traits<char>::int_type get_character() noexcept
5022  {
5023  // check if buffer needs to be filled
5024  if (utf8_bytes_index == utf8_bytes_filled)
5025  {
5026  fill_buffer<sizeof(WideCharType)>();
5027 
5028  JSON_ASSERT(utf8_bytes_filled > 0);
5029  JSON_ASSERT(utf8_bytes_index == 0);
5030  }
5031 
5032  // use buffer
5033  JSON_ASSERT(utf8_bytes_filled > 0);
5034  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5035  return utf8_bytes[utf8_bytes_index++];
5036  }
5037 
5038  private:
5039  BaseInputAdapter base_adapter;
5040 
5041  template<size_t T>
5042  void fill_buffer()
5043  {
5044  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5045  }
5046 
5048  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5049 
5051  std::size_t utf8_bytes_index = 0;
5053  std::size_t utf8_bytes_filled = 0;
5054 };
5055 
5056 
5057 template<typename IteratorType, typename Enable = void>
5058 struct iterator_input_adapter_factory
5059 {
5060  using iterator_type = IteratorType;
5061  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5062  using adapter_type = iterator_input_adapter<iterator_type>;
5063 
5064  static adapter_type create(IteratorType first, IteratorType last)
5065  {
5066  return adapter_type(std::move(first), std::move(last));
5067  }
5068 };
5069 
5070 template<typename T>
5071 struct is_iterator_of_multibyte
5072 {
5073  using value_type = typename std::iterator_traits<T>::value_type;
5074  enum
5075  {
5076  value = sizeof(value_type) > 1
5077  };
5078 };
5079 
5080 template<typename IteratorType>
5081 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5082 {
5083  using iterator_type = IteratorType;
5084  using char_type = typename std::iterator_traits<iterator_type>::value_type;
5085  using base_adapter_type = iterator_input_adapter<iterator_type>;
5086  using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5087 
5088  static adapter_type create(IteratorType first, IteratorType last)
5089  {
5090  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5091  }
5092 };
5093 
5094 // General purpose iterator-based input
5095 template<typename IteratorType>
5096 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5097 {
5098  using factory_type = iterator_input_adapter_factory<IteratorType>;
5099  return factory_type::create(first, last);
5100 }
5101 
5102 // Convenience shorthand from container to iterator
5103 template<typename ContainerType>
5104 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5105 {
5106  // Enable ADL
5107  using std::begin;
5108  using std::end;
5109 
5110  return input_adapter(begin(container), end(container));
5111 }
5112 
5113 // Special cases with fast paths
5114 inline file_input_adapter input_adapter(std::FILE* file)
5115 {
5116  return file_input_adapter(file);
5117 }
5118 
5119 inline input_stream_adapter input_adapter(std::istream& stream)
5120 {
5121  return input_stream_adapter(stream);
5122 }
5123 
5124 inline input_stream_adapter input_adapter(std::istream&& stream)
5125 {
5126  return input_stream_adapter(stream);
5127 }
5128 
5129 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5130 
5131 // Null-delimited strings, and the like.
5132 template < typename CharT,
5133  typename std::enable_if <
5134  std::is_pointer<CharT>::value&&
5135  !std::is_array<CharT>::value&&
5136  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5137  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5138  int >::type = 0 >
5139 contiguous_bytes_input_adapter input_adapter(CharT b)
5140 {
5141  auto length = std::strlen(reinterpret_cast<const char*>(b));
5142  const auto* ptr = reinterpret_cast<const char*>(b);
5143  return input_adapter(ptr, ptr + length);
5144 }
5145 
5146 template<typename T, std::size_t N>
5147 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5148 {
5149  return input_adapter(array, array + N);
5150 }
5151 
5152 // This class only handles inputs of input_buffer_adapter type.
5153 // It's required so that expressions like {ptr, len} can be implicitely casted
5154 // to the correct adapter.
5155 class span_input_adapter
5156 {
5157  public:
5158  template < typename CharT,
5159  typename std::enable_if <
5160  std::is_pointer<CharT>::value&&
5161  std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5162  sizeof(typename std::remove_pointer<CharT>::type) == 1,
5163  int >::type = 0 >
5164  span_input_adapter(CharT b, std::size_t l)
5165  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5166 
5167  template<class IteratorType,
5168  typename std::enable_if<
5169  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5170  int>::type = 0>
5171  span_input_adapter(IteratorType first, IteratorType last)
5172  : ia(input_adapter(first, last)) {}
5173 
5174  contiguous_bytes_input_adapter&& get()
5175  {
5176  return std::move(ia);
5177  }
5178 
5179  private:
5180  contiguous_bytes_input_adapter ia;
5181 };
5182 } // namespace detail
5183 } // namespace nlohmann
5184 
5185 // #include <nlohmann/detail/input/json_sax.hpp>
5186 
5187 
5188 #include <cstddef>
5189 #include <string> // string
5190 #include <utility> // move
5191 #include <vector> // vector
5192 
5193 // #include <nlohmann/detail/exceptions.hpp>
5194 
5195 // #include <nlohmann/detail/macro_scope.hpp>
5196 
5197 
5198 namespace nlohmann
5199 {
5200 
5209 template<typename BasicJsonType>
5210 struct json_sax
5211 {
5212  using number_integer_t = typename BasicJsonType::number_integer_t;
5213  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5214  using number_float_t = typename BasicJsonType::number_float_t;
5215  using string_t = typename BasicJsonType::string_t;
5216  using binary_t = typename BasicJsonType::binary_t;
5217 
5222  virtual bool null() = 0;
5223 
5229  virtual bool boolean(bool val) = 0;
5230 
5236  virtual bool number_integer(number_integer_t val) = 0;
5237 
5243  virtual bool number_unsigned(number_unsigned_t val) = 0;
5244 
5251  virtual bool number_float(number_float_t val, const string_t& s) = 0;
5252 
5259  virtual bool string(string_t& val) = 0;
5260 
5267  virtual bool binary(binary_t& val) = 0;
5268 
5275  virtual bool start_object(std::size_t elements) = 0;
5276 
5283  virtual bool key(string_t& val) = 0;
5284 
5289  virtual bool end_object() = 0;
5290 
5297  virtual bool start_array(std::size_t elements) = 0;
5298 
5303  virtual bool end_array() = 0;
5304 
5312  virtual bool parse_error(std::size_t position,
5313  const std::string& last_token,
5314  const detail::exception& ex) = 0;
5315 
5316  virtual ~json_sax() = default;
5317 };
5318 
5319 
5320 namespace detail
5321 {
5335 template<typename BasicJsonType>
5336 class json_sax_dom_parser
5337 {
5338  public:
5339  using number_integer_t = typename BasicJsonType::number_integer_t;
5340  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5341  using number_float_t = typename BasicJsonType::number_float_t;
5342  using string_t = typename BasicJsonType::string_t;
5343  using binary_t = typename BasicJsonType::binary_t;
5344 
5350  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5351  : root(r), allow_exceptions(allow_exceptions_)
5352  {}
5353 
5354  // make class move-only
5355  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5356  json_sax_dom_parser(json_sax_dom_parser&&) = default;
5357  json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5358  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5359  ~json_sax_dom_parser() = default;
5360 
5361  bool null()
5362  {
5363  handle_value(nullptr);
5364  return true;
5365  }
5366 
5367  bool boolean(bool val)
5368  {
5369  handle_value(val);
5370  return true;
5371  }
5372 
5373  bool number_integer(number_integer_t val)
5374  {
5375  handle_value(val);
5376  return true;
5377  }
5378 
5379  bool number_unsigned(number_unsigned_t val)
5380  {
5381  handle_value(val);
5382  return true;
5383  }
5384 
5385  bool number_float(number_float_t val, const string_t& /*unused*/)
5386  {
5387  handle_value(val);
5388  return true;
5389  }
5390 
5391  bool string(string_t& val)
5392  {
5393  handle_value(val);
5394  return true;
5395  }
5396 
5397  bool binary(binary_t& val)
5398  {
5399  handle_value(std::move(val));
5400  return true;
5401  }
5402 
5403  bool start_object(std::size_t len)
5404  {
5405  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5406 
5407  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5408  {
5409  JSON_THROW(out_of_range::create(408,
5410  "excessive object size: " + std::to_string(len)));
5411  }
5412 
5413  return true;
5414  }
5415 
5416  bool key(string_t& val)
5417  {
5418  // add null at given key and store the reference for later
5419  object_element = &(ref_stack.back()->m_value.object->operator[](val));
5420  return true;
5421  }
5422 
5423  bool end_object()
5424  {
5425  ref_stack.pop_back();
5426  return true;
5427  }
5428 
5429  bool start_array(std::size_t len)
5430  {
5431  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5432 
5433  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5434  {
5435  JSON_THROW(out_of_range::create(408,
5436  "excessive array size: " + std::to_string(len)));
5437  }
5438 
5439  return true;
5440  }
5441 
5442  bool end_array()
5443  {
5444  ref_stack.pop_back();
5445  return true;
5446  }
5447 
5448  template<class Exception>
5449  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5450  const Exception& ex)
5451  {
5452  errored = true;
5453  static_cast<void>(ex);
5454  if (allow_exceptions)
5455  {
5456  JSON_THROW(ex);
5457  }
5458  return false;
5459  }
5460 
5461  constexpr bool is_errored() const
5462  {
5463  return errored;
5464  }
5465 
5466  private:
5473  template<typename Value>
5474 
5475  BasicJsonType* handle_value(Value&& v)
5476  {
5477  if (ref_stack.empty())
5478  {
5479  root = BasicJsonType(std::forward<Value>(v));
5480  return &root;
5481  }
5482 
5483  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5484 
5485  if (ref_stack.back()->is_array())
5486  {
5487  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5488  return &(ref_stack.back()->m_value.array->back());
5489  }
5490 
5491  JSON_ASSERT(ref_stack.back()->is_object());
5492  JSON_ASSERT(object_element);
5493  *object_element = BasicJsonType(std::forward<Value>(v));
5494  return object_element;
5495  }
5496 
5498  BasicJsonType& root;
5500  std::vector<BasicJsonType*> ref_stack {};
5502  BasicJsonType* object_element = nullptr;
5504  bool errored = false;
5506  const bool allow_exceptions = true;
5507 };
5508 
5509 template<typename BasicJsonType>
5510 class json_sax_dom_callback_parser
5511 {
5512  public:
5513  using number_integer_t = typename BasicJsonType::number_integer_t;
5514  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5515  using number_float_t = typename BasicJsonType::number_float_t;
5516  using string_t = typename BasicJsonType::string_t;
5517  using binary_t = typename BasicJsonType::binary_t;
5518  using parser_callback_t = typename BasicJsonType::parser_callback_t;
5519  using parse_event_t = typename BasicJsonType::parse_event_t;
5520 
5521  json_sax_dom_callback_parser(BasicJsonType& r,
5522  const parser_callback_t cb,
5523  const bool allow_exceptions_ = true)
5524  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5525  {
5526  keep_stack.push_back(true);
5527  }
5528 
5529  // make class move-only
5530  json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5531  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5532  json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5533  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5534  ~json_sax_dom_callback_parser() = default;
5535 
5536  bool null()
5537  {
5538  handle_value(nullptr);
5539  return true;
5540  }
5541 
5542  bool boolean(bool val)
5543  {
5544  handle_value(val);
5545  return true;
5546  }
5547 
5548  bool number_integer(number_integer_t val)
5549  {
5550  handle_value(val);
5551  return true;
5552  }
5553 
5554  bool number_unsigned(number_unsigned_t val)
5555  {
5556  handle_value(val);
5557  return true;
5558  }
5559 
5560  bool number_float(number_float_t val, const string_t& /*unused*/)
5561  {
5562  handle_value(val);
5563  return true;
5564  }
5565 
5566  bool string(string_t& val)
5567  {
5568  handle_value(val);
5569  return true;
5570  }
5571 
5572  bool binary(binary_t& val)
5573  {
5574  handle_value(std::move(val));
5575  return true;
5576  }
5577 
5578  bool start_object(std::size_t len)
5579  {
5580  // check callback for object start
5581  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5582  keep_stack.push_back(keep);
5583 
5584  auto val = handle_value(BasicJsonType::value_t::object, true);
5585  ref_stack.push_back(val.second);
5586 
5587  // check object limit
5588  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5589  {
5590  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5591  }
5592 
5593  return true;
5594  }
5595 
5596  bool key(string_t& val)
5597  {
5598  BasicJsonType k = BasicJsonType(val);
5599 
5600  // check callback for key
5601  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5602  key_keep_stack.push_back(keep);
5603 
5604  // add discarded value at given key and store the reference for later
5605  if (keep && ref_stack.back())
5606  {
5607  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5608  }
5609 
5610  return true;
5611  }
5612 
5613  bool end_object()
5614  {
5615  if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5616  {
5617  // discard object
5618  *ref_stack.back() = discarded;
5619  }
5620 
5621  JSON_ASSERT(!ref_stack.empty());
5622  JSON_ASSERT(!keep_stack.empty());
5623  ref_stack.pop_back();
5624  keep_stack.pop_back();
5625 
5626  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5627  {
5628  // remove discarded value
5629  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5630  {
5631  if (it->is_discarded())
5632  {
5633  ref_stack.back()->erase(it);
5634  break;
5635  }
5636  }
5637  }
5638 
5639  return true;
5640  }
5641 
5642  bool start_array(std::size_t len)
5643  {
5644  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5645  keep_stack.push_back(keep);
5646 
5647  auto val = handle_value(BasicJsonType::value_t::array, true);
5648  ref_stack.push_back(val.second);
5649 
5650  // check array limit
5651  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5652  {
5653  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5654  }
5655 
5656  return true;
5657  }
5658 
5659  bool end_array()
5660  {
5661  bool keep = true;
5662 
5663  if (ref_stack.back())
5664  {
5665  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5666  if (!keep)
5667  {
5668  // discard array
5669  *ref_stack.back() = discarded;
5670  }
5671  }
5672 
5673  JSON_ASSERT(!ref_stack.empty());
5674  JSON_ASSERT(!keep_stack.empty());
5675  ref_stack.pop_back();
5676  keep_stack.pop_back();
5677 
5678  // remove discarded value
5679  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5680  {
5681  ref_stack.back()->m_value.array->pop_back();
5682  }
5683 
5684  return true;
5685  }
5686 
5687  template<class Exception>
5688  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5689  const Exception& ex)
5690  {
5691  errored = true;
5692  static_cast<void>(ex);
5693  if (allow_exceptions)
5694  {
5695  JSON_THROW(ex);
5696  }
5697  return false;
5698  }
5699 
5700  constexpr bool is_errored() const
5701  {
5702  return errored;
5703  }
5704 
5705  private:
5721  template<typename Value>
5722  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5723  {
5724  JSON_ASSERT(!keep_stack.empty());
5725 
5726  // do not handle this value if we know it would be added to a discarded
5727  // container
5728  if (!keep_stack.back())
5729  {
5730  return {false, nullptr};
5731  }
5732 
5733  // create value
5734  auto value = BasicJsonType(std::forward<Value>(v));
5735 
5736  // check callback
5737  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5738 
5739  // do not handle this value if we just learnt it shall be discarded
5740  if (!keep)
5741  {
5742  return {false, nullptr};
5743  }
5744 
5745  if (ref_stack.empty())
5746  {
5747  root = std::move(value);
5748  return {true, &root};
5749  }
5750 
5751  // skip this value if we already decided to skip the parent
5752  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5753  if (!ref_stack.back())
5754  {
5755  return {false, nullptr};
5756  }
5757 
5758  // we now only expect arrays and objects
5759  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5760 
5761  // array
5762  if (ref_stack.back()->is_array())
5763  {
5764  ref_stack.back()->m_value.array->push_back(std::move(value));
5765  return {true, &(ref_stack.back()->m_value.array->back())};
5766  }
5767 
5768  // object
5769  JSON_ASSERT(ref_stack.back()->is_object());
5770  // check if we should store an element for the current key
5771  JSON_ASSERT(!key_keep_stack.empty());
5772  const bool store_element = key_keep_stack.back();
5773  key_keep_stack.pop_back();
5774 
5775  if (!store_element)
5776  {
5777  return {false, nullptr};
5778  }
5779 
5780  JSON_ASSERT(object_element);
5781  *object_element = std::move(value);
5782  return {true, object_element};
5783  }
5784 
5786  BasicJsonType& root;
5788  std::vector<BasicJsonType*> ref_stack {};
5790  std::vector<bool> keep_stack {};
5792  std::vector<bool> key_keep_stack {};
5794  BasicJsonType* object_element = nullptr;
5796  bool errored = false;
5798  const parser_callback_t callback = nullptr;
5800  const bool allow_exceptions = true;
5802  BasicJsonType discarded = BasicJsonType::value_t::discarded;
5803 };
5804 
5805 template<typename BasicJsonType>
5806 class json_sax_acceptor
5807 {
5808  public:
5809  using number_integer_t = typename BasicJsonType::number_integer_t;
5810  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5811  using number_float_t = typename BasicJsonType::number_float_t;
5812  using string_t = typename BasicJsonType::string_t;
5813  using binary_t = typename BasicJsonType::binary_t;
5814 
5815  bool null()
5816  {
5817  return true;
5818  }
5819 
5820  bool boolean(bool /*unused*/)
5821  {
5822  return true;
5823  }
5824 
5825  bool number_integer(number_integer_t /*unused*/)
5826  {
5827  return true;
5828  }
5829 
5830  bool number_unsigned(number_unsigned_t /*unused*/)
5831  {
5832  return true;
5833  }
5834 
5835  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5836  {
5837  return true;
5838  }
5839 
5840  bool string(string_t& /*unused*/)
5841  {
5842  return true;
5843  }
5844 
5845  bool binary(binary_t& /*unused*/)
5846  {
5847  return true;
5848  }
5849 
5850  bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5851  {
5852  return true;
5853  }
5854 
5855  bool key(string_t& /*unused*/)
5856  {
5857  return true;
5858  }
5859 
5860  bool end_object()
5861  {
5862  return true;
5863  }
5864 
5865  bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5866  {
5867  return true;
5868  }
5869 
5870  bool end_array()
5871  {
5872  return true;
5873  }
5874 
5875  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5876  {
5877  return false;
5878  }
5879 };
5880 } // namespace detail
5881 
5882 } // namespace nlohmann
5883 
5884 // #include <nlohmann/detail/input/lexer.hpp>
5885 
5886 
5887 #include <array> // array
5888 #include <clocale> // localeconv
5889 #include <cstddef> // size_t
5890 #include <cstdio> // snprintf
5891 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5892 #include <initializer_list> // initializer_list
5893 #include <string> // char_traits, string
5894 #include <utility> // move
5895 #include <vector> // vector
5896 
5897 // #include <nlohmann/detail/input/input_adapters.hpp>
5898 
5899 // #include <nlohmann/detail/input/position_t.hpp>
5900 
5901 // #include <nlohmann/detail/macro_scope.hpp>
5902 
5903 
5904 namespace nlohmann
5905 {
5906 namespace detail
5907 {
5909 // lexer //
5911 
5912 template<typename BasicJsonType>
5913 class lexer_base
5914 {
5915  public:
5917  enum class token_type
5918  {
5919  uninitialized,
5920  literal_true,
5921  literal_false,
5922  literal_null,
5923  value_string,
5924  value_unsigned,
5925  value_integer,
5926  value_float,
5927  begin_array,
5928  begin_object,
5929  end_array,
5930  end_object,
5931  name_separator,
5932  value_separator,
5933  parse_error,
5934  end_of_input,
5935  literal_or_value
5936  };
5937 
5939 
5940  JSON_HEDLEY_CONST
5941  static const char* token_type_name(const token_type t) noexcept
5942  {
5943  switch (t)
5944  {
5945  case token_type::uninitialized:
5946  return "<uninitialized>";
5947  case token_type::literal_true:
5948  return "true literal";
5949  case token_type::literal_false:
5950  return "false literal";
5951  case token_type::literal_null:
5952  return "null literal";
5953  case token_type::value_string:
5954  return "string literal";
5955  case token_type::value_unsigned:
5956  case token_type::value_integer:
5957  case token_type::value_float:
5958  return "number literal";
5959  case token_type::begin_array:
5960  return "'['";
5961  case token_type::begin_object:
5962  return "'{'";
5963  case token_type::end_array:
5964  return "']'";
5965  case token_type::end_object:
5966  return "'}'";
5967  case token_type::name_separator:
5968  return "':'";
5969  case token_type::value_separator:
5970  return "','";
5971  case token_type::parse_error:
5972  return "<parse error>";
5973  case token_type::end_of_input:
5974  return "end of input";
5975  case token_type::literal_or_value:
5976  return "'[', '{', or a literal";
5977  // LCOV_EXCL_START
5978  default: // catch non-enum values
5979  return "unknown token";
5980  // LCOV_EXCL_STOP
5981  }
5982  }
5983 };
5989 template<typename BasicJsonType, typename InputAdapterType>
5990 class lexer : public lexer_base<BasicJsonType>
5991 {
5992  using number_integer_t = typename BasicJsonType::number_integer_t;
5993  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5994  using number_float_t = typename BasicJsonType::number_float_t;
5995  using string_t = typename BasicJsonType::string_t;
5996  using char_type = typename InputAdapterType::char_type;
5997  using char_int_type = typename std::char_traits<char_type>::int_type;
5998 
5999  public:
6000  using token_type = typename lexer_base<BasicJsonType>::token_type;
6001 
6002  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
6003  : ia(std::move(adapter))
6004  , ignore_comments(ignore_comments_)
6005  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6006  {}
6007 
6008  // delete because of pointer members
6009  lexer(const lexer&) = delete;
6010  lexer(lexer&&) = default;
6011  lexer& operator=(lexer&) = delete;
6012  lexer& operator=(lexer&&) = default;
6013  ~lexer() = default;
6014 
6015  private:
6017  // locales
6019 
6021  JSON_HEDLEY_PURE
6022  static char get_decimal_point() noexcept
6023  {
6024  const auto* loc = localeconv();
6025  JSON_ASSERT(loc != nullptr);
6026  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6027  }
6028 
6030  // scan functions
6032 
6048  int get_codepoint()
6049  {
6050  // this function only makes sense after reading `\u`
6051  JSON_ASSERT(current == 'u');
6052  int codepoint = 0;
6053 
6054  const auto factors = { 12u, 8u, 4u, 0u };
6055  for (const auto factor : factors)
6056  {
6057  get();
6058 
6059  if (current >= '0' && current <= '9')
6060  {
6061  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6062  }
6063  else if (current >= 'A' && current <= 'F')
6064  {
6065  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6066  }
6067  else if (current >= 'a' && current <= 'f')
6068  {
6069  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6070  }
6071  else
6072  {
6073  return -1;
6074  }
6075  }
6076 
6077  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6078  return codepoint;
6079  }
6080 
6096  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6097  {
6098  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6099  add(current);
6100 
6101  for (auto range = ranges.begin(); range != ranges.end(); ++range)
6102  {
6103  get();
6104  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6105  {
6106  add(current);
6107  }
6108  else
6109  {
6110  error_message = "invalid string: ill-formed UTF-8 byte";
6111  return false;
6112  }
6113  }
6114 
6115  return true;
6116  }
6117 
6133  token_type scan_string()
6134  {
6135  // reset token_buffer (ignore opening quote)
6136  reset();
6137 
6138  // we entered the function by reading an open quote
6139  JSON_ASSERT(current == '\"');
6140 
6141  while (true)
6142  {
6143  // get next character
6144  switch (get())
6145  {
6146  // end of file while parsing string
6147  case std::char_traits<char_type>::eof():
6148  {
6149  error_message = "invalid string: missing closing quote";
6150  return token_type::parse_error;
6151  }
6152 
6153  // closing quote
6154  case '\"':
6155  {
6156  return token_type::value_string;
6157  }
6158 
6159  // escapes
6160  case '\\':
6161  {
6162  switch (get())
6163  {
6164  // quotation mark
6165  case '\"':
6166  add('\"');
6167  break;
6168  // reverse solidus
6169  case '\\':
6170  add('\\');
6171  break;
6172  // solidus
6173  case '/':
6174  add('/');
6175  break;
6176  // backspace
6177  case 'b':
6178  add('\b');
6179  break;
6180  // form feed
6181  case 'f':
6182  add('\f');
6183  break;
6184  // line feed
6185  case 'n':
6186  add('\n');
6187  break;
6188  // carriage return
6189  case 'r':
6190  add('\r');
6191  break;
6192  // tab
6193  case 't':
6194  add('\t');
6195  break;
6196 
6197  // unicode escapes
6198  case 'u':
6199  {
6200  const int codepoint1 = get_codepoint();
6201  int codepoint = codepoint1; // start with codepoint1
6202 
6203  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6204  {
6205  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6206  return token_type::parse_error;
6207  }
6208 
6209  // check if code point is a high surrogate
6210  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6211  {
6212  // expect next \uxxxx entry
6213  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6214  {
6215  const int codepoint2 = get_codepoint();
6216 
6217  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6218  {
6219  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6220  return token_type::parse_error;
6221  }
6222 
6223  // check if codepoint2 is a low surrogate
6224  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6225  {
6226  // overwrite codepoint
6227  codepoint = static_cast<int>(
6228  // high surrogate occupies the most significant 22 bits
6229  (static_cast<unsigned int>(codepoint1) << 10u)
6230  // low surrogate occupies the least significant 15 bits
6231  + static_cast<unsigned int>(codepoint2)
6232  // there is still the 0xD800, 0xDC00 and 0x10000 noise
6233  // in the result so we have to subtract with:
6234  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6235  - 0x35FDC00u);
6236  }
6237  else
6238  {
6239  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6240  return token_type::parse_error;
6241  }
6242  }
6243  else
6244  {
6245  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6246  return token_type::parse_error;
6247  }
6248  }
6249  else
6250  {
6251  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6252  {
6253  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6254  return token_type::parse_error;
6255  }
6256  }
6257 
6258  // result of the above calculation yields a proper codepoint
6259  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6260 
6261  // translate codepoint into bytes
6262  if (codepoint < 0x80)
6263  {
6264  // 1-byte characters: 0xxxxxxx (ASCII)
6265  add(static_cast<char_int_type>(codepoint));
6266  }
6267  else if (codepoint <= 0x7FF)
6268  {
6269  // 2-byte characters: 110xxxxx 10xxxxxx
6270  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6271  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6272  }
6273  else if (codepoint <= 0xFFFF)
6274  {
6275  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6276  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6277  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6278  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6279  }
6280  else
6281  {
6282  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6283  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6284  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6285  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6286  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6287  }
6288 
6289  break;
6290  }
6291 
6292  // other characters after escape
6293  default:
6294  error_message = "invalid string: forbidden character after backslash";
6295  return token_type::parse_error;
6296  }
6297 
6298  break;
6299  }
6300 
6301  // invalid control characters
6302  case 0x00:
6303  {
6304  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6305  return token_type::parse_error;
6306  }
6307 
6308  case 0x01:
6309  {
6310  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6311  return token_type::parse_error;
6312  }
6313 
6314  case 0x02:
6315  {
6316  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6317  return token_type::parse_error;
6318  }
6319 
6320  case 0x03:
6321  {
6322  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6323  return token_type::parse_error;
6324  }
6325 
6326  case 0x04:
6327  {
6328  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6329  return token_type::parse_error;
6330  }
6331 
6332  case 0x05:
6333  {
6334  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6335  return token_type::parse_error;
6336  }
6337 
6338  case 0x06:
6339  {
6340  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6341  return token_type::parse_error;
6342  }
6343 
6344  case 0x07:
6345  {
6346  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6347  return token_type::parse_error;
6348  }
6349 
6350  case 0x08:
6351  {
6352  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6353  return token_type::parse_error;
6354  }
6355 
6356  case 0x09:
6357  {
6358  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6359  return token_type::parse_error;
6360  }
6361 
6362  case 0x0A:
6363  {
6364  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6365  return token_type::parse_error;
6366  }
6367 
6368  case 0x0B:
6369  {
6370  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6371  return token_type::parse_error;
6372  }
6373 
6374  case 0x0C:
6375  {
6376  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6377  return token_type::parse_error;
6378  }
6379 
6380  case 0x0D:
6381  {
6382  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6383  return token_type::parse_error;
6384  }
6385 
6386  case 0x0E:
6387  {
6388  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6389  return token_type::parse_error;
6390  }
6391 
6392  case 0x0F:
6393  {
6394  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6395  return token_type::parse_error;
6396  }
6397 
6398  case 0x10:
6399  {
6400  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6401  return token_type::parse_error;
6402  }
6403 
6404  case 0x11:
6405  {
6406  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6407  return token_type::parse_error;
6408  }
6409 
6410  case 0x12:
6411  {
6412  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6413  return token_type::parse_error;
6414  }
6415 
6416  case 0x13:
6417  {
6418  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6419  return token_type::parse_error;
6420  }
6421 
6422  case 0x14:
6423  {
6424  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6425  return token_type::parse_error;
6426  }
6427 
6428  case 0x15:
6429  {
6430  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6431  return token_type::parse_error;
6432  }
6433 
6434  case 0x16:
6435  {
6436  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6437  return token_type::parse_error;
6438  }
6439 
6440  case 0x17:
6441  {
6442  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6443  return token_type::parse_error;
6444  }
6445 
6446  case 0x18:
6447  {
6448  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6449  return token_type::parse_error;
6450  }
6451 
6452  case 0x19:
6453  {
6454  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6455  return token_type::parse_error;
6456  }
6457 
6458  case 0x1A:
6459  {
6460  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6461  return token_type::parse_error;
6462  }
6463 
6464  case 0x1B:
6465  {
6466  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6467  return token_type::parse_error;
6468  }
6469 
6470  case 0x1C:
6471  {
6472  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6473  return token_type::parse_error;
6474  }
6475 
6476  case 0x1D:
6477  {
6478  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6479  return token_type::parse_error;
6480  }
6481 
6482  case 0x1E:
6483  {
6484  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6485  return token_type::parse_error;
6486  }
6487 
6488  case 0x1F:
6489  {
6490  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6491  return token_type::parse_error;
6492  }
6493 
6494  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6495  case 0x20:
6496  case 0x21:
6497  case 0x23:
6498  case 0x24:
6499  case 0x25:
6500  case 0x26:
6501  case 0x27:
6502  case 0x28:
6503  case 0x29:
6504  case 0x2A:
6505  case 0x2B:
6506  case 0x2C:
6507  case 0x2D:
6508  case 0x2E:
6509  case 0x2F:
6510  case 0x30:
6511  case 0x31:
6512  case 0x32:
6513  case 0x33:
6514  case 0x34:
6515  case 0x35:
6516  case 0x36:
6517  case 0x37:
6518  case 0x38:
6519  case 0x39:
6520  case 0x3A:
6521  case 0x3B:
6522  case 0x3C:
6523  case 0x3D:
6524  case 0x3E:
6525  case 0x3F:
6526  case 0x40:
6527  case 0x41:
6528  case 0x42:
6529  case 0x43:
6530  case 0x44:
6531  case 0x45:
6532  case 0x46:
6533  case 0x47:
6534  case 0x48:
6535  case 0x49:
6536  case 0x4A:
6537  case 0x4B:
6538  case 0x4C:
6539  case 0x4D:
6540  case 0x4E:
6541  case 0x4F:
6542  case 0x50:
6543  case 0x51:
6544  case 0x52:
6545  case 0x53:
6546  case 0x54:
6547  case 0x55:
6548  case 0x56:
6549  case 0x57:
6550  case 0x58:
6551  case 0x59:
6552  case 0x5A:
6553  case 0x5B:
6554  case 0x5D:
6555  case 0x5E:
6556  case 0x5F:
6557  case 0x60:
6558  case 0x61:
6559  case 0x62:
6560  case 0x63:
6561  case 0x64:
6562  case 0x65:
6563  case 0x66:
6564  case 0x67:
6565  case 0x68:
6566  case 0x69:
6567  case 0x6A:
6568  case 0x6B:
6569  case 0x6C:
6570  case 0x6D:
6571  case 0x6E:
6572  case 0x6F:
6573  case 0x70:
6574  case 0x71:
6575  case 0x72:
6576  case 0x73:
6577  case 0x74:
6578  case 0x75:
6579  case 0x76:
6580  case 0x77:
6581  case 0x78:
6582  case 0x79:
6583  case 0x7A:
6584  case 0x7B:
6585  case 0x7C:
6586  case 0x7D:
6587  case 0x7E:
6588  case 0x7F:
6589  {
6590  add(current);
6591  break;
6592  }
6593 
6594  // U+0080..U+07FF: bytes C2..DF 80..BF
6595  case 0xC2:
6596  case 0xC3:
6597  case 0xC4:
6598  case 0xC5:
6599  case 0xC6:
6600  case 0xC7:
6601  case 0xC8:
6602  case 0xC9:
6603  case 0xCA:
6604  case 0xCB:
6605  case 0xCC:
6606  case 0xCD:
6607  case 0xCE:
6608  case 0xCF:
6609  case 0xD0:
6610  case 0xD1:
6611  case 0xD2:
6612  case 0xD3:
6613  case 0xD4:
6614  case 0xD5:
6615  case 0xD6:
6616  case 0xD7:
6617  case 0xD8:
6618  case 0xD9:
6619  case 0xDA:
6620  case 0xDB:
6621  case 0xDC:
6622  case 0xDD:
6623  case 0xDE:
6624  case 0xDF:
6625  {
6626  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6627  {
6628  return token_type::parse_error;
6629  }
6630  break;
6631  }
6632 
6633  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6634  case 0xE0:
6635  {
6636  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6637  {
6638  return token_type::parse_error;
6639  }
6640  break;
6641  }
6642 
6643  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6644  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6645  case 0xE1:
6646  case 0xE2:
6647  case 0xE3:
6648  case 0xE4:
6649  case 0xE5:
6650  case 0xE6:
6651  case 0xE7:
6652  case 0xE8:
6653  case 0xE9:
6654  case 0xEA:
6655  case 0xEB:
6656  case 0xEC:
6657  case 0xEE:
6658  case 0xEF:
6659  {
6660  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6661  {
6662  return token_type::parse_error;
6663  }
6664  break;
6665  }
6666 
6667  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6668  case 0xED:
6669  {
6670  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6671  {
6672  return token_type::parse_error;
6673  }
6674  break;
6675  }
6676 
6677  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6678  case 0xF0:
6679  {
6680  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6681  {
6682  return token_type::parse_error;
6683  }
6684  break;
6685  }
6686 
6687  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6688  case 0xF1:
6689  case 0xF2:
6690  case 0xF3:
6691  {
6692  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6693  {
6694  return token_type::parse_error;
6695  }
6696  break;
6697  }
6698 
6699  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6700  case 0xF4:
6701  {
6702  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6703  {
6704  return token_type::parse_error;
6705  }
6706  break;
6707  }
6708 
6709  // remaining bytes (80..C1 and F5..FF) are ill-formed
6710  default:
6711  {
6712  error_message = "invalid string: ill-formed UTF-8 byte";
6713  return token_type::parse_error;
6714  }
6715  }
6716  }
6717  }
6718 
6723  bool scan_comment()
6724  {
6725  switch (get())
6726  {
6727  // single-line comments skip input until a newline or EOF is read
6728  case '/':
6729  {
6730  while (true)
6731  {
6732  switch (get())
6733  {
6734  case '\n':
6735  case '\r':
6736  case std::char_traits<char_type>::eof():
6737  case '\0':
6738  return true;
6739 
6740  default:
6741  break;
6742  }
6743  }
6744  }
6745 
6746  // multi-line comments skip input until */ is read
6747  case '*':
6748  {
6749  while (true)
6750  {
6751  switch (get())
6752  {
6753  case std::char_traits<char_type>::eof():
6754  case '\0':
6755  {
6756  error_message = "invalid comment; missing closing '*/'";
6757  return false;
6758  }
6759 
6760  case '*':
6761  {
6762  switch (get())
6763  {
6764  case '/':
6765  return true;
6766 
6767  default:
6768  {
6769  unget();
6770  continue;
6771  }
6772  }
6773  }
6774 
6775  default:
6776  continue;
6777  }
6778  }
6779  }
6780 
6781  // unexpected character after reading '/'
6782  default:
6783  {
6784  error_message = "invalid comment; expecting '/' or '*' after '/'";
6785  return false;
6786  }
6787  }
6788  }
6789 
6790  JSON_HEDLEY_NON_NULL(2)
6791  static void strtof(float& f, const char* str, char** endptr) noexcept
6792  {
6793  f = std::strtof(str, endptr);
6794  }
6795 
6796  JSON_HEDLEY_NON_NULL(2)
6797  static void strtof(double& f, const char* str, char** endptr) noexcept
6798  {
6799  f = std::strtod(str, endptr);
6800  }
6801 
6802  JSON_HEDLEY_NON_NULL(2)
6803  static void strtof(long double& f, const char* str, char** endptr) noexcept
6804  {
6805  f = std::strtold(str, endptr);
6806  }
6807 
6848  token_type scan_number() // lgtm [cpp/use-of-goto]
6849  {
6850  // reset token_buffer to store the number's bytes
6851  reset();
6852 
6853  // the type of the parsed number; initially set to unsigned; will be
6854  // changed if minus sign, decimal point or exponent is read
6855  token_type number_type = token_type::value_unsigned;
6856 
6857  // state (init): we just found out we need to scan a number
6858  switch (current)
6859  {
6860  case '-':
6861  {
6862  add(current);
6863  goto scan_number_minus;
6864  }
6865 
6866  case '0':
6867  {
6868  add(current);
6869  goto scan_number_zero;
6870  }
6871 
6872  case '1':
6873  case '2':
6874  case '3':
6875  case '4':
6876  case '5':
6877  case '6':
6878  case '7':
6879  case '8':
6880  case '9':
6881  {
6882  add(current);
6883  goto scan_number_any1;
6884  }
6885 
6886  // all other characters are rejected outside scan_number()
6887  default: // LCOV_EXCL_LINE
6888  JSON_ASSERT(false); // LCOV_EXCL_LINE
6889  }
6890 
6891 scan_number_minus:
6892  // state: we just parsed a leading minus sign
6893  number_type = token_type::value_integer;
6894  switch (get())
6895  {
6896  case '0':
6897  {
6898  add(current);
6899  goto scan_number_zero;
6900  }
6901 
6902  case '1':
6903  case '2':
6904  case '3':
6905  case '4':
6906  case '5':
6907  case '6':
6908  case '7':
6909  case '8':
6910  case '9':
6911  {
6912  add(current);
6913  goto scan_number_any1;
6914  }
6915 
6916  default:
6917  {
6918  error_message = "invalid number; expected digit after '-'";
6919  return token_type::parse_error;
6920  }
6921  }
6922 
6923 scan_number_zero:
6924  // state: we just parse a zero (maybe with a leading minus sign)
6925  switch (get())
6926  {
6927  case '.':
6928  {
6929  add(decimal_point_char);
6930  goto scan_number_decimal1;
6931  }
6932 
6933  case 'e':
6934  case 'E':
6935  {
6936  add(current);
6937  goto scan_number_exponent;
6938  }
6939 
6940  default:
6941  goto scan_number_done;
6942  }
6943 
6944 scan_number_any1:
6945  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6946  switch (get())
6947  {
6948  case '0':
6949  case '1':
6950  case '2':
6951  case '3':
6952  case '4':
6953  case '5':
6954  case '6':
6955  case '7':
6956  case '8':
6957  case '9':
6958  {
6959  add(current);
6960  goto scan_number_any1;
6961  }
6962 
6963  case '.':
6964  {
6965  add(decimal_point_char);
6966  goto scan_number_decimal1;
6967  }
6968 
6969  case 'e':
6970  case 'E':
6971  {
6972  add(current);
6973  goto scan_number_exponent;
6974  }
6975 
6976  default:
6977  goto scan_number_done;
6978  }
6979 
6980 scan_number_decimal1:
6981  // state: we just parsed a decimal point
6982  number_type = token_type::value_float;
6983  switch (get())
6984  {
6985  case '0':
6986  case '1':
6987  case '2':
6988  case '3':
6989  case '4':
6990  case '5':
6991  case '6':
6992  case '7':
6993  case '8':
6994  case '9':
6995  {
6996  add(current);
6997  goto scan_number_decimal2;
6998  }
6999 
7000  default:
7001  {
7002  error_message = "invalid number; expected digit after '.'";
7003  return token_type::parse_error;
7004  }
7005  }
7006 
7007 scan_number_decimal2:
7008  // we just parsed at least one number after a decimal point
7009  switch (get())
7010  {
7011  case '0':
7012  case '1':
7013  case '2':
7014  case '3':
7015  case '4':
7016  case '5':
7017  case '6':
7018  case '7':
7019  case '8':
7020  case '9':
7021  {
7022  add(current);
7023  goto scan_number_decimal2;
7024  }
7025 
7026  case 'e':
7027  case 'E':
7028  {
7029  add(current);
7030  goto scan_number_exponent;
7031  }
7032 
7033  default:
7034  goto scan_number_done;
7035  }
7036 
7037 scan_number_exponent:
7038  // we just parsed an exponent
7039  number_type = token_type::value_float;
7040  switch (get())
7041  {
7042  case '+':
7043  case '-':
7044  {
7045  add(current);
7046  goto scan_number_sign;
7047  }
7048 
7049  case '0':
7050  case '1':
7051  case '2':
7052  case '3':
7053  case '4':
7054  case '5':
7055  case '6':
7056  case '7':
7057  case '8':
7058  case '9':
7059  {
7060  add(current);
7061  goto scan_number_any2;
7062  }
7063 
7064  default:
7065  {
7066  error_message =
7067  "invalid number; expected '+', '-', or digit after exponent";
7068  return token_type::parse_error;
7069  }
7070  }
7071 
7072 scan_number_sign:
7073  // we just parsed an exponent sign
7074  switch (get())
7075  {
7076  case '0':
7077  case '1':
7078  case '2':
7079  case '3':
7080  case '4':
7081  case '5':
7082  case '6':
7083  case '7':
7084  case '8':
7085  case '9':
7086  {
7087  add(current);
7088  goto scan_number_any2;
7089  }
7090 
7091  default:
7092  {
7093  error_message = "invalid number; expected digit after exponent sign";
7094  return token_type::parse_error;
7095  }
7096  }
7097 
7098 scan_number_any2:
7099  // we just parsed a number after the exponent or exponent sign
7100  switch (get())
7101  {
7102  case '0':
7103  case '1':
7104  case '2':
7105  case '3':
7106  case '4':
7107  case '5':
7108  case '6':
7109  case '7':
7110  case '8':
7111  case '9':
7112  {
7113  add(current);
7114  goto scan_number_any2;
7115  }
7116 
7117  default:
7118  goto scan_number_done;
7119  }
7120 
7121 scan_number_done:
7122  // unget the character after the number (we only read it to know that
7123  // we are done scanning a number)
7124  unget();
7125 
7126  char* endptr = nullptr;
7127  errno = 0;
7128 
7129  // try to parse integers first and fall back to floats
7130  if (number_type == token_type::value_unsigned)
7131  {
7132  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7133 
7134  // we checked the number format before
7135  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7136 
7137  if (errno == 0)
7138  {
7139  value_unsigned = static_cast<number_unsigned_t>(x);
7140  if (value_unsigned == x)
7141  {
7142  return token_type::value_unsigned;
7143  }
7144  }
7145  }
7146  else if (number_type == token_type::value_integer)
7147  {
7148  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7149 
7150  // we checked the number format before
7151  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7152 
7153  if (errno == 0)
7154  {
7155  value_integer = static_cast<number_integer_t>(x);
7156  if (value_integer == x)
7157  {
7158  return token_type::value_integer;
7159  }
7160  }
7161  }
7162 
7163  // this code is reached if we parse a floating-point number or if an
7164  // integer conversion above failed
7165  strtof(value_float, token_buffer.data(), &endptr);
7166 
7167  // we checked the number format before
7168  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7169 
7170  return token_type::value_float;
7171  }
7172 
7178  JSON_HEDLEY_NON_NULL(2)
7179  token_type scan_literal(const char_type* literal_text, const std::size_t length,
7180  token_type return_type)
7181  {
7182  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7183  for (std::size_t i = 1; i < length; ++i)
7184  {
7185  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7186  {
7187  error_message = "invalid literal";
7188  return token_type::parse_error;
7189  }
7190  }
7191  return return_type;
7192  }
7193 
7195  // input management
7197 
7199  void reset() noexcept
7200  {
7201  token_buffer.clear();
7202  token_string.clear();
7203  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7204  }
7205 
7206  /*
7207  @brief get next character from the input
7208 
7209  This function provides the interface to the used input adapter. It does
7210  not throw in case the input reached EOF, but returns a
7211  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7212  for use in error messages.
7213 
7214  @return character read from the input
7215  */
7216  char_int_type get()
7217  {
7218  ++position.chars_read_total;
7219  ++position.chars_read_current_line;
7220 
7221  if (next_unget)
7222  {
7223  // just reset the next_unget variable and work with current
7224  next_unget = false;
7225  }
7226  else
7227  {
7228  current = ia.get_character();
7229  }
7230 
7231  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7232  {
7233  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7234  }
7235 
7236  if (current == '\n')
7237  {
7238  ++position.lines_read;
7239  position.chars_read_current_line = 0;
7240  }
7241 
7242  return current;
7243  }
7244 
7253  void unget()
7254  {
7255  next_unget = true;
7256 
7257  --position.chars_read_total;
7258 
7259  // in case we "unget" a newline, we have to also decrement the lines_read
7260  if (position.chars_read_current_line == 0)
7261  {
7262  if (position.lines_read > 0)
7263  {
7264  --position.lines_read;
7265  }
7266  }
7267  else
7268  {
7269  --position.chars_read_current_line;
7270  }
7271 
7272  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7273  {
7274  JSON_ASSERT(!token_string.empty());
7275  token_string.pop_back();
7276  }
7277  }
7278 
7280  void add(char_int_type c)
7281  {
7282  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7283  }
7284 
7285  public:
7287  // value getters
7289 
7291  constexpr number_integer_t get_number_integer() const noexcept
7292  {
7293  return value_integer;
7294  }
7295 
7297  constexpr number_unsigned_t get_number_unsigned() const noexcept
7298  {
7299  return value_unsigned;
7300  }
7301 
7303  constexpr number_float_t get_number_float() const noexcept
7304  {
7305  return value_float;
7306  }
7307 
7309  string_t& get_string()
7310  {
7311  return token_buffer;
7312  }
7313 
7315  // diagnostics
7317 
7319  constexpr position_t get_position() const noexcept
7320  {
7321  return position;
7322  }
7323 
7327  std::string get_token_string() const
7328  {
7329  // escape control characters
7330  std::string result;
7331  for (const auto c : token_string)
7332  {
7333  if (static_cast<unsigned char>(c) <= '\x1F')
7334  {
7335  // escape control characters
7336  std::array<char, 9> cs{{}};
7337  (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7338  result += cs.data();
7339  }
7340  else
7341  {
7342  // add character as is
7343  result.push_back(static_cast<std::string::value_type>(c));
7344  }
7345  }
7346 
7347  return result;
7348  }
7349 
7351 
7352  constexpr const char* get_error_message() const noexcept
7353  {
7354  return error_message;
7355  }
7356 
7358  // actual scanner
7360 
7365  bool skip_bom()
7366  {
7367  if (get() == 0xEF)
7368  {
7369  // check if we completely parse the BOM
7370  return get() == 0xBB && get() == 0xBF;
7371  }
7372 
7373  // the first character is not the beginning of the BOM; unget it to
7374  // process is later
7375  unget();
7376  return true;
7377  }
7378 
7379  void skip_whitespace()
7380  {
7381  do
7382  {
7383  get();
7384  }
7385  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7386  }
7387 
7388  token_type scan()
7389  {
7390  // initially, skip the BOM
7391  if (position.chars_read_total == 0 && !skip_bom())
7392  {
7393  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7394  return token_type::parse_error;
7395  }
7396 
7397  // read next character and ignore whitespace
7398  skip_whitespace();
7399 
7400  // ignore comments
7401  while (ignore_comments && current == '/')
7402  {
7403  if (!scan_comment())
7404  {
7405  return token_type::parse_error;
7406  }
7407 
7408  // skip following whitespace
7409  skip_whitespace();
7410  }
7411 
7412  switch (current)
7413  {
7414  // structural characters
7415  case '[':
7416  return token_type::begin_array;
7417  case ']':
7418  return token_type::end_array;
7419  case '{':
7420  return token_type::begin_object;
7421  case '}':
7422  return token_type::end_object;
7423  case ':':
7424  return token_type::name_separator;
7425  case ',':
7426  return token_type::value_separator;
7427 
7428  // literals
7429  case 't':
7430  {
7431  std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7432  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7433  }
7434  case 'f':
7435  {
7436  std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7437  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7438  }
7439  case 'n':
7440  {
7441  std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7442  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7443  }
7444 
7445  // string
7446  case '\"':
7447  return scan_string();
7448 
7449  // number
7450  case '-':
7451  case '0':
7452  case '1':
7453  case '2':
7454  case '3':
7455  case '4':
7456  case '5':
7457  case '6':
7458  case '7':
7459  case '8':
7460  case '9':
7461  return scan_number();
7462 
7463  // end of input (the null byte is needed when parsing from
7464  // string literals)
7465  case '\0':
7466  case std::char_traits<char_type>::eof():
7467  return token_type::end_of_input;
7468 
7469  // error
7470  default:
7471  error_message = "invalid literal";
7472  return token_type::parse_error;
7473  }
7474  }
7475 
7476  private:
7478  InputAdapterType ia;
7479 
7481  const bool ignore_comments = false;
7482 
7484  char_int_type current = std::char_traits<char_type>::eof();
7485 
7487  bool next_unget = false;
7488 
7490  position_t position {};
7491 
7493  std::vector<char_type> token_string {};
7494 
7496  string_t token_buffer {};
7497 
7499  const char* error_message = "";
7500 
7501  // number values
7502  number_integer_t value_integer = 0;
7503  number_unsigned_t value_unsigned = 0;
7504  number_float_t value_float = 0;
7505 
7507  const char_int_type decimal_point_char = '.';
7508 };
7509 } // namespace detail
7510 } // namespace nlohmann
7511 
7512 // #include <nlohmann/detail/macro_scope.hpp>
7513 
7514 // #include <nlohmann/detail/meta/is_sax.hpp>
7515 
7516 
7517 #include <cstdint> // size_t
7518 #include <utility> // declval
7519 #include <string> // string
7520 
7521 // #include <nlohmann/detail/meta/detected.hpp>
7522 
7523 // #include <nlohmann/detail/meta/type_traits.hpp>
7524 
7525 
7526 namespace nlohmann
7527 {
7528 namespace detail
7529 {
7530 template<typename T>
7531 using null_function_t = decltype(std::declval<T&>().null());
7532 
7533 template<typename T>
7534 using boolean_function_t =
7535  decltype(std::declval<T&>().boolean(std::declval<bool>()));
7536 
7537 template<typename T, typename Integer>
7538 using number_integer_function_t =
7539  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7540 
7541 template<typename T, typename Unsigned>
7542 using number_unsigned_function_t =
7543  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7544 
7545 template<typename T, typename Float, typename String>
7546 using number_float_function_t = decltype(std::declval<T&>().number_float(
7547  std::declval<Float>(), std::declval<const String&>()));
7548 
7549 template<typename T, typename String>
7550 using string_function_t =
7551  decltype(std::declval<T&>().string(std::declval<String&>()));
7552 
7553 template<typename T, typename Binary>
7554 using binary_function_t =
7555  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7556 
7557 template<typename T>
7558 using start_object_function_t =
7559  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7560 
7561 template<typename T, typename String>
7562 using key_function_t =
7563  decltype(std::declval<T&>().key(std::declval<String&>()));
7564 
7565 template<typename T>
7566 using end_object_function_t = decltype(std::declval<T&>().end_object());
7567 
7568 template<typename T>
7569 using start_array_function_t =
7570  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7571 
7572 template<typename T>
7573 using end_array_function_t = decltype(std::declval<T&>().end_array());
7574 
7575 template<typename T, typename Exception>
7576 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7577  std::declval<std::size_t>(), std::declval<const std::string&>(),
7578  std::declval<const Exception&>()));
7579 
7580 template<typename SAX, typename BasicJsonType>
7581 struct is_sax
7582 {
7583  private:
7584  static_assert(is_basic_json<BasicJsonType>::value,
7585  "BasicJsonType must be of type basic_json<...>");
7586 
7587  using number_integer_t = typename BasicJsonType::number_integer_t;
7588  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7589  using number_float_t = typename BasicJsonType::number_float_t;
7590  using string_t = typename BasicJsonType::string_t;
7591  using binary_t = typename BasicJsonType::binary_t;
7592  using exception_t = typename BasicJsonType::exception;
7593 
7594  public:
7595  static constexpr bool value =
7596  is_detected_exact<bool, null_function_t, SAX>::value &&
7597  is_detected_exact<bool, boolean_function_t, SAX>::value &&
7598  is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
7599  is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
7600  is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
7601  is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
7602  is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
7603  is_detected_exact<bool, start_object_function_t, SAX>::value &&
7604  is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
7605  is_detected_exact<bool, end_object_function_t, SAX>::value &&
7606  is_detected_exact<bool, start_array_function_t, SAX>::value &&
7607  is_detected_exact<bool, end_array_function_t, SAX>::value &&
7608  is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
7609 };
7610 
7611 template<typename SAX, typename BasicJsonType>
7612 struct is_sax_static_asserts
7613 {
7614  private:
7615  static_assert(is_basic_json<BasicJsonType>::value,
7616  "BasicJsonType must be of type basic_json<...>");
7617 
7618  using number_integer_t = typename BasicJsonType::number_integer_t;
7619  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7620  using number_float_t = typename BasicJsonType::number_float_t;
7621  using string_t = typename BasicJsonType::string_t;
7622  using binary_t = typename BasicJsonType::binary_t;
7623  using exception_t = typename BasicJsonType::exception;
7624 
7625  public:
7626  static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
7627  "Missing/invalid function: bool null()");
7628  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7629  "Missing/invalid function: bool boolean(bool)");
7630  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7631  "Missing/invalid function: bool boolean(bool)");
7632  static_assert(
7633  is_detected_exact<bool, number_integer_function_t, SAX,
7634  number_integer_t>::value,
7635  "Missing/invalid function: bool number_integer(number_integer_t)");
7636  static_assert(
7637  is_detected_exact<bool, number_unsigned_function_t, SAX,
7638  number_unsigned_t>::value,
7639  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7640  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7641  number_float_t, string_t>::value,
7642  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7643  static_assert(
7644  is_detected_exact<bool, string_function_t, SAX, string_t>::value,
7645  "Missing/invalid function: bool string(string_t&)");
7646  static_assert(
7647  is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
7648  "Missing/invalid function: bool binary(binary_t&)");
7649  static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
7650  "Missing/invalid function: bool start_object(std::size_t)");
7651  static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
7652  "Missing/invalid function: bool key(string_t&)");
7653  static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
7654  "Missing/invalid function: bool end_object()");
7655  static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
7656  "Missing/invalid function: bool start_array(std::size_t)");
7657  static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
7658  "Missing/invalid function: bool end_array()");
7659  static_assert(
7660  is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
7661  "Missing/invalid function: bool parse_error(std::size_t, const "
7662  "std::string&, const exception&)");
7663 };
7664 } // namespace detail
7665 } // namespace nlohmann
7666 
7667 // #include <nlohmann/detail/value_t.hpp>
7668 
7669 
7670 namespace nlohmann
7671 {
7672 namespace detail
7673 {
7674 
7676 enum class cbor_tag_handler_t
7677 {
7678  error,
7679  ignore
7680 };
7681 
7689 static inline bool little_endianess(int num = 1) noexcept
7690 {
7691  return *reinterpret_cast<char*>(&num) == 1;
7692 }
7693 
7694 
7696 // binary reader //
7698 
7702 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7703 class binary_reader
7704 {
7705  using number_integer_t = typename BasicJsonType::number_integer_t;
7706  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7707  using number_float_t = typename BasicJsonType::number_float_t;
7708  using string_t = typename BasicJsonType::string_t;
7709  using binary_t = typename BasicJsonType::binary_t;
7710  using json_sax_t = SAX;
7711  using char_type = typename InputAdapterType::char_type;
7712  using char_int_type = typename std::char_traits<char_type>::int_type;
7713 
7714  public:
7720  explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7721  {
7722  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7723  }
7724 
7725  // make class move-only
7726  binary_reader(const binary_reader&) = delete;
7727  binary_reader(binary_reader&&) = default;
7728  binary_reader& operator=(const binary_reader&) = delete;
7729  binary_reader& operator=(binary_reader&&) = default;
7730  ~binary_reader() = default;
7731 
7740  JSON_HEDLEY_NON_NULL(3)
7741  bool sax_parse(const input_format_t format,
7742  json_sax_t* sax_,
7743  const bool strict = true,
7744  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7745  {
7746  sax = sax_;
7747  bool result = false;
7748 
7749  switch (format)
7750  {
7751  case input_format_t::bson:
7752  result = parse_bson_internal();
7753  break;
7754 
7755  case input_format_t::cbor:
7756  result = parse_cbor_internal(true, tag_handler);
7757  break;
7758 
7759  case input_format_t::msgpack:
7760  result = parse_msgpack_internal();
7761  break;
7762 
7763  case input_format_t::ubjson:
7764  result = parse_ubjson_internal();
7765  break;
7766 
7767  default: // LCOV_EXCL_LINE
7768  JSON_ASSERT(false); // LCOV_EXCL_LINE
7769  }
7770 
7771  // strict mode: next byte must be EOF
7772  if (result && strict)
7773  {
7774  if (format == input_format_t::ubjson)
7775  {
7776  get_ignore_noop();
7777  }
7778  else
7779  {
7780  get();
7781  }
7782 
7783  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7784  {
7785  return sax->parse_error(chars_read, get_token_string(),
7786  parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7787  }
7788  }
7789 
7790  return result;
7791  }
7792 
7793  private:
7795  // BSON //
7797 
7802  bool parse_bson_internal()
7803  {
7804  std::int32_t document_size{};
7805  get_number<std::int32_t, true>(input_format_t::bson, document_size);
7806 
7807  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7808  {
7809  return false;
7810  }
7811 
7812  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7813  {
7814  return false;
7815  }
7816 
7817  return sax->end_object();
7818  }
7819 
7827  bool get_bson_cstr(string_t& result)
7828  {
7829  auto out = std::back_inserter(result);
7830  while (true)
7831  {
7832  get();
7833  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
7834  {
7835  return false;
7836  }
7837  if (current == 0x00)
7838  {
7839  return true;
7840  }
7841  *out++ = static_cast<typename string_t::value_type>(current);
7842  }
7843  }
7844 
7856  template<typename NumberType>
7857  bool get_bson_string(const NumberType len, string_t& result)
7858  {
7859  if (JSON_HEDLEY_UNLIKELY(len < 1))
7860  {
7861  auto last_token = get_token_string();
7862  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
7863  }
7864 
7865  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7866  }
7867 
7877  template<typename NumberType>
7878  bool get_bson_binary(const NumberType len, binary_t& result)
7879  {
7880  if (JSON_HEDLEY_UNLIKELY(len < 0))
7881  {
7882  auto last_token = get_token_string();
7883  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
7884  }
7885 
7886  // All BSON binary values have a subtype
7887  std::uint8_t subtype{};
7888  get_number<std::uint8_t>(input_format_t::bson, subtype);
7889  result.set_subtype(subtype);
7890 
7891  return get_binary(input_format_t::bson, len, result);
7892  }
7893 
7904  bool parse_bson_element_internal(const char_int_type element_type,
7905  const std::size_t element_type_parse_position)
7906  {
7907  switch (element_type)
7908  {
7909  case 0x01: // double
7910  {
7911  double number{};
7912  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7913  }
7914 
7915  case 0x02: // string
7916  {
7917  std::int32_t len{};
7918  string_t value;
7919  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7920  }
7921 
7922  case 0x03: // object
7923  {
7924  return parse_bson_internal();
7925  }
7926 
7927  case 0x04: // array
7928  {
7929  return parse_bson_array();
7930  }
7931 
7932  case 0x05: // binary
7933  {
7934  std::int32_t len{};
7935  binary_t value;
7936  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7937  }
7938 
7939  case 0x08: // boolean
7940  {
7941  return sax->boolean(get() != 0);
7942  }
7943 
7944  case 0x0A: // null
7945  {
7946  return sax->null();
7947  }
7948 
7949  case 0x10: // int32
7950  {
7951  std::int32_t value{};
7952  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7953  }
7954 
7955  case 0x12: // int64
7956  {
7957  std::int64_t value{};
7958  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7959  }
7960 
7961  default: // anything else not supported (yet)
7962  {
7963  std::array<char, 3> cr{{}};
7964  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
7965  return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
7966  }
7967  }
7968  }
7969 
7982  bool parse_bson_element_list(const bool is_array)
7983  {
7984  string_t key;
7985 
7986  while (auto element_type = get())
7987  {
7988  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
7989  {
7990  return false;
7991  }
7992 
7993  const std::size_t element_type_parse_position = chars_read;
7994  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
7995  {
7996  return false;
7997  }
7998 
7999  if (!is_array && !sax->key(key))
8000  {
8001  return false;
8002  }
8003 
8004  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8005  {
8006  return false;
8007  }
8008 
8009  // get_bson_cstr only appends
8010  key.clear();
8011  }
8012 
8013  return true;
8014  }
8015 
8020  bool parse_bson_array()
8021  {
8022  std::int32_t document_size{};
8023  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8024 
8025  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8026  {
8027  return false;
8028  }
8029 
8030  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8031  {
8032  return false;
8033  }
8034 
8035  return sax->end_array();
8036  }
8037 
8039  // CBOR //
8041 
8050  bool parse_cbor_internal(const bool get_char,
8051  const cbor_tag_handler_t tag_handler)
8052  {
8053  switch (get_char ? get() : current)
8054  {
8055  // EOF
8056  case std::char_traits<char_type>::eof():
8057  return unexpect_eof(input_format_t::cbor, "value");
8058 
8059  // Integer 0x00..0x17 (0..23)
8060  case 0x00:
8061  case 0x01:
8062  case 0x02:
8063  case 0x03:
8064  case 0x04:
8065  case 0x05:
8066  case 0x06:
8067  case 0x07:
8068  case 0x08:
8069  case 0x09:
8070  case 0x0A:
8071  case 0x0B:
8072  case 0x0C:
8073  case 0x0D:
8074  case 0x0E:
8075  case 0x0F:
8076  case 0x10:
8077  case 0x11:
8078  case 0x12:
8079  case 0x13:
8080  case 0x14:
8081  case 0x15:
8082  case 0x16:
8083  case 0x17:
8084  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8085 
8086  case 0x18: // Unsigned integer (one-byte uint8_t follows)
8087  {
8088  std::uint8_t number{};
8089  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8090  }
8091 
8092  case 0x19: // Unsigned integer (two-byte uint16_t follows)
8093  {
8094  std::uint16_t number{};
8095  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8096  }
8097 
8098  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8099  {
8100  std::uint32_t number{};
8101  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8102  }
8103 
8104  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8105  {
8106  std::uint64_t number{};
8107  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8108  }
8109 
8110  // Negative integer -1-0x00..-1-0x17 (-1..-24)
8111  case 0x20:
8112  case 0x21:
8113  case 0x22:
8114  case 0x23:
8115  case 0x24:
8116  case 0x25:
8117  case 0x26:
8118  case 0x27:
8119  case 0x28:
8120  case 0x29:
8121  case 0x2A:
8122  case 0x2B:
8123  case 0x2C:
8124  case 0x2D:
8125  case 0x2E:
8126  case 0x2F:
8127  case 0x30:
8128  case 0x31:
8129  case 0x32:
8130  case 0x33:
8131  case 0x34:
8132  case 0x35:
8133  case 0x36:
8134  case 0x37:
8135  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8136 
8137  case 0x38: // Negative integer (one-byte uint8_t follows)
8138  {
8139  std::uint8_t number{};
8140  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8141  }
8142 
8143  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8144  {
8145  std::uint16_t number{};
8146  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8147  }
8148 
8149  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8150  {
8151  std::uint32_t number{};
8152  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8153  }
8154 
8155  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8156  {
8157  std::uint64_t number{};
8158  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8159  - static_cast<number_integer_t>(number));
8160  }
8161 
8162  // Binary data (0x00..0x17 bytes follow)
8163  case 0x40:
8164  case 0x41:
8165  case 0x42:
8166  case 0x43:
8167  case 0x44:
8168  case 0x45:
8169  case 0x46:
8170  case 0x47:
8171  case 0x48:
8172  case 0x49:
8173  case 0x4A:
8174  case 0x4B:
8175  case 0x4C:
8176  case 0x4D:
8177  case 0x4E:
8178  case 0x4F:
8179  case 0x50:
8180  case 0x51:
8181  case 0x52:
8182  case 0x53:
8183  case 0x54:
8184  case 0x55:
8185  case 0x56:
8186  case 0x57:
8187  case 0x58: // Binary data (one-byte uint8_t for n follows)
8188  case 0x59: // Binary data (two-byte uint16_t for n follow)
8189  case 0x5A: // Binary data (four-byte uint32_t for n follow)
8190  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8191  case 0x5F: // Binary data (indefinite length)
8192  {
8193  binary_t b;
8194  return get_cbor_binary(b) && sax->binary(b);
8195  }
8196 
8197  // UTF-8 string (0x00..0x17 bytes follow)
8198  case 0x60:
8199  case 0x61:
8200  case 0x62:
8201  case 0x63:
8202  case 0x64:
8203  case 0x65:
8204  case 0x66:
8205  case 0x67:
8206  case 0x68:
8207  case 0x69:
8208  case 0x6A:
8209  case 0x6B:
8210  case 0x6C:
8211  case 0x6D:
8212  case 0x6E:
8213  case 0x6F:
8214  case 0x70:
8215  case 0x71:
8216  case 0x72:
8217  case 0x73:
8218  case 0x74:
8219  case 0x75:
8220  case 0x76:
8221  case 0x77:
8222  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8223  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8224  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8225  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8226  case 0x7F: // UTF-8 string (indefinite length)
8227  {
8228  string_t s;
8229  return get_cbor_string(s) && sax->string(s);
8230  }
8231 
8232  // array (0x00..0x17 data items follow)
8233  case 0x80:
8234  case 0x81:
8235  case 0x82:
8236  case 0x83:
8237  case 0x84:
8238  case 0x85:
8239  case 0x86:
8240  case 0x87:
8241  case 0x88:
8242  case 0x89:
8243  case 0x8A:
8244  case 0x8B:
8245  case 0x8C:
8246  case 0x8D:
8247  case 0x8E:
8248  case 0x8F:
8249  case 0x90:
8250  case 0x91:
8251  case 0x92:
8252  case 0x93:
8253  case 0x94:
8254  case 0x95:
8255  case 0x96:
8256  case 0x97:
8257  return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8258 
8259  case 0x98: // array (one-byte uint8_t for n follows)
8260  {
8261  std::uint8_t len{};
8262  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8263  }
8264 
8265  case 0x99: // array (two-byte uint16_t for n follow)
8266  {
8267  std::uint16_t len{};
8268  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8269  }
8270 
8271  case 0x9A: // array (four-byte uint32_t for n follow)
8272  {
8273  std::uint32_t len{};
8274  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8275  }
8276 
8277  case 0x9B: // array (eight-byte uint64_t for n follow)
8278  {
8279  std::uint64_t len{};
8280  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8281  }
8282 
8283  case 0x9F: // array (indefinite length)
8284  return get_cbor_array(std::size_t(-1), tag_handler);
8285 
8286  // map (0x00..0x17 pairs of data items follow)
8287  case 0xA0:
8288  case 0xA1:
8289  case 0xA2:
8290  case 0xA3:
8291  case 0xA4:
8292  case 0xA5:
8293  case 0xA6:
8294  case 0xA7:
8295  case 0xA8:
8296  case 0xA9:
8297  case 0xAA:
8298  case 0xAB:
8299  case 0xAC:
8300  case 0xAD:
8301  case 0xAE:
8302  case 0xAF:
8303  case 0xB0:
8304  case 0xB1:
8305  case 0xB2:
8306  case 0xB3:
8307  case 0xB4:
8308  case 0xB5:
8309  case 0xB6:
8310  case 0xB7:
8311  return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8312 
8313  case 0xB8: // map (one-byte uint8_t for n follows)
8314  {
8315  std::uint8_t len{};
8316  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8317  }
8318 
8319  case 0xB9: // map (two-byte uint16_t for n follow)
8320  {
8321  std::uint16_t len{};
8322  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8323  }
8324 
8325  case 0xBA: // map (four-byte uint32_t for n follow)
8326  {
8327  std::uint32_t len{};
8328  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8329  }
8330 
8331  case 0xBB: // map (eight-byte uint64_t for n follow)
8332  {
8333  std::uint64_t len{};
8334  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8335  }
8336 
8337  case 0xBF: // map (indefinite length)
8338  return get_cbor_object(std::size_t(-1), tag_handler);
8339 
8340  case 0xC6: // tagged item
8341  case 0xC7:
8342  case 0xC8:
8343  case 0xC9:
8344  case 0xCA:
8345  case 0xCB:
8346  case 0xCC:
8347  case 0xCD:
8348  case 0xCE:
8349  case 0xCF:
8350  case 0xD0:
8351  case 0xD1:
8352  case 0xD2:
8353  case 0xD3:
8354  case 0xD4:
8355  case 0xD8: // tagged item (1 bytes follow)
8356  case 0xD9: // tagged item (2 bytes follow)
8357  case 0xDA: // tagged item (4 bytes follow)
8358  case 0xDB: // tagged item (8 bytes follow)
8359  {
8360  switch (tag_handler)
8361  {
8362  case cbor_tag_handler_t::error:
8363  {
8364  auto last_token = get_token_string();
8365  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
8366  }
8367 
8368  case cbor_tag_handler_t::ignore:
8369  {
8370  switch (current)
8371  {
8372  case 0xD8:
8373  {
8374  std::uint8_t len{};
8375  get_number(input_format_t::cbor, len);
8376  break;
8377  }
8378  case 0xD9:
8379  {
8380  std::uint16_t len{};
8381  get_number(input_format_t::cbor, len);
8382  break;
8383  }
8384  case 0xDA:
8385  {
8386  std::uint32_t len{};
8387  get_number(input_format_t::cbor, len);
8388  break;
8389  }
8390  case 0xDB:
8391  {
8392  std::uint64_t len{};
8393  get_number(input_format_t::cbor, len);
8394  break;
8395  }
8396  default:
8397  break;
8398  }
8399  return parse_cbor_internal(true, tag_handler);
8400  }
8401 
8402  default: // LCOV_EXCL_LINE
8403  JSON_ASSERT(false); // LCOV_EXCL_LINE
8404  return false; // LCOV_EXCL_LINE
8405  }
8406  }
8407 
8408  case 0xF4: // false
8409  return sax->boolean(false);
8410 
8411  case 0xF5: // true
8412  return sax->boolean(true);
8413 
8414  case 0xF6: // null
8415  return sax->null();
8416 
8417  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8418  {
8419  const auto byte1_raw = get();
8420  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8421  {
8422  return false;
8423  }
8424  const auto byte2_raw = get();
8425  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8426  {
8427  return false;
8428  }
8429 
8430  const auto byte1 = static_cast<unsigned char>(byte1_raw);
8431  const auto byte2 = static_cast<unsigned char>(byte2_raw);
8432 
8433  // code from RFC 7049, Appendix D, Figure 3:
8434  // As half-precision floating-point numbers were only added
8435  // to IEEE 754 in 2008, today's programming platforms often
8436  // still only have limited support for them. It is very
8437  // easy to include at least decoding support for them even
8438  // without such support. An example of a small decoder for
8439  // half-precision floating-point numbers in the C language
8440  // is shown in Fig. 3.
8441  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8442  const double val = [&half]
8443  {
8444  const int exp = (half >> 10u) & 0x1Fu;
8445  const unsigned int mant = half & 0x3FFu;
8446  JSON_ASSERT(0 <= exp&& exp <= 32);
8447  JSON_ASSERT(mant <= 1024);
8448  switch (exp)
8449  {
8450  case 0:
8451  return std::ldexp(mant, -24);
8452  case 31:
8453  return (mant == 0)
8454  ? std::numeric_limits<double>::infinity()
8455  : std::numeric_limits<double>::quiet_NaN();
8456  default:
8457  return std::ldexp(mant + 1024, exp - 25);
8458  }
8459  }();
8460  return sax->number_float((half & 0x8000u) != 0
8461  ? static_cast<number_float_t>(-val)
8462  : static_cast<number_float_t>(val), "");
8463  }
8464 
8465  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8466  {
8467  float number{};
8468  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8469  }
8470 
8471  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8472  {
8473  double number{};
8474  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8475  }
8476 
8477  default: // anything else (0xFF is handled inside the other types)
8478  {
8479  auto last_token = get_token_string();
8480  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
8481  }
8482  }
8483  }
8484 
8496  bool get_cbor_string(string_t& result)
8497  {
8498  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
8499  {
8500  return false;
8501  }
8502 
8503  switch (current)
8504  {
8505  // UTF-8 string (0x00..0x17 bytes follow)
8506  case 0x60:
8507  case 0x61:
8508  case 0x62:
8509  case 0x63:
8510  case 0x64:
8511  case 0x65:
8512  case 0x66:
8513  case 0x67:
8514  case 0x68:
8515  case 0x69:
8516  case 0x6A:
8517  case 0x6B:
8518  case 0x6C:
8519  case 0x6D:
8520  case 0x6E:
8521  case 0x6F:
8522  case 0x70:
8523  case 0x71:
8524  case 0x72:
8525  case 0x73:
8526  case 0x74:
8527  case 0x75:
8528  case 0x76:
8529  case 0x77:
8530  {
8531  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8532  }
8533 
8534  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8535  {
8536  std::uint8_t len{};
8537  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8538  }
8539 
8540  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8541  {
8542  std::uint16_t len{};
8543  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8544  }
8545 
8546  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8547  {
8548  std::uint32_t len{};
8549  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8550  }
8551 
8552  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8553  {
8554  std::uint64_t len{};
8555  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8556  }
8557 
8558  case 0x7F: // UTF-8 string (indefinite length)
8559  {
8560  while (get() != 0xFF)
8561  {
8562  string_t chunk;
8563  if (!get_cbor_string(chunk))
8564  {
8565  return false;
8566  }
8567  result.append(chunk);
8568  }
8569  return true;
8570  }
8571 
8572  default:
8573  {
8574  auto last_token = get_token_string();
8575  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
8576  }
8577  }
8578  }
8579 
8591  bool get_cbor_binary(binary_t& result)
8592  {
8593  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
8594  {
8595  return false;
8596  }
8597 
8598  switch (current)
8599  {
8600  // Binary data (0x00..0x17 bytes follow)
8601  case 0x40:
8602  case 0x41:
8603  case 0x42:
8604  case 0x43:
8605  case 0x44:
8606  case 0x45:
8607  case 0x46:
8608  case 0x47:
8609  case 0x48:
8610  case 0x49:
8611  case 0x4A:
8612  case 0x4B:
8613  case 0x4C:
8614  case 0x4D:
8615  case 0x4E:
8616  case 0x4F:
8617  case 0x50:
8618  case 0x51:
8619  case 0x52:
8620  case 0x53:
8621  case 0x54:
8622  case 0x55:
8623  case 0x56:
8624  case 0x57:
8625  {
8626  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8627  }
8628 
8629  case 0x58: // Binary data (one-byte uint8_t for n follows)
8630  {
8631  std::uint8_t len{};
8632  return get_number(input_format_t::cbor, len) &&
8633  get_binary(input_format_t::cbor, len, result);
8634  }
8635 
8636  case 0x59: // Binary data (two-byte uint16_t for n follow)
8637  {
8638  std::uint16_t len{};
8639  return get_number(input_format_t::cbor, len) &&
8640  get_binary(input_format_t::cbor, len, result);
8641  }
8642 
8643  case 0x5A: // Binary data (four-byte uint32_t for n follow)
8644  {
8645  std::uint32_t len{};
8646  return get_number(input_format_t::cbor, len) &&
8647  get_binary(input_format_t::cbor, len, result);
8648  }
8649 
8650  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8651  {
8652  std::uint64_t len{};
8653  return get_number(input_format_t::cbor, len) &&
8654  get_binary(input_format_t::cbor, len, result);
8655  }
8656 
8657  case 0x5F: // Binary data (indefinite length)
8658  {
8659  while (get() != 0xFF)
8660  {
8661  binary_t chunk;
8662  if (!get_cbor_binary(chunk))
8663  {
8664  return false;
8665  }
8666  result.insert(result.end(), chunk.begin(), chunk.end());
8667  }
8668  return true;
8669  }
8670 
8671  default:
8672  {
8673  auto last_token = get_token_string();
8674  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
8675  }
8676  }
8677  }
8678 
8685  bool get_cbor_array(const std::size_t len,
8686  const cbor_tag_handler_t tag_handler)
8687  {
8688  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8689  {
8690  return false;
8691  }
8692 
8693  if (len != std::size_t(-1))
8694  {
8695  for (std::size_t i = 0; i < len; ++i)
8696  {
8697  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8698  {
8699  return false;
8700  }
8701  }
8702  }
8703  else
8704  {
8705  while (get() != 0xFF)
8706  {
8707  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8708  {
8709  return false;
8710  }
8711  }
8712  }
8713 
8714  return sax->end_array();
8715  }
8716 
8723  bool get_cbor_object(const std::size_t len,
8724  const cbor_tag_handler_t tag_handler)
8725  {
8726  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8727  {
8728  return false;
8729  }
8730 
8731  string_t key;
8732  if (len != std::size_t(-1))
8733  {
8734  for (std::size_t i = 0; i < len; ++i)
8735  {
8736  get();
8737  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8738  {
8739  return false;
8740  }
8741 
8742  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8743  {
8744  return false;
8745  }
8746  key.clear();
8747  }
8748  }
8749  else
8750  {
8751  while (get() != 0xFF)
8752  {
8753  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8754  {
8755  return false;
8756  }
8757 
8758  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8759  {
8760  return false;
8761  }
8762  key.clear();
8763  }
8764  }
8765 
8766  return sax->end_object();
8767  }
8768 
8770  // MsgPack //
8772 
8776  bool parse_msgpack_internal()
8777  {
8778  switch (get())
8779  {
8780  // EOF
8781  case std::char_traits<char_type>::eof():
8782  return unexpect_eof(input_format_t::msgpack, "value");
8783 
8784  // positive fixint
8785  case 0x00:
8786  case 0x01:
8787  case 0x02:
8788  case 0x03:
8789  case 0x04:
8790  case 0x05:
8791  case 0x06:
8792  case 0x07:
8793  case 0x08:
8794  case 0x09:
8795  case 0x0A:
8796  case 0x0B:
8797  case 0x0C:
8798  case 0x0D:
8799  case 0x0E:
8800  case 0x0F:
8801  case 0x10:
8802  case 0x11:
8803  case 0x12:
8804  case 0x13:
8805  case 0x14:
8806  case 0x15:
8807  case 0x16:
8808  case 0x17:
8809  case 0x18:
8810  case 0x19:
8811  case 0x1A:
8812  case 0x1B:
8813  case 0x1C:
8814  case 0x1D:
8815  case 0x1E:
8816  case 0x1F:
8817  case 0x20:
8818  case 0x21:
8819  case 0x22:
8820  case 0x23:
8821  case 0x24:
8822  case 0x25:
8823  case 0x26:
8824  case 0x27:
8825  case 0x28:
8826  case 0x29:
8827  case 0x2A:
8828  case 0x2B:
8829  case 0x2C:
8830  case 0x2D:
8831  case 0x2E:
8832  case 0x2F:
8833  case 0x30:
8834  case 0x31:
8835  case 0x32:
8836  case 0x33:
8837  case 0x34:
8838  case 0x35:
8839  case 0x36:
8840  case 0x37:
8841  case 0x38:
8842  case 0x39:
8843  case 0x3A:
8844  case 0x3B:
8845  case 0x3C:
8846  case 0x3D:
8847  case 0x3E:
8848  case 0x3F:
8849  case 0x40:
8850  case 0x41:
8851  case 0x42:
8852  case 0x43:
8853  case 0x44:
8854  case 0x45:
8855  case 0x46:
8856  case 0x47:
8857  case 0x48:
8858  case 0x49:
8859  case 0x4A:
8860  case 0x4B:
8861  case 0x4C:
8862  case 0x4D:
8863  case 0x4E:
8864  case 0x4F:
8865  case 0x50:
8866  case 0x51:
8867  case 0x52:
8868  case 0x53:
8869  case 0x54:
8870  case 0x55:
8871  case 0x56:
8872  case 0x57:
8873  case 0x58:
8874  case 0x59:
8875  case 0x5A:
8876  case 0x5B:
8877  case 0x5C:
8878  case 0x5D:
8879  case 0x5E:
8880  case 0x5F:
8881  case 0x60:
8882  case 0x61:
8883  case 0x62:
8884  case 0x63:
8885  case 0x64:
8886  case 0x65:
8887  case 0x66:
8888  case 0x67:
8889  case 0x68:
8890  case 0x69:
8891  case 0x6A:
8892  case 0x6B:
8893  case 0x6C:
8894  case 0x6D:
8895  case 0x6E:
8896  case 0x6F:
8897  case 0x70:
8898  case 0x71:
8899  case 0x72:
8900  case 0x73:
8901  case 0x74:
8902  case 0x75:
8903  case 0x76:
8904  case 0x77:
8905  case 0x78:
8906  case 0x79:
8907  case 0x7A:
8908  case 0x7B:
8909  case 0x7C:
8910  case 0x7D:
8911  case 0x7E:
8912  case 0x7F:
8913  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8914 
8915  // fixmap
8916  case 0x80:
8917  case 0x81:
8918  case 0x82:
8919  case 0x83:
8920  case 0x84:
8921  case 0x85:
8922  case 0x86:
8923  case 0x87:
8924  case 0x88:
8925  case 0x89:
8926  case 0x8A:
8927  case 0x8B:
8928  case 0x8C:
8929  case 0x8D:
8930  case 0x8E:
8931  case 0x8F:
8932  return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8933 
8934  // fixarray
8935  case 0x90:
8936  case 0x91:
8937  case 0x92:
8938  case 0x93:
8939  case 0x94:
8940  case 0x95:
8941  case 0x96:
8942  case 0x97:
8943  case 0x98:
8944  case 0x99:
8945  case 0x9A:
8946  case 0x9B:
8947  case 0x9C:
8948  case 0x9D:
8949  case 0x9E:
8950  case 0x9F:
8951  return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8952 
8953  // fixstr
8954  case 0xA0:
8955  case 0xA1:
8956  case 0xA2:
8957  case 0xA3:
8958  case 0xA4:
8959  case 0xA5:
8960  case 0xA6:
8961  case 0xA7:
8962  case 0xA8:
8963  case 0xA9:
8964  case 0xAA:
8965  case 0xAB:
8966  case 0xAC:
8967  case 0xAD:
8968  case 0xAE:
8969  case 0xAF:
8970  case 0xB0:
8971  case 0xB1:
8972  case 0xB2:
8973  case 0xB3:
8974  case 0xB4:
8975  case 0xB5:
8976  case 0xB6:
8977  case 0xB7:
8978  case 0xB8:
8979  case 0xB9:
8980  case 0xBA:
8981  case 0xBB:
8982  case 0xBC:
8983  case 0xBD:
8984  case 0xBE:
8985  case 0xBF:
8986  case 0xD9: // str 8
8987  case 0xDA: // str 16
8988  case 0xDB: // str 32
8989  {
8990  string_t s;
8991  return get_msgpack_string(s) && sax->string(s);
8992  }
8993 
8994  case 0xC0: // nil
8995  return sax->null();
8996 
8997  case 0xC2: // false
8998  return sax->boolean(false);
8999 
9000  case 0xC3: // true
9001  return sax->boolean(true);
9002 
9003  case 0xC4: // bin 8
9004  case 0xC5: // bin 16
9005  case 0xC6: // bin 32
9006  case 0xC7: // ext 8
9007  case 0xC8: // ext 16
9008  case 0xC9: // ext 32
9009  case 0xD4: // fixext 1
9010  case 0xD5: // fixext 2
9011  case 0xD6: // fixext 4
9012  case 0xD7: // fixext 8
9013  case 0xD8: // fixext 16
9014  {
9015  binary_t b;
9016  return get_msgpack_binary(b) && sax->binary(b);
9017  }
9018 
9019  case 0xCA: // float 32
9020  {
9021  float number{};
9022  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9023  }
9024 
9025  case 0xCB: // float 64
9026  {
9027  double number{};
9028  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9029  }
9030 
9031  case 0xCC: // uint 8
9032  {
9033  std::uint8_t number{};
9034  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9035  }
9036 
9037  case 0xCD: // uint 16
9038  {
9039  std::uint16_t number{};
9040  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9041  }
9042 
9043  case 0xCE: // uint 32
9044  {
9045  std::uint32_t number{};
9046  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9047  }
9048 
9049  case 0xCF: // uint 64
9050  {
9051  std::uint64_t number{};
9052  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9053  }
9054 
9055  case 0xD0: // int 8
9056  {
9057  std::int8_t number{};
9058  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9059  }
9060 
9061  case 0xD1: // int 16
9062  {
9063  std::int16_t number{};
9064  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9065  }
9066 
9067  case 0xD2: // int 32
9068  {
9069  std::int32_t number{};
9070  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9071  }
9072 
9073  case 0xD3: // int 64
9074  {
9075  std::int64_t number{};
9076  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9077  }
9078 
9079  case 0xDC: // array 16
9080  {
9081  std::uint16_t len{};
9082  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9083  }
9084 
9085  case 0xDD: // array 32
9086  {
9087  std::uint32_t len{};
9088  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9089  }
9090 
9091  case 0xDE: // map 16
9092  {
9093  std::uint16_t len{};
9094  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9095  }
9096 
9097  case 0xDF: // map 32
9098  {
9099  std::uint32_t len{};
9100  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9101  }
9102 
9103  // negative fixint
9104  case 0xE0:
9105  case 0xE1:
9106  case 0xE2:
9107  case 0xE3:
9108  case 0xE4:
9109  case 0xE5:
9110  case 0xE6:
9111  case 0xE7:
9112  case 0xE8:
9113  case 0xE9:
9114  case 0xEA:
9115  case 0xEB:
9116  case 0xEC:
9117  case 0xED:
9118  case 0xEE:
9119  case 0xEF:
9120  case 0xF0:
9121  case 0xF1:
9122  case 0xF2:
9123  case 0xF3:
9124  case 0xF4:
9125  case 0xF5:
9126  case 0xF6:
9127  case 0xF7:
9128  case 0xF8:
9129  case 0xF9:
9130  case 0xFA:
9131  case 0xFB:
9132  case 0xFC:
9133  case 0xFD:
9134  case 0xFE:
9135  case 0xFF:
9136  return sax->number_integer(static_cast<std::int8_t>(current));
9137 
9138  default: // anything else
9139  {
9140  auto last_token = get_token_string();
9141  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
9142  }
9143  }
9144  }
9145 
9156  bool get_msgpack_string(string_t& result)
9157  {
9158  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9159  {
9160  return false;
9161  }
9162 
9163  switch (current)
9164  {
9165  // fixstr
9166  case 0xA0:
9167  case 0xA1:
9168  case 0xA2:
9169  case 0xA3:
9170  case 0xA4:
9171  case 0xA5:
9172  case 0xA6:
9173  case 0xA7:
9174  case 0xA8:
9175  case 0xA9:
9176  case 0xAA:
9177  case 0xAB:
9178  case 0xAC:
9179  case 0xAD:
9180  case 0xAE:
9181  case 0xAF:
9182  case 0xB0:
9183  case 0xB1:
9184  case 0xB2:
9185  case 0xB3:
9186  case 0xB4:
9187  case 0xB5:
9188  case 0xB6:
9189  case 0xB7:
9190  case 0xB8:
9191  case 0xB9:
9192  case 0xBA:
9193  case 0xBB:
9194  case 0xBC:
9195  case 0xBD:
9196  case 0xBE:
9197  case 0xBF:
9198  {
9199  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9200  }
9201 
9202  case 0xD9: // str 8
9203  {
9204  std::uint8_t len{};
9205  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9206  }
9207 
9208  case 0xDA: // str 16
9209  {
9210  std::uint16_t len{};
9211  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9212  }
9213 
9214  case 0xDB: // str 32
9215  {
9216  std::uint32_t len{};
9217  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9218  }
9219 
9220  default:
9221  {
9222  auto last_token = get_token_string();
9223  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
9224  }
9225  }
9226  }
9227 
9238  bool get_msgpack_binary(binary_t& result)
9239  {
9240  // helper function to set the subtype
9241  auto assign_and_return_true = [&result](std::int8_t subtype)
9242  {
9243  result.set_subtype(static_cast<std::uint8_t>(subtype));
9244  return true;
9245  };
9246 
9247  switch (current)
9248  {
9249  case 0xC4: // bin 8
9250  {
9251  std::uint8_t len{};
9252  return get_number(input_format_t::msgpack, len) &&
9253  get_binary(input_format_t::msgpack, len, result);
9254  }
9255 
9256  case 0xC5: // bin 16
9257  {
9258  std::uint16_t len{};
9259  return get_number(input_format_t::msgpack, len) &&
9260  get_binary(input_format_t::msgpack, len, result);
9261  }
9262 
9263  case 0xC6: // bin 32
9264  {
9265  std::uint32_t len{};
9266  return get_number(input_format_t::msgpack, len) &&
9267  get_binary(input_format_t::msgpack, len, result);
9268  }
9269 
9270  case 0xC7: // ext 8
9271  {
9272  std::uint8_t len{};
9273  std::int8_t subtype{};
9274  return get_number(input_format_t::msgpack, len) &&
9275  get_number(input_format_t::msgpack, subtype) &&
9276  get_binary(input_format_t::msgpack, len, result) &&
9277  assign_and_return_true(subtype);
9278  }
9279 
9280  case 0xC8: // ext 16
9281  {
9282  std::uint16_t len{};
9283  std::int8_t subtype{};
9284  return get_number(input_format_t::msgpack, len) &&
9285  get_number(input_format_t::msgpack, subtype) &&
9286  get_binary(input_format_t::msgpack, len, result) &&
9287  assign_and_return_true(subtype);
9288  }
9289 
9290  case 0xC9: // ext 32
9291  {
9292  std::uint32_t len{};
9293  std::int8_t subtype{};
9294  return get_number(input_format_t::msgpack, len) &&
9295  get_number(input_format_t::msgpack, subtype) &&
9296  get_binary(input_format_t::msgpack, len, result) &&
9297  assign_and_return_true(subtype);
9298  }
9299 
9300  case 0xD4: // fixext 1
9301  {
9302  std::int8_t subtype{};
9303  return get_number(input_format_t::msgpack, subtype) &&
9304  get_binary(input_format_t::msgpack, 1, result) &&
9305  assign_and_return_true(subtype);
9306  }
9307 
9308  case 0xD5: // fixext 2
9309  {
9310  std::int8_t subtype{};
9311  return get_number(input_format_t::msgpack, subtype) &&
9312  get_binary(input_format_t::msgpack, 2, result) &&
9313  assign_and_return_true(subtype);
9314  }
9315 
9316  case 0xD6: // fixext 4
9317  {
9318  std::int8_t subtype{};
9319  return get_number(input_format_t::msgpack, subtype) &&
9320  get_binary(input_format_t::msgpack, 4, result) &&
9321  assign_and_return_true(subtype);
9322  }
9323 
9324  case 0xD7: // fixext 8
9325  {
9326  std::int8_t subtype{};
9327  return get_number(input_format_t::msgpack, subtype) &&
9328  get_binary(input_format_t::msgpack, 8, result) &&
9329  assign_and_return_true(subtype);
9330  }
9331 
9332  case 0xD8: // fixext 16
9333  {
9334  std::int8_t subtype{};
9335  return get_number(input_format_t::msgpack, subtype) &&
9336  get_binary(input_format_t::msgpack, 16, result) &&
9337  assign_and_return_true(subtype);
9338  }
9339 
9340  default: // LCOV_EXCL_LINE
9341  return false; // LCOV_EXCL_LINE
9342  }
9343  }
9344 
9349  bool get_msgpack_array(const std::size_t len)
9350  {
9351  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9352  {
9353  return false;
9354  }
9355 
9356  for (std::size_t i = 0; i < len; ++i)
9357  {
9358  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9359  {
9360  return false;
9361  }
9362  }
9363 
9364  return sax->end_array();
9365  }
9366 
9371  bool get_msgpack_object(const std::size_t len)
9372  {
9373  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9374  {
9375  return false;
9376  }
9377 
9378  string_t key;
9379  for (std::size_t i = 0; i < len; ++i)
9380  {
9381  get();
9382  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9383  {
9384  return false;
9385  }
9386 
9387  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9388  {
9389  return false;
9390  }
9391  key.clear();
9392  }
9393 
9394  return sax->end_object();
9395  }
9396 
9398  // UBJSON //
9400 
9408  bool parse_ubjson_internal(const bool get_char = true)
9409  {
9410  return get_ubjson_value(get_char ? get_ignore_noop() : current);
9411  }
9412 
9427  bool get_ubjson_string(string_t& result, const bool get_char = true)
9428  {
9429  if (get_char)
9430  {
9431  get(); // TODO(niels): may we ignore N here?
9432  }
9433 
9434  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9435  {
9436  return false;
9437  }
9438 
9439  switch (current)
9440  {
9441  case 'U':
9442  {
9443  std::uint8_t len{};
9444  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9445  }
9446 
9447  case 'i':
9448  {
9449  std::int8_t len{};
9450  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9451  }
9452 
9453  case 'I':
9454  {
9455  std::int16_t len{};
9456  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9457  }
9458 
9459  case 'l':
9460  {
9461  std::int32_t len{};
9462  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9463  }
9464 
9465  case 'L':
9466  {
9467  std::int64_t len{};
9468  return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9469  }
9470 
9471  default:
9472  auto last_token = get_token_string();
9473  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
9474  }
9475  }
9476 
9481  bool get_ubjson_size_value(std::size_t& result)
9482  {
9483  switch (get_ignore_noop())
9484  {
9485  case 'U':
9486  {
9487  std::uint8_t number{};
9488  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9489  {
9490  return false;
9491  }
9492  result = static_cast<std::size_t>(number);
9493  return true;
9494  }
9495 
9496  case 'i':
9497  {
9498  std::int8_t number{};
9499  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9500  {
9501  return false;
9502  }
9503  result = static_cast<std::size_t>(number);
9504  return true;
9505  }
9506 
9507  case 'I':
9508  {
9509  std::int16_t number{};
9510  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9511  {
9512  return false;
9513  }
9514  result = static_cast<std::size_t>(number);
9515  return true;
9516  }
9517 
9518  case 'l':
9519  {
9520  std::int32_t number{};
9521  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9522  {
9523  return false;
9524  }
9525  result = static_cast<std::size_t>(number);
9526  return true;
9527  }
9528 
9529  case 'L':
9530  {
9531  std::int64_t number{};
9532  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9533  {
9534  return false;
9535  }
9536  result = static_cast<std::size_t>(number);
9537  return true;
9538  }
9539 
9540  default:
9541  {
9542  auto last_token = get_token_string();
9543  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
9544  }
9545  }
9546  }
9547 
9558  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9559  {
9560  result.first = string_t::npos; // size
9561  result.second = 0; // type
9562 
9563  get_ignore_noop();
9564 
9565  if (current == '$')
9566  {
9567  result.second = get(); // must not ignore 'N', because 'N' maybe the type
9568  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
9569  {
9570  return false;
9571  }
9572 
9573  get_ignore_noop();
9574  if (JSON_HEDLEY_UNLIKELY(current != '#'))
9575  {
9576  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9577  {
9578  return false;
9579  }
9580  auto last_token = get_token_string();
9581  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
9582  }
9583 
9584  return get_ubjson_size_value(result.first);
9585  }
9586 
9587  if (current == '#')
9588  {
9589  return get_ubjson_size_value(result.first);
9590  }
9591 
9592  return true;
9593  }
9594 
9599  bool get_ubjson_value(const char_int_type prefix)
9600  {
9601  switch (prefix)
9602  {
9603  case std::char_traits<char_type>::eof(): // EOF
9604  return unexpect_eof(input_format_t::ubjson, "value");
9605 
9606  case 'T': // true
9607  return sax->boolean(true);
9608  case 'F': // false
9609  return sax->boolean(false);
9610 
9611  case 'Z': // null
9612  return sax->null();
9613 
9614  case 'U':
9615  {
9616  std::uint8_t number{};
9617  return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9618  }
9619 
9620  case 'i':
9621  {
9622  std::int8_t number{};
9623  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9624  }
9625 
9626  case 'I':
9627  {
9628  std::int16_t number{};
9629  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9630  }
9631 
9632  case 'l':
9633  {
9634  std::int32_t number{};
9635  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9636  }
9637 
9638  case 'L':
9639  {
9640  std::int64_t number{};
9641  return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9642  }
9643 
9644  case 'd':
9645  {
9646  float number{};
9647  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9648  }
9649 
9650  case 'D':
9651  {
9652  double number{};
9653  return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9654  }
9655 
9656  case 'H':
9657  {
9658  return get_ubjson_high_precision_number();
9659  }
9660 
9661  case 'C': // char
9662  {
9663  get();
9664  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
9665  {
9666  return false;
9667  }
9668  if (JSON_HEDLEY_UNLIKELY(current > 127))
9669  {
9670  auto last_token = get_token_string();
9671  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
9672  }
9673  string_t s(1, static_cast<typename string_t::value_type>(current));
9674  return sax->string(s);
9675  }
9676 
9677  case 'S': // string
9678  {
9679  string_t s;
9680  return get_ubjson_string(s) && sax->string(s);
9681  }
9682 
9683  case '[': // array
9684  return get_ubjson_array();
9685 
9686  case '{': // object
9687  return get_ubjson_object();
9688 
9689  default: // anything else
9690  {
9691  auto last_token = get_token_string();
9692  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
9693  }
9694  }
9695  }
9696 
9700  bool get_ubjson_array()
9701  {
9702  std::pair<std::size_t, char_int_type> size_and_type;
9703  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9704  {
9705  return false;
9706  }
9707 
9708  if (size_and_type.first != string_t::npos)
9709  {
9710  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9711  {
9712  return false;
9713  }
9714 
9715  if (size_and_type.second != 0)
9716  {
9717  if (size_and_type.second != 'N')
9718  {
9719  for (std::size_t i = 0; i < size_and_type.first; ++i)
9720  {
9721  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9722  {
9723  return false;
9724  }
9725  }
9726  }
9727  }
9728  else
9729  {
9730  for (std::size_t i = 0; i < size_and_type.first; ++i)
9731  {
9732  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9733  {
9734  return false;
9735  }
9736  }
9737  }
9738  }
9739  else
9740  {
9741  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9742  {
9743  return false;
9744  }
9745 
9746  while (current != ']')
9747  {
9748  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
9749  {
9750  return false;
9751  }
9752  get_ignore_noop();
9753  }
9754  }
9755 
9756  return sax->end_array();
9757  }
9758 
9762  bool get_ubjson_object()
9763  {
9764  std::pair<std::size_t, char_int_type> size_and_type;
9765  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9766  {
9767  return false;
9768  }
9769 
9770  string_t key;
9771  if (size_and_type.first != string_t::npos)
9772  {
9773  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9774  {
9775  return false;
9776  }
9777 
9778  if (size_and_type.second != 0)
9779  {
9780  for (std::size_t i = 0; i < size_and_type.first; ++i)
9781  {
9782  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9783  {
9784  return false;
9785  }
9786  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9787  {
9788  return false;
9789  }
9790  key.clear();
9791  }
9792  }
9793  else
9794  {
9795  for (std::size_t i = 0; i < size_and_type.first; ++i)
9796  {
9797  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9798  {
9799  return false;
9800  }
9801  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9802  {
9803  return false;
9804  }
9805  key.clear();
9806  }
9807  }
9808  }
9809  else
9810  {
9811  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9812  {
9813  return false;
9814  }
9815 
9816  while (current != '}')
9817  {
9818  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9819  {
9820  return false;
9821  }
9822  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9823  {
9824  return false;
9825  }
9826  get_ignore_noop();
9827  key.clear();
9828  }
9829  }
9830 
9831  return sax->end_object();
9832  }
9833 
9834  // Note, no reader for UBJSON binary types is implemented because they do
9835  // not exist
9836 
9837  bool get_ubjson_high_precision_number()
9838  {
9839  // get size of following number string
9840  std::size_t size{};
9841  auto res = get_ubjson_size_value(size);
9842  if (JSON_HEDLEY_UNLIKELY(!res))
9843  {
9844  return res;
9845  }
9846 
9847  // get number string
9848  std::vector<char> number_vector;
9849  for (std::size_t i = 0; i < size; ++i)
9850  {
9851  get();
9852  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
9853  {
9854  return false;
9855  }
9856  number_vector.push_back(static_cast<char>(current));
9857  }
9858 
9859  // parse number string
9860  auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9861  auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9862  const auto result_number = number_lexer.scan();
9863  const auto number_string = number_lexer.get_token_string();
9864  const auto result_remainder = number_lexer.scan();
9865 
9866  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9867 
9868  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9869  {
9870  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9871  }
9872 
9873  switch (result_number)
9874  {
9875  case token_type::value_integer:
9876  return sax->number_integer(number_lexer.get_number_integer());
9877  case token_type::value_unsigned:
9878  return sax->number_unsigned(number_lexer.get_number_unsigned());
9879  case token_type::value_float:
9880  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9881  default:
9882  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9883  }
9884  }
9885 
9887  // Utility functions //
9889 
9899  char_int_type get()
9900  {
9901  ++chars_read;
9902  return current = ia.get_character();
9903  }
9904 
9908  char_int_type get_ignore_noop()
9909  {
9910  do
9911  {
9912  get();
9913  }
9914  while (current == 'N');
9915 
9916  return current;
9917  }
9918 
9919  /*
9920  @brief read a number from the input
9921 
9922  @tparam NumberType the type of the number
9923  @param[in] format the current format (for diagnostics)
9924  @param[out] result number of type @a NumberType
9925 
9926  @return whether conversion completed
9927 
9928  @note This function needs to respect the system's endianess, because
9929  bytes in CBOR, MessagePack, and UBJSON are stored in network order
9930  (big endian) and therefore need reordering on little endian systems.
9931  */
9932  template<typename NumberType, bool InputIsLittleEndian = false>
9933  bool get_number(const input_format_t format, NumberType& result)
9934  {
9935  // step 1: read input into array with system's byte order
9936  std::array<std::uint8_t, sizeof(NumberType)> vec;
9937  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9938  {
9939  get();
9940  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
9941  {
9942  return false;
9943  }
9944 
9945  // reverse byte order prior to conversion if necessary
9946  if (is_little_endian != InputIsLittleEndian)
9947  {
9948  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
9949  }
9950  else
9951  {
9952  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
9953  }
9954  }
9955 
9956  // step 2: convert array into number of type T and return
9957  std::memcpy(&result, vec.data(), sizeof(NumberType));
9958  return true;
9959  }
9960 
9975  template<typename NumberType>
9976  bool get_string(const input_format_t format,
9977  const NumberType len,
9978  string_t& result)
9979  {
9980  bool success = true;
9981  for (NumberType i = 0; i < len; i++)
9982  {
9983  get();
9984  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
9985  {
9986  success = false;
9987  break;
9988  }
9989  result.push_back(static_cast<typename string_t::value_type>(current));
9990  };
9991  return success;
9992  }
9993 
10008  template<typename NumberType>
10009  bool get_binary(const input_format_t format,
10010  const NumberType len,
10011  binary_t& result)
10012  {
10013  bool success = true;
10014  for (NumberType i = 0; i < len; i++)
10015  {
10016  get();
10017  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10018  {
10019  success = false;
10020  break;
10021  }
10022  result.push_back(static_cast<std::uint8_t>(current));
10023  }
10024  return success;
10025  }
10026 
10032  JSON_HEDLEY_NON_NULL(3)
10033  bool unexpect_eof(const input_format_t format, const char* context) const
10034  {
10035  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10036  {
10037  return sax->parse_error(chars_read, "<end of file>",
10038  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10039  }
10040  return true;
10041  }
10042 
10046  std::string get_token_string() const
10047  {
10048  std::array<char, 3> cr{{}};
10049  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10050  return std::string{cr.data()};
10051  }
10052 
10059  std::string exception_message(const input_format_t format,
10060  const std::string& detail,
10061  const std::string& context) const
10062  {
10063  std::string error_msg = "syntax error while parsing ";
10064 
10065  switch (format)
10066  {
10067  case input_format_t::cbor:
10068  error_msg += "CBOR";
10069  break;
10070 
10071  case input_format_t::msgpack:
10072  error_msg += "MessagePack";
10073  break;
10074 
10075  case input_format_t::ubjson:
10076  error_msg += "UBJSON";
10077  break;
10078 
10079  case input_format_t::bson:
10080  error_msg += "BSON";
10081  break;
10082 
10083  default: // LCOV_EXCL_LINE
10084  JSON_ASSERT(false); // LCOV_EXCL_LINE
10085  }
10086 
10087  return error_msg + " " + context + ": " + detail;
10088  }
10089 
10090  private:
10092  InputAdapterType ia;
10093 
10095  char_int_type current = std::char_traits<char_type>::eof();
10096 
10098  std::size_t chars_read = 0;
10099 
10101  const bool is_little_endian = little_endianess();
10102 
10104  json_sax_t* sax = nullptr;
10105 };
10106 } // namespace detail
10107 } // namespace nlohmann
10108 
10109 // #include <nlohmann/detail/input/input_adapters.hpp>
10110 
10111 // #include <nlohmann/detail/input/lexer.hpp>
10112 
10113 // #include <nlohmann/detail/input/parser.hpp>
10114 
10115 
10116 #include <cmath> // isfinite
10117 #include <cstdint> // uint8_t
10118 #include <functional> // function
10119 #include <string> // string
10120 #include <utility> // move
10121 #include <vector> // vector
10122 
10123 // #include <nlohmann/detail/exceptions.hpp>
10124 
10125 // #include <nlohmann/detail/input/input_adapters.hpp>
10126 
10127 // #include <nlohmann/detail/input/json_sax.hpp>
10128 
10129 // #include <nlohmann/detail/input/lexer.hpp>
10130 
10131 // #include <nlohmann/detail/macro_scope.hpp>
10132 
10133 // #include <nlohmann/detail/meta/is_sax.hpp>
10134 
10135 // #include <nlohmann/detail/value_t.hpp>
10136 
10137 
10138 namespace nlohmann
10139 {
10140 namespace detail
10141 {
10143 // parser //
10145 
10146 enum class parse_event_t : uint8_t
10147 {
10149  object_start,
10151  object_end,
10153  array_start,
10155  array_end,
10157  key,
10159  value
10160 };
10161 
10162 template<typename BasicJsonType>
10163 using parser_callback_t =
10164  std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10165 
10171 template<typename BasicJsonType, typename InputAdapterType>
10172 class parser
10173 {
10174  using number_integer_t = typename BasicJsonType::number_integer_t;
10175  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10176  using number_float_t = typename BasicJsonType::number_float_t;
10177  using string_t = typename BasicJsonType::string_t;
10178  using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10179  using token_type = typename lexer_t::token_type;
10180 
10181  public:
10183  explicit parser(InputAdapterType&& adapter,
10184  const parser_callback_t<BasicJsonType> cb = nullptr,
10185  const bool allow_exceptions_ = true,
10186  const bool skip_comments = false)
10187  : callback(cb)
10188  , m_lexer(std::move(adapter), skip_comments)
10189  , allow_exceptions(allow_exceptions_)
10190  {
10191  // read first token
10192  get_token();
10193  }
10194 
10205  void parse(const bool strict, BasicJsonType& result)
10206  {
10207  if (callback)
10208  {
10209  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10210  sax_parse_internal(&sdp);
10211  result.assert_invariant();
10212 
10213  // in strict mode, input must be completely read
10214  if (strict && (get_token() != token_type::end_of_input))
10215  {
10216  sdp.parse_error(m_lexer.get_position(),
10217  m_lexer.get_token_string(),
10218  parse_error::create(101, m_lexer.get_position(),
10219  exception_message(token_type::end_of_input, "value")));
10220  }
10221 
10222  // in case of an error, return discarded value
10223  if (sdp.is_errored())
10224  {
10225  result = value_t::discarded;
10226  return;
10227  }
10228 
10229  // set top-level value to null if it was discarded by the callback
10230  // function
10231  if (result.is_discarded())
10232  {
10233  result = nullptr;
10234  }
10235  }
10236  else
10237  {
10238  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10239  sax_parse_internal(&sdp);
10240  result.assert_invariant();
10241 
10242  // in strict mode, input must be completely read
10243  if (strict && (get_token() != token_type::end_of_input))
10244  {
10245  sdp.parse_error(m_lexer.get_position(),
10246  m_lexer.get_token_string(),
10247  parse_error::create(101, m_lexer.get_position(),
10248  exception_message(token_type::end_of_input, "value")));
10249  }
10250 
10251  // in case of an error, return discarded value
10252  if (sdp.is_errored())
10253  {
10254  result = value_t::discarded;
10255  return;
10256  }
10257  }
10258  }
10259 
10266  bool accept(const bool strict = true)
10267  {
10268  json_sax_acceptor<BasicJsonType> sax_acceptor;
10269  return sax_parse(&sax_acceptor, strict);
10270  }
10271 
10272  template<typename SAX>
10273  JSON_HEDLEY_NON_NULL(2)
10274  bool sax_parse(SAX* sax, const bool strict = true)
10275  {
10276  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10277  const bool result = sax_parse_internal(sax);
10278 
10279  // strict mode: next byte must be EOF
10280  if (result && strict && (get_token() != token_type::end_of_input))
10281  {
10282  return sax->parse_error(m_lexer.get_position(),
10283  m_lexer.get_token_string(),
10284  parse_error::create(101, m_lexer.get_position(),
10285  exception_message(token_type::end_of_input, "value")));
10286  }
10287 
10288  return result;
10289  }
10290 
10291  private:
10292  template<typename SAX>
10293  JSON_HEDLEY_NON_NULL(2)
10294  bool sax_parse_internal(SAX* sax)
10295  {
10296  // stack to remember the hierarchy of structured values we are parsing
10297  // true = array; false = object
10298  std::vector<bool> states;
10299  // value to avoid a goto (see comment where set to true)
10300  bool skip_to_state_evaluation = false;
10301 
10302  while (true)
10303  {
10304  if (!skip_to_state_evaluation)
10305  {
10306  // invariant: get_token() was called before each iteration
10307  switch (last_token)
10308  {
10309  case token_type::begin_object:
10310  {
10311  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10312  {
10313  return false;
10314  }
10315 
10316  // closing } -> we are done
10317  if (get_token() == token_type::end_object)
10318  {
10319  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10320  {
10321  return false;
10322  }
10323  break;
10324  }
10325 
10326  // parse key
10327  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10328  {
10329  return sax->parse_error(m_lexer.get_position(),
10330  m_lexer.get_token_string(),
10331  parse_error::create(101, m_lexer.get_position(),
10332  exception_message(token_type::value_string, "object key")));
10333  }
10334  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10335  {
10336  return false;
10337  }
10338 
10339  // parse separator (:)
10340  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10341  {
10342  return sax->parse_error(m_lexer.get_position(),
10343  m_lexer.get_token_string(),
10344  parse_error::create(101, m_lexer.get_position(),
10345  exception_message(token_type::name_separator, "object separator")));
10346  }
10347 
10348  // remember we are now inside an object
10349  states.push_back(false);
10350 
10351  // parse values
10352  get_token();
10353  continue;
10354  }
10355 
10356  case token_type::begin_array:
10357  {
10358  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10359  {
10360  return false;
10361  }
10362 
10363  // closing ] -> we are done
10364  if (get_token() == token_type::end_array)
10365  {
10366  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10367  {
10368  return false;
10369  }
10370  break;
10371  }
10372 
10373  // remember we are now inside an array
10374  states.push_back(true);
10375 
10376  // parse values (no need to call get_token)
10377  continue;
10378  }
10379 
10380  case token_type::value_float:
10381  {
10382  const auto res = m_lexer.get_number_float();
10383 
10384  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10385  {
10386  return sax->parse_error(m_lexer.get_position(),
10387  m_lexer.get_token_string(),
10388  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10389  }
10390 
10391  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10392  {
10393  return false;
10394  }
10395 
10396  break;
10397  }
10398 
10399  case token_type::literal_false:
10400  {
10401  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10402  {
10403  return false;
10404  }
10405  break;
10406  }
10407 
10408  case token_type::literal_null:
10409  {
10410  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10411  {
10412  return false;
10413  }
10414  break;
10415  }
10416 
10417  case token_type::literal_true:
10418  {
10419  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10420  {
10421  return false;
10422  }
10423  break;
10424  }
10425 
10426  case token_type::value_integer:
10427  {
10428  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10429  {
10430  return false;
10431  }
10432  break;
10433  }
10434 
10435  case token_type::value_string:
10436  {
10437  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10438  {
10439  return false;
10440  }
10441  break;
10442  }
10443 
10444  case token_type::value_unsigned:
10445  {
10446  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10447  {
10448  return false;
10449  }
10450  break;
10451  }
10452 
10453  case token_type::parse_error:
10454  {
10455  // using "uninitialized" to avoid "expected" message
10456  return sax->parse_error(m_lexer.get_position(),
10457  m_lexer.get_token_string(),
10458  parse_error::create(101, m_lexer.get_position(),
10459  exception_message(token_type::uninitialized, "value")));
10460  }
10461 
10462  default: // the last token was unexpected
10463  {
10464  return sax->parse_error(m_lexer.get_position(),
10465  m_lexer.get_token_string(),
10466  parse_error::create(101, m_lexer.get_position(),
10467  exception_message(token_type::literal_or_value, "value")));
10468  }
10469  }
10470  }
10471  else
10472  {
10473  skip_to_state_evaluation = false;
10474  }
10475 
10476  // we reached this line after we successfully parsed a value
10477  if (states.empty())
10478  {
10479  // empty stack: we reached the end of the hierarchy: done
10480  return true;
10481  }
10482 
10483  if (states.back()) // array
10484  {
10485  // comma -> next value
10486  if (get_token() == token_type::value_separator)
10487  {
10488  // parse a new value
10489  get_token();
10490  continue;
10491  }
10492 
10493  // closing ]
10494  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10495  {
10496  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10497  {
10498  return false;
10499  }
10500 
10501  // We are done with this array. Before we can parse a
10502  // new value, we need to evaluate the new state first.
10503  // By setting skip_to_state_evaluation to false, we
10504  // are effectively jumping to the beginning of this if.
10505  JSON_ASSERT(!states.empty());
10506  states.pop_back();
10507  skip_to_state_evaluation = true;
10508  continue;
10509  }
10510 
10511  return sax->parse_error(m_lexer.get_position(),
10512  m_lexer.get_token_string(),
10513  parse_error::create(101, m_lexer.get_position(),
10514  exception_message(token_type::end_array, "array")));
10515  }
10516  else // object
10517  {
10518  // comma -> next value
10519  if (get_token() == token_type::value_separator)
10520  {
10521  // parse key
10522  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10523  {
10524  return sax->parse_error(m_lexer.get_position(),
10525  m_lexer.get_token_string(),
10526  parse_error::create(101, m_lexer.get_position(),
10527  exception_message(token_type::value_string, "object key")));
10528  }
10529 
10530  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10531  {
10532  return false;
10533  }
10534 
10535  // parse separator (:)
10536  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10537  {
10538  return sax->parse_error(m_lexer.get_position(),
10539  m_lexer.get_token_string(),
10540  parse_error::create(101, m_lexer.get_position(),
10541  exception_message(token_type::name_separator, "object separator")));
10542  }
10543 
10544  // parse values
10545  get_token();
10546  continue;
10547  }
10548 
10549  // closing }
10550  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10551  {
10552  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10553  {
10554  return false;
10555  }
10556 
10557  // We are done with this object. Before we can parse a
10558  // new value, we need to evaluate the new state first.
10559  // By setting skip_to_state_evaluation to false, we
10560  // are effectively jumping to the beginning of this if.
10561  JSON_ASSERT(!states.empty());
10562  states.pop_back();
10563  skip_to_state_evaluation = true;
10564  continue;
10565  }
10566 
10567  return sax->parse_error(m_lexer.get_position(),
10568  m_lexer.get_token_string(),
10569  parse_error::create(101, m_lexer.get_position(),
10570  exception_message(token_type::end_object, "object")));
10571  }
10572  }
10573  }
10574 
10576  token_type get_token()
10577  {
10578  return last_token = m_lexer.scan();
10579  }
10580 
10581  std::string exception_message(const token_type expected, const std::string& context)
10582  {
10583  std::string error_msg = "syntax error ";
10584 
10585  if (!context.empty())
10586  {
10587  error_msg += "while parsing " + context + " ";
10588  }
10589 
10590  error_msg += "- ";
10591 
10592  if (last_token == token_type::parse_error)
10593  {
10594  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10595  m_lexer.get_token_string() + "'";
10596  }
10597  else
10598  {
10599  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10600  }
10601 
10602  if (expected != token_type::uninitialized)
10603  {
10604  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10605  }
10606 
10607  return error_msg;
10608  }
10609 
10610  private:
10612  const parser_callback_t<BasicJsonType> callback = nullptr;
10614  token_type last_token = token_type::uninitialized;
10616  lexer_t m_lexer;
10618  const bool allow_exceptions = true;
10619 };
10620 } // namespace detail
10621 } // namespace nlohmann
10622 
10623 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10624 
10625 
10626 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10627 
10628 
10629 #include <cstddef> // ptrdiff_t
10630 #include <limits> // numeric_limits
10631 
10632 namespace nlohmann
10633 {
10634 namespace detail
10635 {
10636 /*
10637 @brief an iterator for primitive JSON types
10638 
10639 This class models an iterator for primitive JSON types (boolean, number,
10640 string). It's only purpose is to allow the iterator/const_iterator classes
10641 to "iterate" over primitive values. Internally, the iterator is modeled by
10642 a `difference_type` variable. Value begin_value (`0`) models the begin,
10643 end_value (`1`) models past the end.
10644 */
10645 class primitive_iterator_t
10646 {
10647  private:
10648  using difference_type = std::ptrdiff_t;
10649  static constexpr difference_type begin_value = 0;
10650  static constexpr difference_type end_value = begin_value + 1;
10651 
10652  JSON_PRIVATE_UNLESS_TESTED:
10654  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10655 
10656  public:
10657  constexpr difference_type get_value() const noexcept
10658  {
10659  return m_it;
10660  }
10661 
10663  void set_begin() noexcept
10664  {
10665  m_it = begin_value;
10666  }
10667 
10669  void set_end() noexcept
10670  {
10671  m_it = end_value;
10672  }
10673 
10675  constexpr bool is_begin() const noexcept
10676  {
10677  return m_it == begin_value;
10678  }
10679 
10681  constexpr bool is_end() const noexcept
10682  {
10683  return m_it == end_value;
10684  }
10685 
10686  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10687  {
10688  return lhs.m_it == rhs.m_it;
10689  }
10690 
10691  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10692  {
10693  return lhs.m_it < rhs.m_it;
10694  }
10695 
10696  primitive_iterator_t operator+(difference_type n) noexcept
10697  {
10698  auto result = *this;
10699  result += n;
10700  return result;
10701  }
10702 
10703  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10704  {
10705  return lhs.m_it - rhs.m_it;
10706  }
10707 
10708  primitive_iterator_t& operator++() noexcept
10709  {
10710  ++m_it;
10711  return *this;
10712  }
10713 
10714  primitive_iterator_t const operator++(int) noexcept
10715  {
10716  auto result = *this;
10717  ++m_it;
10718  return result;
10719  }
10720 
10721  primitive_iterator_t& operator--() noexcept
10722  {
10723  --m_it;
10724  return *this;
10725  }
10726 
10727  primitive_iterator_t const operator--(int) noexcept
10728  {
10729  auto result = *this;
10730  --m_it;
10731  return result;
10732  }
10733 
10734  primitive_iterator_t& operator+=(difference_type n) noexcept
10735  {
10736  m_it += n;
10737  return *this;
10738  }
10739 
10740  primitive_iterator_t& operator-=(difference_type n) noexcept
10741  {
10742  m_it -= n;
10743  return *this;
10744  }
10745 };
10746 } // namespace detail
10747 } // namespace nlohmann
10748 
10749 
10750 namespace nlohmann
10751 {
10752 namespace detail
10753 {
10760 template<typename BasicJsonType> struct internal_iterator
10761 {
10763  typename BasicJsonType::object_t::iterator object_iterator {};
10765  typename BasicJsonType::array_t::iterator array_iterator {};
10767  primitive_iterator_t primitive_iterator {};
10768 };
10769 } // namespace detail
10770 } // namespace nlohmann
10771 
10772 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10773 
10774 
10775 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10776 #include <type_traits> // conditional, is_const, remove_const
10777 
10778 // #include <nlohmann/detail/exceptions.hpp>
10779 
10780 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10781 
10782 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10783 
10784 // #include <nlohmann/detail/macro_scope.hpp>
10785 
10786 // #include <nlohmann/detail/meta/cpp_future.hpp>
10787 
10788 // #include <nlohmann/detail/meta/type_traits.hpp>
10789 
10790 // #include <nlohmann/detail/value_t.hpp>
10791 
10792 
10793 namespace nlohmann
10794 {
10795 namespace detail
10796 {
10797 // forward declare, to be able to friend it later on
10798 template<typename IteratorType> class iteration_proxy;
10799 template<typename IteratorType> class iteration_proxy_value;
10800 
10817 template<typename BasicJsonType>
10818 class iter_impl
10819 {
10821  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10822  friend BasicJsonType;
10823  friend iteration_proxy<iter_impl>;
10824  friend iteration_proxy_value<iter_impl>;
10825 
10826  using object_t = typename BasicJsonType::object_t;
10827  using array_t = typename BasicJsonType::array_t;
10828  // make sure BasicJsonType is basic_json or const basic_json
10829  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10830  "iter_impl only accepts (const) basic_json");
10831 
10832  public:
10833 
10839  using iterator_category = std::bidirectional_iterator_tag;
10840 
10842  using value_type = typename BasicJsonType::value_type;
10844  using difference_type = typename BasicJsonType::difference_type;
10846  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10847  typename BasicJsonType::const_pointer,
10848  typename BasicJsonType::pointer>::type;
10850  using reference =
10851  typename std::conditional<std::is_const<BasicJsonType>::value,
10852  typename BasicJsonType::const_reference,
10853  typename BasicJsonType::reference>::type;
10854 
10856  iter_impl() = default;
10857 
10864  explicit iter_impl(pointer object) noexcept : m_object(object)
10865  {
10866  JSON_ASSERT(m_object != nullptr);
10867 
10868  switch (m_object->m_type)
10869  {
10870  case value_t::object:
10871  {
10872  m_it.object_iterator = typename object_t::iterator();
10873  break;
10874  }
10875 
10876  case value_t::array:
10877  {
10878  m_it.array_iterator = typename array_t::iterator();
10879  break;
10880  }
10881 
10882  default:
10883  {
10884  m_it.primitive_iterator = primitive_iterator_t();
10885  break;
10886  }
10887  }
10888  }
10889 
10906  iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10907  : m_object(other.m_object), m_it(other.m_it)
10908  {}
10909 
10916  iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10917  {
10918  m_object = other.m_object;
10919  m_it = other.m_it;
10920  return *this;
10921  }
10922 
10928  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10929  : m_object(other.m_object), m_it(other.m_it)
10930  {}
10931 
10938  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10939  {
10940  m_object = other.m_object;
10941  m_it = other.m_it;
10942  return *this;
10943  }
10944 
10945  JSON_PRIVATE_UNLESS_TESTED:
10950  void set_begin() noexcept
10951  {
10952  JSON_ASSERT(m_object != nullptr);
10953 
10954  switch (m_object->m_type)
10955  {
10956  case value_t::object:
10957  {
10958  m_it.object_iterator = m_object->m_value.object->begin();
10959  break;
10960  }
10961 
10962  case value_t::array:
10963  {
10964  m_it.array_iterator = m_object->m_value.array->begin();
10965  break;
10966  }
10967 
10968  case value_t::null:
10969  {
10970  // set to end so begin()==end() is true: null is empty
10971  m_it.primitive_iterator.set_end();
10972  break;
10973  }
10974 
10975  default:
10976  {
10977  m_it.primitive_iterator.set_begin();
10978  break;
10979  }
10980  }
10981  }
10982 
10987  void set_end() noexcept
10988  {
10989  JSON_ASSERT(m_object != nullptr);
10990 
10991  switch (m_object->m_type)
10992  {
10993  case value_t::object:
10994  {
10995  m_it.object_iterator = m_object->m_value.object->end();
10996  break;
10997  }
10998 
10999  case value_t::array:
11000  {
11001  m_it.array_iterator = m_object->m_value.array->end();
11002  break;
11003  }
11004 
11005  default:
11006  {
11007  m_it.primitive_iterator.set_end();
11008  break;
11009  }
11010  }
11011  }
11012 
11013  public:
11018  reference operator*() const
11019  {
11020  JSON_ASSERT(m_object != nullptr);
11021 
11022  switch (m_object->m_type)
11023  {
11024  case value_t::object:
11025  {
11026  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11027  return m_it.object_iterator->second;
11028  }
11029 
11030  case value_t::array:
11031  {
11032  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11033  return *m_it.array_iterator;
11034  }
11035 
11036  case value_t::null:
11037  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11038 
11039  default:
11040  {
11041  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11042  {
11043  return *m_object;
11044  }
11045 
11046  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11047  }
11048  }
11049  }
11050 
11055  pointer operator->() const
11056  {
11057  JSON_ASSERT(m_object != nullptr);
11058 
11059  switch (m_object->m_type)
11060  {
11061  case value_t::object:
11062  {
11063  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11064  return &(m_it.object_iterator->second);
11065  }
11066 
11067  case value_t::array:
11068  {
11069  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11070  return &*m_it.array_iterator;
11071  }
11072 
11073  default:
11074  {
11075  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11076  {
11077  return m_object;
11078  }
11079 
11080  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11081  }
11082  }
11083  }
11084 
11089  iter_impl const operator++(int)
11090  {
11091  auto result = *this;
11092  ++(*this);
11093  return result;
11094  }
11095 
11100  iter_impl& operator++()
11101  {
11102  JSON_ASSERT(m_object != nullptr);
11103 
11104  switch (m_object->m_type)
11105  {
11106  case value_t::object:
11107  {
11108  std::advance(m_it.object_iterator, 1);
11109  break;
11110  }
11111 
11112  case value_t::array:
11113  {
11114  std::advance(m_it.array_iterator, 1);
11115  break;
11116  }
11117 
11118  default:
11119  {
11120  ++m_it.primitive_iterator;
11121  break;
11122  }
11123  }
11124 
11125  return *this;
11126  }
11127 
11132  iter_impl const operator--(int)
11133  {
11134  auto result = *this;
11135  --(*this);
11136  return result;
11137  }
11138 
11143  iter_impl& operator--()
11144  {
11145  JSON_ASSERT(m_object != nullptr);
11146 
11147  switch (m_object->m_type)
11148  {
11149  case value_t::object:
11150  {
11151  std::advance(m_it.object_iterator, -1);
11152  break;
11153  }
11154 
11155  case value_t::array:
11156  {
11157  std::advance(m_it.array_iterator, -1);
11158  break;
11159  }
11160 
11161  default:
11162  {
11163  --m_it.primitive_iterator;
11164  break;
11165  }
11166  }
11167 
11168  return *this;
11169  }
11170 
11175  bool operator==(const iter_impl& other) const
11176  {
11177  // if objects are not the same, the comparison is undefined
11178  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11179  {
11180  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11181  }
11182 
11183  JSON_ASSERT(m_object != nullptr);
11184 
11185  switch (m_object->m_type)
11186  {
11187  case value_t::object:
11188  return (m_it.object_iterator == other.m_it.object_iterator);
11189 
11190  case value_t::array:
11191  return (m_it.array_iterator == other.m_it.array_iterator);
11192 
11193  default:
11194  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11195  }
11196  }
11197 
11202  bool operator!=(const iter_impl& other) const
11203  {
11204  return !operator==(other);
11205  }
11206 
11211  bool operator<(const iter_impl& other) const
11212  {
11213  // if objects are not the same, the comparison is undefined
11214  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11215  {
11216  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11217  }
11218 
11219  JSON_ASSERT(m_object != nullptr);
11220 
11221  switch (m_object->m_type)
11222  {
11223  case value_t::object:
11224  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11225 
11226  case value_t::array:
11227  return (m_it.array_iterator < other.m_it.array_iterator);
11228 
11229  default:
11230  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11231  }
11232  }
11233 
11238  bool operator<=(const iter_impl& other) const
11239  {
11240  return !other.operator < (*this);
11241  }
11242 
11247  bool operator>(const iter_impl& other) const
11248  {
11249  return !operator<=(other);
11250  }
11251 
11256  bool operator>=(const iter_impl& other) const
11257  {
11258  return !operator<(other);
11259  }
11260 
11265  iter_impl& operator+=(difference_type i)
11266  {
11267  JSON_ASSERT(m_object != nullptr);
11268 
11269  switch (m_object->m_type)
11270  {
11271  case value_t::object:
11272  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11273 
11274  case value_t::array:
11275  {
11276  std::advance(m_it.array_iterator, i);
11277  break;
11278  }
11279 
11280  default:
11281  {
11282  m_it.primitive_iterator += i;
11283  break;
11284  }
11285  }
11286 
11287  return *this;
11288  }
11289 
11294  iter_impl& operator-=(difference_type i)
11295  {
11296  return operator+=(-i);
11297  }
11298 
11303  iter_impl operator+(difference_type i) const
11304  {
11305  auto result = *this;
11306  result += i;
11307  return result;
11308  }
11309 
11314  friend iter_impl operator+(difference_type i, const iter_impl& it)
11315  {
11316  auto result = it;
11317  result += i;
11318  return result;
11319  }
11320 
11325  iter_impl operator-(difference_type i) const
11326  {
11327  auto result = *this;
11328  result -= i;
11329  return result;
11330  }
11331 
11336  difference_type operator-(const iter_impl& other) const
11337  {
11338  JSON_ASSERT(m_object != nullptr);
11339 
11340  switch (m_object->m_type)
11341  {
11342  case value_t::object:
11343  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11344 
11345  case value_t::array:
11346  return m_it.array_iterator - other.m_it.array_iterator;
11347 
11348  default:
11349  return m_it.primitive_iterator - other.m_it.primitive_iterator;
11350  }
11351  }
11352 
11357  reference operator[](difference_type n) const
11358  {
11359  JSON_ASSERT(m_object != nullptr);
11360 
11361  switch (m_object->m_type)
11362  {
11363  case value_t::object:
11364  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11365 
11366  case value_t::array:
11367  return *std::next(m_it.array_iterator, n);
11368 
11369  case value_t::null:
11370  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11371 
11372  default:
11373  {
11374  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11375  {
11376  return *m_object;
11377  }
11378 
11379  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11380  }
11381  }
11382  }
11383 
11388  const typename object_t::key_type& key() const
11389  {
11390  JSON_ASSERT(m_object != nullptr);
11391 
11392  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11393  {
11394  return m_it.object_iterator->first;
11395  }
11396 
11397  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11398  }
11399 
11404  reference value() const
11405  {
11406  return operator*();
11407  }
11408 
11409  JSON_PRIVATE_UNLESS_TESTED:
11411  pointer m_object = nullptr;
11413  internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11414 };
11415 } // namespace detail
11416 } // namespace nlohmann
11417 
11418 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11419 
11420 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11421 
11422 
11423 #include <cstddef> // ptrdiff_t
11424 #include <iterator> // reverse_iterator
11425 #include <utility> // declval
11426 
11427 namespace nlohmann
11428 {
11429 namespace detail
11430 {
11432 // reverse_iterator //
11434 
11453 template<typename Base>
11454 class json_reverse_iterator : public std::reverse_iterator<Base>
11455 {
11456  public:
11457  using difference_type = std::ptrdiff_t;
11459  using base_iterator = std::reverse_iterator<Base>;
11461  using reference = typename Base::reference;
11462 
11464  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11465  : base_iterator(it) {}
11466 
11468  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11469 
11471  json_reverse_iterator const operator++(int)
11472  {
11473  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11474  }
11475 
11477  json_reverse_iterator& operator++()
11478  {
11479  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11480  }
11481 
11483  json_reverse_iterator const operator--(int)
11484  {
11485  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11486  }
11487 
11489  json_reverse_iterator& operator--()
11490  {
11491  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11492  }
11493 
11495  json_reverse_iterator& operator+=(difference_type i)
11496  {
11497  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11498  }
11499 
11501  json_reverse_iterator operator+(difference_type i) const
11502  {
11503  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11504  }
11505 
11507  json_reverse_iterator operator-(difference_type i) const
11508  {
11509  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11510  }
11511 
11513  difference_type operator-(const json_reverse_iterator& other) const
11514  {
11515  return base_iterator(*this) - base_iterator(other);
11516  }
11517 
11519  reference operator[](difference_type n) const
11520  {
11521  return *(this->operator+(n));
11522  }
11523 
11525  auto key() const -> decltype(std::declval<Base>().key())
11526  {
11527  auto it = --this->base();
11528  return it.key();
11529  }
11530 
11532  reference value() const
11533  {
11534  auto it = --this->base();
11535  return it.operator * ();
11536  }
11537 };
11538 } // namespace detail
11539 } // namespace nlohmann
11540 
11541 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11542 
11543 // #include <nlohmann/detail/json_pointer.hpp>
11544 
11545 
11546 #include <algorithm> // all_of
11547 #include <cctype> // isdigit
11548 #include <limits> // max
11549 #include <numeric> // accumulate
11550 #include <string> // string
11551 #include <utility> // move
11552 #include <vector> // vector
11553 
11554 // #include <nlohmann/detail/exceptions.hpp>
11555 
11556 // #include <nlohmann/detail/macro_scope.hpp>
11557 
11558 // #include <nlohmann/detail/value_t.hpp>
11559 
11560 
11561 namespace nlohmann
11562 {
11563 template<typename BasicJsonType>
11565 {
11566  // allow basic_json to access private members
11567  NLOHMANN_BASIC_JSON_TPL_DECLARATION
11568  friend class basic_json;
11569 
11570  public:
11592  explicit json_pointer(const std::string& s = "")
11593  : reference_tokens(split(s))
11594  {}
11595 
11610  std::string to_string() const
11611  {
11612  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11613  std::string{},
11614  [](const std::string & a, const std::string & b)
11615  {
11616  return a + "/" + escape(b);
11617  });
11618  }
11619 
11621  operator std::string() const
11622  {
11623  return to_string();
11624  }
11625 
11643  {
11644  reference_tokens.insert(reference_tokens.end(),
11645  ptr.reference_tokens.begin(),
11646  ptr.reference_tokens.end());
11647  return *this;
11648  }
11649 
11666  json_pointer& operator/=(std::string token)
11667  {
11668  push_back(std::move(token));
11669  return *this;
11670  }
11671 
11688  json_pointer& operator/=(std::size_t array_idx)
11689  {
11690  return *this /= std::to_string(array_idx);
11691  }
11692 
11709  const json_pointer& rhs)
11710  {
11711  return json_pointer(lhs) /= rhs;
11712  }
11713 
11729  friend json_pointer operator/(const json_pointer& ptr, std::string token)
11730  {
11731  return json_pointer(ptr) /= std::move(token);
11732  }
11733 
11749  friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11750  {
11751  return json_pointer(ptr) /= array_idx;
11752  }
11753 
11768  {
11769  if (empty())
11770  {
11771  return *this;
11772  }
11773 
11774  json_pointer res = *this;
11775  res.pop_back();
11776  return res;
11777  }
11778 
11792  void pop_back()
11793  {
11794  if (JSON_HEDLEY_UNLIKELY(empty()))
11795  {
11796  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11797  }
11798 
11799  reference_tokens.pop_back();
11800  }
11801 
11816  const std::string& back() const
11817  {
11818  if (JSON_HEDLEY_UNLIKELY(empty()))
11819  {
11820  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11821  }
11822 
11823  return reference_tokens.back();
11824  }
11825 
11838  void push_back(const std::string& token)
11839  {
11840  reference_tokens.push_back(token);
11841  }
11842 
11844  void push_back(std::string&& token)
11845  {
11846  reference_tokens.push_back(std::move(token));
11847  }
11848 
11863  bool empty() const noexcept
11864  {
11865  return reference_tokens.empty();
11866  }
11867 
11868  private:
11879  static typename BasicJsonType::size_type array_index(const std::string& s)
11880  {
11881  using size_type = typename BasicJsonType::size_type;
11882 
11883  // error condition (cf. RFC 6901, Sect. 4)
11884  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11885  {
11886  JSON_THROW(detail::parse_error::create(106, 0,
11887  "array index '" + s +
11888  "' must not begin with '0'"));
11889  }
11890 
11891  // error condition (cf. RFC 6901, Sect. 4)
11892  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11893  {
11894  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11895  }
11896 
11897  std::size_t processed_chars = 0;
11898  unsigned long long res = 0;
11899  JSON_TRY
11900  {
11901  res = std::stoull(s, &processed_chars);
11902  }
11903  JSON_CATCH(std::out_of_range&)
11904  {
11905  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11906  }
11907 
11908  // check if the string was completely read
11909  if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11910  {
11911  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11912  }
11913 
11914  // only triggered on special platforms (like 32bit), see also
11915  // https://github.com/nlohmann/json/pull/2203
11916  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11917  {
11918  JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11919  }
11920 
11921  return static_cast<size_type>(res);
11922  }
11923 
11924  JSON_PRIVATE_UNLESS_TESTED:
11925  json_pointer top() const
11926  {
11927  if (JSON_HEDLEY_UNLIKELY(empty()))
11928  {
11929  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11930  }
11931 
11932  json_pointer result = *this;
11933  result.reference_tokens = {reference_tokens[0]};
11934  return result;
11935  }
11936 
11937  private:
11946  BasicJsonType& get_and_create(BasicJsonType& j) const
11947  {
11948  auto result = &j;
11949 
11950  // in case no reference tokens exist, return a reference to the JSON value
11951  // j which will be overwritten by a primitive value
11952  for (const auto& reference_token : reference_tokens)
11953  {
11954  switch (result->type())
11955  {
11956  case detail::value_t::null:
11957  {
11958  if (reference_token == "0")
11959  {
11960  // start a new array if reference token is 0
11961  result = &result->operator[](0);
11962  }
11963  else
11964  {
11965  // start a new object otherwise
11966  result = &result->operator[](reference_token);
11967  }
11968  break;
11969  }
11970 
11971  case detail::value_t::object:
11972  {
11973  // create an entry in the object
11974  result = &result->operator[](reference_token);
11975  break;
11976  }
11977 
11978  case detail::value_t::array:
11979  {
11980  // create an entry in the array
11981  result = &result->operator[](array_index(reference_token));
11982  break;
11983  }
11984 
11985  /*
11986  The following code is only reached if there exists a reference
11987  token _and_ the current value is primitive. In this case, we have
11988  an error situation, because primitive values may only occur as
11989  single value; that is, with an empty list of reference tokens.
11990  */
11991  default:
11992  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11993  }
11994  }
11995 
11996  return *result;
11997  }
11998 
12018  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12019  {
12020  for (const auto& reference_token : reference_tokens)
12021  {
12022  // convert null values to arrays or objects before continuing
12023  if (ptr->is_null())
12024  {
12025  // check if reference token is a number
12026  const bool nums =
12027  std::all_of(reference_token.begin(), reference_token.end(),
12028  [](const unsigned char x)
12029  {
12030  return std::isdigit(x);
12031  });
12032 
12033  // change value to array for numbers or "-" or to object otherwise
12034  *ptr = (nums || reference_token == "-")
12035  ? detail::value_t::array
12036  : detail::value_t::object;
12037  }
12038 
12039  switch (ptr->type())
12040  {
12041  case detail::value_t::object:
12042  {
12043  // use unchecked object access
12044  ptr = &ptr->operator[](reference_token);
12045  break;
12046  }
12047 
12048  case detail::value_t::array:
12049  {
12050  if (reference_token == "-")
12051  {
12052  // explicitly treat "-" as index beyond the end
12053  ptr = &ptr->operator[](ptr->m_value.array->size());
12054  }
12055  else
12056  {
12057  // convert array index to number; unchecked access
12058  ptr = &ptr->operator[](array_index(reference_token));
12059  }
12060  break;
12061  }
12062 
12063  default:
12064  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12065  }
12066  }
12067 
12068  return *ptr;
12069  }
12070 
12077  BasicJsonType& get_checked(BasicJsonType* ptr) const
12078  {
12079  for (const auto& reference_token : reference_tokens)
12080  {
12081  switch (ptr->type())
12082  {
12083  case detail::value_t::object:
12084  {
12085  // note: at performs range check
12086  ptr = &ptr->at(reference_token);
12087  break;
12088  }
12089 
12090  case detail::value_t::array:
12091  {
12092  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12093  {
12094  // "-" always fails the range check
12095  JSON_THROW(detail::out_of_range::create(402,
12096  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12097  ") is out of range"));
12098  }
12099 
12100  // note: at performs range check
12101  ptr = &ptr->at(array_index(reference_token));
12102  break;
12103  }
12104 
12105  default:
12106  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12107  }
12108  }
12109 
12110  return *ptr;
12111  }
12112 
12126  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12127  {
12128  for (const auto& reference_token : reference_tokens)
12129  {
12130  switch (ptr->type())
12131  {
12132  case detail::value_t::object:
12133  {
12134  // use unchecked object access
12135  ptr = &ptr->operator[](reference_token);
12136  break;
12137  }
12138 
12139  case detail::value_t::array:
12140  {
12141  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12142  {
12143  // "-" cannot be used for const access
12144  JSON_THROW(detail::out_of_range::create(402,
12145  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12146  ") is out of range"));
12147  }
12148 
12149  // use unchecked array access
12150  ptr = &ptr->operator[](array_index(reference_token));
12151  break;
12152  }
12153 
12154  default:
12155  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12156  }
12157  }
12158 
12159  return *ptr;
12160  }
12161 
12168  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12169  {
12170  for (const auto& reference_token : reference_tokens)
12171  {
12172  switch (ptr->type())
12173  {
12174  case detail::value_t::object:
12175  {
12176  // note: at performs range check
12177  ptr = &ptr->at(reference_token);
12178  break;
12179  }
12180 
12181  case detail::value_t::array:
12182  {
12183  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12184  {
12185  // "-" always fails the range check
12186  JSON_THROW(detail::out_of_range::create(402,
12187  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12188  ") is out of range"));
12189  }
12190 
12191  // note: at performs range check
12192  ptr = &ptr->at(array_index(reference_token));
12193  break;
12194  }
12195 
12196  default:
12197  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12198  }
12199  }
12200 
12201  return *ptr;
12202  }
12203 
12208  bool contains(const BasicJsonType* ptr) const
12209  {
12210  for (const auto& reference_token : reference_tokens)
12211  {
12212  switch (ptr->type())
12213  {
12214  case detail::value_t::object:
12215  {
12216  if (!ptr->contains(reference_token))
12217  {
12218  // we did not find the key in the object
12219  return false;
12220  }
12221 
12222  ptr = &ptr->operator[](reference_token);
12223  break;
12224  }
12225 
12226  case detail::value_t::array:
12227  {
12228  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12229  {
12230  // "-" always fails the range check
12231  return false;
12232  }
12233  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12234  {
12235  // invalid char
12236  return false;
12237  }
12238  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12239  {
12240  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12241  {
12242  // first char should be between '1' and '9'
12243  return false;
12244  }
12245  for (std::size_t i = 1; i < reference_token.size(); i++)
12246  {
12247  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12248  {
12249  // other char should be between '0' and '9'
12250  return false;
12251  }
12252  }
12253  }
12254 
12255  const auto idx = array_index(reference_token);
12256  if (idx >= ptr->size())
12257  {
12258  // index out of range
12259  return false;
12260  }
12261 
12262  ptr = &ptr->operator[](idx);
12263  break;
12264  }
12265 
12266  default:
12267  {
12268  // we do not expect primitive values if there is still a
12269  // reference token to process
12270  return false;
12271  }
12272  }
12273  }
12274 
12275  // no reference token left means we found a primitive value
12276  return true;
12277  }
12278 
12288  static std::vector<std::string> split(const std::string& reference_string)
12289  {
12290  std::vector<std::string> result;
12291 
12292  // special case: empty reference string -> no reference tokens
12293  if (reference_string.empty())
12294  {
12295  return result;
12296  }
12297 
12298  // check if nonempty reference string begins with slash
12299  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12300  {
12301  JSON_THROW(detail::parse_error::create(107, 1,
12302  "JSON pointer must be empty or begin with '/' - was: '" +
12303  reference_string + "'"));
12304  }
12305 
12306  // extract the reference tokens:
12307  // - slash: position of the last read slash (or end of string)
12308  // - start: position after the previous slash
12309  for (
12310  // search for the first slash after the first character
12311  std::size_t slash = reference_string.find_first_of('/', 1),
12312  // set the beginning of the first reference token
12313  start = 1;
12314  // we can stop if start == 0 (if slash == std::string::npos)
12315  start != 0;
12316  // set the beginning of the next reference token
12317  // (will eventually be 0 if slash == std::string::npos)
12318  start = (slash == std::string::npos) ? 0 : slash + 1,
12319  // find next slash
12320  slash = reference_string.find_first_of('/', start))
12321  {
12322  // use the text between the beginning of the reference token
12323  // (start) and the last slash (slash).
12324  auto reference_token = reference_string.substr(start, slash - start);
12325 
12326  // check reference tokens are properly escaped
12327  for (std::size_t pos = reference_token.find_first_of('~');
12328  pos != std::string::npos;
12329  pos = reference_token.find_first_of('~', pos + 1))
12330  {
12331  JSON_ASSERT(reference_token[pos] == '~');
12332 
12333  // ~ must be followed by 0 or 1
12334  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12335  (reference_token[pos + 1] != '0' &&
12336  reference_token[pos + 1] != '1')))
12337  {
12338  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12339  }
12340  }
12341 
12342  // finally, store the reference token
12343  unescape(reference_token);
12344  result.push_back(reference_token);
12345  }
12346 
12347  return result;
12348  }
12349 
12363  static void replace_substring(std::string& s, const std::string& f,
12364  const std::string& t)
12365  {
12366  JSON_ASSERT(!f.empty());
12367  for (auto pos = s.find(f); // find first occurrence of f
12368  pos != std::string::npos; // make sure f was found
12369  s.replace(pos, f.size(), t), // replace with t, and
12370  pos = s.find(f, pos + t.size())) // find next occurrence of f
12371  {}
12372  }
12373 
12374  JSON_PRIVATE_UNLESS_TESTED:
12376  static std::string escape(std::string s)
12377  {
12378  replace_substring(s, "~", "~0");
12379  replace_substring(s, "/", "~1");
12380  return s;
12381  }
12382 
12384  static void unescape(std::string& s)
12385  {
12386  replace_substring(s, "~1", "/");
12387  replace_substring(s, "~0", "~");
12388  }
12389 
12390  private:
12398  static void flatten(const std::string& reference_string,
12399  const BasicJsonType& value,
12400  BasicJsonType& result)
12401  {
12402  switch (value.type())
12403  {
12404  case detail::value_t::array:
12405  {
12406  if (value.m_value.array->empty())
12407  {
12408  // flatten empty array as null
12409  result[reference_string] = nullptr;
12410  }
12411  else
12412  {
12413  // iterate array and use index as reference string
12414  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12415  {
12416  flatten(reference_string + "/" + std::to_string(i),
12417  value.m_value.array->operator[](i), result);
12418  }
12419  }
12420  break;
12421  }
12422 
12423  case detail::value_t::object:
12424  {
12425  if (value.m_value.object->empty())
12426  {
12427  // flatten empty object as null
12428  result[reference_string] = nullptr;
12429  }
12430  else
12431  {
12432  // iterate object and use keys as reference string
12433  for (const auto& element : *value.m_value.object)
12434  {
12435  flatten(reference_string + "/" + escape(element.first), element.second, result);
12436  }
12437  }
12438  break;
12439  }
12440 
12441  default:
12442  {
12443  // add primitive value with its reference string
12444  result[reference_string] = value;
12445  break;
12446  }
12447  }
12448  }
12449 
12460  static BasicJsonType
12461  unflatten(const BasicJsonType& value)
12462  {
12463  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12464  {
12465  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12466  }
12467 
12468  BasicJsonType result;
12469 
12470  // iterate the JSON object values
12471  for (const auto& element : *value.m_value.object)
12472  {
12473  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12474  {
12475  JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12476  }
12477 
12478  // assign value to reference pointed to by JSON pointer; Note that if
12479  // the JSON pointer is "" (i.e., points to the whole value), function
12480  // get_and_create returns a reference to result itself. An assignment
12481  // will then create a primitive value.
12482  json_pointer(element.first).get_and_create(result) = element.second;
12483  }
12484 
12485  return result;
12486  }
12487 
12499  friend bool operator==(json_pointer const& lhs,
12500  json_pointer const& rhs) noexcept
12501  {
12502  return lhs.reference_tokens == rhs.reference_tokens;
12503  }
12504 
12516  friend bool operator!=(json_pointer const& lhs,
12517  json_pointer const& rhs) noexcept
12518  {
12519  return !(lhs == rhs);
12520  }
12521 
12523  std::vector<std::string> reference_tokens;
12524 };
12525 } // namespace nlohmann
12526 
12527 // #include <nlohmann/detail/json_ref.hpp>
12528 
12529 
12530 #include <initializer_list>
12531 #include <utility>
12532 
12533 // #include <nlohmann/detail/meta/type_traits.hpp>
12534 
12535 
12536 namespace nlohmann
12537 {
12538 namespace detail
12539 {
12540 template<typename BasicJsonType>
12541 class json_ref
12542 {
12543  public:
12544  using value_type = BasicJsonType;
12545 
12546  json_ref(value_type&& value)
12547  : owned_value(std::move(value))
12548  , value_ref(&owned_value)
12549  , is_rvalue(true)
12550  {}
12551 
12552  json_ref(const value_type& value)
12553  : value_ref(const_cast<value_type*>(&value))
12554  , is_rvalue(false)
12555  {}
12556 
12557  json_ref(std::initializer_list<json_ref> init)
12558  : owned_value(init)
12559  , value_ref(&owned_value)
12560  , is_rvalue(true)
12561  {}
12562 
12563  template <
12564  class... Args,
12565  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12566  json_ref(Args && ... args)
12567  : owned_value(std::forward<Args>(args)...)
12568  , value_ref(&owned_value)
12569  , is_rvalue(true)
12570  {}
12571 
12572  // class should be movable only
12573  json_ref(json_ref&&) = default;
12574  json_ref(const json_ref&) = delete;
12575  json_ref& operator=(const json_ref&) = delete;
12576  json_ref& operator=(json_ref&&) = delete;
12577  ~json_ref() = default;
12578 
12579  value_type moved_or_copied() const
12580  {
12581  if (is_rvalue)
12582  {
12583  return std::move(*value_ref);
12584  }
12585  return *value_ref;
12586  }
12587 
12588  value_type const& operator*() const
12589  {
12590  return *static_cast<value_type const*>(value_ref);
12591  }
12592 
12593  value_type const* operator->() const
12594  {
12595  return static_cast<value_type const*>(value_ref);
12596  }
12597 
12598  private:
12599  mutable value_type owned_value = nullptr;
12600  value_type* value_ref = nullptr;
12601  const bool is_rvalue = true;
12602 };
12603 } // namespace detail
12604 } // namespace nlohmann
12605 
12606 // #include <nlohmann/detail/macro_scope.hpp>
12607 
12608 // #include <nlohmann/detail/meta/cpp_future.hpp>
12609 
12610 // #include <nlohmann/detail/meta/type_traits.hpp>
12611 
12612 // #include <nlohmann/detail/output/binary_writer.hpp>
12613 
12614 
12615 #include <algorithm> // reverse
12616 #include <array> // array
12617 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12618 #include <cstring> // memcpy
12619 #include <limits> // numeric_limits
12620 #include <string> // string
12621 #include <cmath> // isnan, isinf
12622 
12623 // #include <nlohmann/detail/input/binary_reader.hpp>
12624 
12625 // #include <nlohmann/detail/macro_scope.hpp>
12626 
12627 // #include <nlohmann/detail/output/output_adapters.hpp>
12628 
12629 
12630 #include <algorithm> // copy
12631 #include <cstddef> // size_t
12632 #include <ios> // streamsize
12633 #include <iterator> // back_inserter
12634 #include <memory> // shared_ptr, make_shared
12635 #include <ostream> // basic_ostream
12636 #include <string> // basic_string
12637 #include <vector> // vector
12638 // #include <nlohmann/detail/macro_scope.hpp>
12639 
12640 
12641 namespace nlohmann
12642 {
12643 namespace detail
12644 {
12646 template<typename CharType> struct output_adapter_protocol
12647 {
12648  virtual void write_character(CharType c) = 0;
12649  virtual void write_characters(const CharType* s, std::size_t length) = 0;
12650  virtual ~output_adapter_protocol() = default;
12651 };
12652 
12654 template<typename CharType>
12655 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12656 
12658 template<typename CharType>
12659 class output_vector_adapter : public output_adapter_protocol<CharType>
12660 {
12661  public:
12662  explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12663  : v(vec)
12664  {}
12665 
12666  void write_character(CharType c) override
12667  {
12668  v.push_back(c);
12669  }
12670 
12671  JSON_HEDLEY_NON_NULL(2)
12672  void write_characters(const CharType* s, std::size_t length) override
12673  {
12674  std::copy(s, s + length, std::back_inserter(v));
12675  }
12676 
12677  private:
12678  std::vector<CharType>& v;
12679 };
12680 
12682 template<typename CharType>
12683 class output_stream_adapter : public output_adapter_protocol<CharType>
12684 {
12685  public:
12686  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12687  : stream(s)
12688  {}
12689 
12690  void write_character(CharType c) override
12691  {
12692  stream.put(c);
12693  }
12694 
12695  JSON_HEDLEY_NON_NULL(2)
12696  void write_characters(const CharType* s, std::size_t length) override
12697  {
12698  stream.write(s, static_cast<std::streamsize>(length));
12699  }
12700 
12701  private:
12702  std::basic_ostream<CharType>& stream;
12703 };
12704 
12706 template<typename CharType, typename StringType = std::basic_string<CharType>>
12707 class output_string_adapter : public output_adapter_protocol<CharType>
12708 {
12709  public:
12710  explicit output_string_adapter(StringType& s) noexcept
12711  : str(s)
12712  {}
12713 
12714  void write_character(CharType c) override
12715  {
12716  str.push_back(c);
12717  }
12718 
12719  JSON_HEDLEY_NON_NULL(2)
12720  void write_characters(const CharType* s, std::size_t length) override
12721  {
12722  str.append(s, length);
12723  }
12724 
12725  private:
12726  StringType& str;
12727 };
12728 
12729 template<typename CharType, typename StringType = std::basic_string<CharType>>
12730 class output_adapter
12731 {
12732  public:
12733  output_adapter(std::vector<CharType>& vec)
12734  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12735 
12736  output_adapter(std::basic_ostream<CharType>& s)
12737  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12738 
12739  output_adapter(StringType& s)
12740  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12741 
12742  operator output_adapter_t<CharType>()
12743  {
12744  return oa;
12745  }
12746 
12747  private:
12748  output_adapter_t<CharType> oa = nullptr;
12749 };
12750 } // namespace detail
12751 } // namespace nlohmann
12752 
12753 
12754 namespace nlohmann
12755 {
12756 namespace detail
12757 {
12759 // binary writer //
12761 
12765 template<typename BasicJsonType, typename CharType>
12766 class binary_writer
12767 {
12768  using string_t = typename BasicJsonType::string_t;
12769  using binary_t = typename BasicJsonType::binary_t;
12770  using number_float_t = typename BasicJsonType::number_float_t;
12771 
12772  public:
12778  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12779  {
12780  JSON_ASSERT(oa);
12781  }
12782 
12787  void write_bson(const BasicJsonType& j)
12788  {
12789  switch (j.type())
12790  {
12791  case value_t::object:
12792  {
12793  write_bson_object(*j.m_value.object);
12794  break;
12795  }
12796 
12797  default:
12798  {
12799  JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12800  }
12801  }
12802  }
12803 
12807  void write_cbor(const BasicJsonType& j)
12808  {
12809  switch (j.type())
12810  {
12811  case value_t::null:
12812  {
12813  oa->write_character(to_char_type(0xF6));
12814  break;
12815  }
12816 
12817  case value_t::boolean:
12818  {
12819  oa->write_character(j.m_value.boolean
12820  ? to_char_type(0xF5)
12821  : to_char_type(0xF4));
12822  break;
12823  }
12824 
12825  case value_t::number_integer:
12826  {
12827  if (j.m_value.number_integer >= 0)
12828  {
12829  // CBOR does not differentiate between positive signed
12830  // integers and unsigned integers. Therefore, we used the
12831  // code from the value_t::number_unsigned case here.
12832  if (j.m_value.number_integer <= 0x17)
12833  {
12834  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12835  }
12836  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12837  {
12838  oa->write_character(to_char_type(0x18));
12839  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12840  }
12841  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12842  {
12843  oa->write_character(to_char_type(0x19));
12844  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12845  }
12846  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12847  {
12848  oa->write_character(to_char_type(0x1A));
12849  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12850  }
12851  else
12852  {
12853  oa->write_character(to_char_type(0x1B));
12854  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12855  }
12856  }
12857  else
12858  {
12859  // The conversions below encode the sign in the first
12860  // byte, and the value is converted to a positive number.
12861  const auto positive_number = -1 - j.m_value.number_integer;
12862  if (j.m_value.number_integer >= -24)
12863  {
12864  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12865  }
12866  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12867  {
12868  oa->write_character(to_char_type(0x38));
12869  write_number(static_cast<std::uint8_t>(positive_number));
12870  }
12871  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12872  {
12873  oa->write_character(to_char_type(0x39));
12874  write_number(static_cast<std::uint16_t>(positive_number));
12875  }
12876  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12877  {
12878  oa->write_character(to_char_type(0x3A));
12879  write_number(static_cast<std::uint32_t>(positive_number));
12880  }
12881  else
12882  {
12883  oa->write_character(to_char_type(0x3B));
12884  write_number(static_cast<std::uint64_t>(positive_number));
12885  }
12886  }
12887  break;
12888  }
12889 
12890  case value_t::number_unsigned:
12891  {
12892  if (j.m_value.number_unsigned <= 0x17)
12893  {
12894  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12895  }
12896  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12897  {
12898  oa->write_character(to_char_type(0x18));
12899  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12900  }
12901  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12902  {
12903  oa->write_character(to_char_type(0x19));
12904  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12905  }
12906  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12907  {
12908  oa->write_character(to_char_type(0x1A));
12909  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12910  }
12911  else
12912  {
12913  oa->write_character(to_char_type(0x1B));
12914  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12915  }
12916  break;
12917  }
12918 
12919  case value_t::number_float:
12920  {
12921  if (std::isnan(j.m_value.number_float))
12922  {
12923  // NaN is 0xf97e00 in CBOR
12924  oa->write_character(to_char_type(0xF9));
12925  oa->write_character(to_char_type(0x7E));
12926  oa->write_character(to_char_type(0x00));
12927  }
12928  else if (std::isinf(j.m_value.number_float))
12929  {
12930  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12931  oa->write_character(to_char_type(0xf9));
12932  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12933  oa->write_character(to_char_type(0x00));
12934  }
12935  else
12936  {
12937  write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12938  }
12939  break;
12940  }
12941 
12942  case value_t::string:
12943  {
12944  // step 1: write control byte and the string length
12945  const auto N = j.m_value.string->size();
12946  if (N <= 0x17)
12947  {
12948  write_number(static_cast<std::uint8_t>(0x60 + N));
12949  }
12950  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12951  {
12952  oa->write_character(to_char_type(0x78));
12953  write_number(static_cast<std::uint8_t>(N));
12954  }
12955  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12956  {
12957  oa->write_character(to_char_type(0x79));
12958  write_number(static_cast<std::uint16_t>(N));
12959  }
12960  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12961  {
12962  oa->write_character(to_char_type(0x7A));
12963  write_number(static_cast<std::uint32_t>(N));
12964  }
12965  // LCOV_EXCL_START
12966  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12967  {
12968  oa->write_character(to_char_type(0x7B));
12969  write_number(static_cast<std::uint64_t>(N));
12970  }
12971  // LCOV_EXCL_STOP
12972 
12973  // step 2: write the string
12974  oa->write_characters(
12975  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12976  j.m_value.string->size());
12977  break;
12978  }
12979 
12980  case value_t::array:
12981  {
12982  // step 1: write control byte and the array size
12983  const auto N = j.m_value.array->size();
12984  if (N <= 0x17)
12985  {
12986  write_number(static_cast<std::uint8_t>(0x80 + N));
12987  }
12988  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12989  {
12990  oa->write_character(to_char_type(0x98));
12991  write_number(static_cast<std::uint8_t>(N));
12992  }
12993  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12994  {
12995  oa->write_character(to_char_type(0x99));
12996  write_number(static_cast<std::uint16_t>(N));
12997  }
12998  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12999  {
13000  oa->write_character(to_char_type(0x9A));
13001  write_number(static_cast<std::uint32_t>(N));
13002  }
13003  // LCOV_EXCL_START
13004  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13005  {
13006  oa->write_character(to_char_type(0x9B));
13007  write_number(static_cast<std::uint64_t>(N));
13008  }
13009  // LCOV_EXCL_STOP
13010 
13011  // step 2: write each element
13012  for (const auto& el : *j.m_value.array)
13013  {
13014  write_cbor(el);
13015  }
13016  break;
13017  }
13018 
13019  case value_t::binary:
13020  {
13021  if (j.m_value.binary->has_subtype())
13022  {
13023  write_number(static_cast<std::uint8_t>(0xd8));
13024  write_number(j.m_value.binary->subtype());
13025  }
13026 
13027  // step 1: write control byte and the binary array size
13028  const auto N = j.m_value.binary->size();
13029  if (N <= 0x17)
13030  {
13031  write_number(static_cast<std::uint8_t>(0x40 + N));
13032  }
13033  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13034  {
13035  oa->write_character(to_char_type(0x58));
13036  write_number(static_cast<std::uint8_t>(N));
13037  }
13038  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13039  {
13040  oa->write_character(to_char_type(0x59));
13041  write_number(static_cast<std::uint16_t>(N));
13042  }
13043  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13044  {
13045  oa->write_character(to_char_type(0x5A));
13046  write_number(static_cast<std::uint32_t>(N));
13047  }
13048  // LCOV_EXCL_START
13049  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13050  {
13051  oa->write_character(to_char_type(0x5B));
13052  write_number(static_cast<std::uint64_t>(N));
13053  }
13054  // LCOV_EXCL_STOP
13055 
13056  // step 2: write each element
13057  oa->write_characters(
13058  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13059  N);
13060 
13061  break;
13062  }
13063 
13064  case value_t::object:
13065  {
13066  // step 1: write control byte and the object size
13067  const auto N = j.m_value.object->size();
13068  if (N <= 0x17)
13069  {
13070  write_number(static_cast<std::uint8_t>(0xA0 + N));
13071  }
13072  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13073  {
13074  oa->write_character(to_char_type(0xB8));
13075  write_number(static_cast<std::uint8_t>(N));
13076  }
13077  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13078  {
13079  oa->write_character(to_char_type(0xB9));
13080  write_number(static_cast<std::uint16_t>(N));
13081  }
13082  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13083  {
13084  oa->write_character(to_char_type(0xBA));
13085  write_number(static_cast<std::uint32_t>(N));
13086  }
13087  // LCOV_EXCL_START
13088  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13089  {
13090  oa->write_character(to_char_type(0xBB));
13091  write_number(static_cast<std::uint64_t>(N));
13092  }
13093  // LCOV_EXCL_STOP
13094 
13095  // step 2: write each element
13096  for (const auto& el : *j.m_value.object)
13097  {
13098  write_cbor(el.first);
13099  write_cbor(el.second);
13100  }
13101  break;
13102  }
13103 
13104  default:
13105  break;
13106  }
13107  }
13108 
13112  void write_msgpack(const BasicJsonType& j)
13113  {
13114  switch (j.type())
13115  {
13116  case value_t::null: // nil
13117  {
13118  oa->write_character(to_char_type(0xC0));
13119  break;
13120  }
13121 
13122  case value_t::boolean: // true and false
13123  {
13124  oa->write_character(j.m_value.boolean
13125  ? to_char_type(0xC3)
13126  : to_char_type(0xC2));
13127  break;
13128  }
13129 
13130  case value_t::number_integer:
13131  {
13132  if (j.m_value.number_integer >= 0)
13133  {
13134  // MessagePack does not differentiate between positive
13135  // signed integers and unsigned integers. Therefore, we used
13136  // the code from the value_t::number_unsigned case here.
13137  if (j.m_value.number_unsigned < 128)
13138  {
13139  // positive fixnum
13140  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13141  }
13142  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13143  {
13144  // uint 8
13145  oa->write_character(to_char_type(0xCC));
13146  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13147  }
13148  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13149  {
13150  // uint 16
13151  oa->write_character(to_char_type(0xCD));
13152  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13153  }
13154  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13155  {
13156  // uint 32
13157  oa->write_character(to_char_type(0xCE));
13158  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13159  }
13160  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13161  {
13162  // uint 64
13163  oa->write_character(to_char_type(0xCF));
13164  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13165  }
13166  }
13167  else
13168  {
13169  if (j.m_value.number_integer >= -32)
13170  {
13171  // negative fixnum
13172  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13173  }
13174  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13175  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13176  {
13177  // int 8
13178  oa->write_character(to_char_type(0xD0));
13179  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13180  }
13181  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13182  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13183  {
13184  // int 16
13185  oa->write_character(to_char_type(0xD1));
13186  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13187  }
13188  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13189  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13190  {
13191  // int 32
13192  oa->write_character(to_char_type(0xD2));
13193  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13194  }
13195  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13196  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13197  {
13198  // int 64
13199  oa->write_character(to_char_type(0xD3));
13200  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13201  }
13202  }
13203  break;
13204  }
13205 
13206  case value_t::number_unsigned:
13207  {
13208  if (j.m_value.number_unsigned < 128)
13209  {
13210  // positive fixnum
13211  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13212  }
13213  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13214  {
13215  // uint 8
13216  oa->write_character(to_char_type(0xCC));
13217  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13218  }
13219  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13220  {
13221  // uint 16
13222  oa->write_character(to_char_type(0xCD));
13223  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13224  }
13225  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13226  {
13227  // uint 32
13228  oa->write_character(to_char_type(0xCE));
13229  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13230  }
13231  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13232  {
13233  // uint 64
13234  oa->write_character(to_char_type(0xCF));
13235  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13236  }
13237  break;
13238  }
13239 
13240  case value_t::number_float:
13241  {
13242  write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13243  break;
13244  }
13245 
13246  case value_t::string:
13247  {
13248  // step 1: write control byte and the string length
13249  const auto N = j.m_value.string->size();
13250  if (N <= 31)
13251  {
13252  // fixstr
13253  write_number(static_cast<std::uint8_t>(0xA0 | N));
13254  }
13255  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13256  {
13257  // str 8
13258  oa->write_character(to_char_type(0xD9));
13259  write_number(static_cast<std::uint8_t>(N));
13260  }
13261  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13262  {
13263  // str 16
13264  oa->write_character(to_char_type(0xDA));
13265  write_number(static_cast<std::uint16_t>(N));
13266  }
13267  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13268  {
13269  // str 32
13270  oa->write_character(to_char_type(0xDB));
13271  write_number(static_cast<std::uint32_t>(N));
13272  }
13273 
13274  // step 2: write the string
13275  oa->write_characters(
13276  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13277  j.m_value.string->size());
13278  break;
13279  }
13280 
13281  case value_t::array:
13282  {
13283  // step 1: write control byte and the array size
13284  const auto N = j.m_value.array->size();
13285  if (N <= 15)
13286  {
13287  // fixarray
13288  write_number(static_cast<std::uint8_t>(0x90 | N));
13289  }
13290  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13291  {
13292  // array 16
13293  oa->write_character(to_char_type(0xDC));
13294  write_number(static_cast<std::uint16_t>(N));
13295  }
13296  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13297  {
13298  // array 32
13299  oa->write_character(to_char_type(0xDD));
13300  write_number(static_cast<std::uint32_t>(N));
13301  }
13302 
13303  // step 2: write each element
13304  for (const auto& el : *j.m_value.array)
13305  {
13306  write_msgpack(el);
13307  }
13308  break;
13309  }
13310 
13311  case value_t::binary:
13312  {
13313  // step 0: determine if the binary type has a set subtype to
13314  // determine whether or not to use the ext or fixext types
13315  const bool use_ext = j.m_value.binary->has_subtype();
13316 
13317  // step 1: write control byte and the byte string length
13318  const auto N = j.m_value.binary->size();
13319  if (N <= (std::numeric_limits<std::uint8_t>::max)())
13320  {
13321  std::uint8_t output_type{};
13322  bool fixed = true;
13323  if (use_ext)
13324  {
13325  switch (N)
13326  {
13327  case 1:
13328  output_type = 0xD4; // fixext 1
13329  break;
13330  case 2:
13331  output_type = 0xD5; // fixext 2
13332  break;
13333  case 4:
13334  output_type = 0xD6; // fixext 4
13335  break;
13336  case 8:
13337  output_type = 0xD7; // fixext 8
13338  break;
13339  case 16:
13340  output_type = 0xD8; // fixext 16
13341  break;
13342  default:
13343  output_type = 0xC7; // ext 8
13344  fixed = false;
13345  break;
13346  }
13347 
13348  }
13349  else
13350  {
13351  output_type = 0xC4; // bin 8
13352  fixed = false;
13353  }
13354 
13355  oa->write_character(to_char_type(output_type));
13356  if (!fixed)
13357  {
13358  write_number(static_cast<std::uint8_t>(N));
13359  }
13360  }
13361  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13362  {
13363  std::uint8_t output_type = use_ext
13364  ? 0xC8 // ext 16
13365  : 0xC5; // bin 16
13366 
13367  oa->write_character(to_char_type(output_type));
13368  write_number(static_cast<std::uint16_t>(N));
13369  }
13370  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13371  {
13372  std::uint8_t output_type = use_ext
13373  ? 0xC9 // ext 32
13374  : 0xC6; // bin 32
13375 
13376  oa->write_character(to_char_type(output_type));
13377  write_number(static_cast<std::uint32_t>(N));
13378  }
13379 
13380  // step 1.5: if this is an ext type, write the subtype
13381  if (use_ext)
13382  {
13383  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13384  }
13385 
13386  // step 2: write the byte string
13387  oa->write_characters(
13388  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13389  N);
13390 
13391  break;
13392  }
13393 
13394  case value_t::object:
13395  {
13396  // step 1: write control byte and the object size
13397  const auto N = j.m_value.object->size();
13398  if (N <= 15)
13399  {
13400  // fixmap
13401  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13402  }
13403  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13404  {
13405  // map 16
13406  oa->write_character(to_char_type(0xDE));
13407  write_number(static_cast<std::uint16_t>(N));
13408  }
13409  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13410  {
13411  // map 32
13412  oa->write_character(to_char_type(0xDF));
13413  write_number(static_cast<std::uint32_t>(N));
13414  }
13415 
13416  // step 2: write each element
13417  for (const auto& el : *j.m_value.object)
13418  {
13419  write_msgpack(el.first);
13420  write_msgpack(el.second);
13421  }
13422  break;
13423  }
13424 
13425  default:
13426  break;
13427  }
13428  }
13429 
13436  void write_ubjson(const BasicJsonType& j, const bool use_count,
13437  const bool use_type, const bool add_prefix = true)
13438  {
13439  switch (j.type())
13440  {
13441  case value_t::null:
13442  {
13443  if (add_prefix)
13444  {
13445  oa->write_character(to_char_type('Z'));
13446  }
13447  break;
13448  }
13449 
13450  case value_t::boolean:
13451  {
13452  if (add_prefix)
13453  {
13454  oa->write_character(j.m_value.boolean
13455  ? to_char_type('T')
13456  : to_char_type('F'));
13457  }
13458  break;
13459  }
13460 
13461  case value_t::number_integer:
13462  {
13463  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13464  break;
13465  }
13466 
13467  case value_t::number_unsigned:
13468  {
13469  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13470  break;
13471  }
13472 
13473  case value_t::number_float:
13474  {
13475  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13476  break;
13477  }
13478 
13479  case value_t::string:
13480  {
13481  if (add_prefix)
13482  {
13483  oa->write_character(to_char_type('S'));
13484  }
13485  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13486  oa->write_characters(
13487  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13488  j.m_value.string->size());
13489  break;
13490  }
13491 
13492  case value_t::array:
13493  {
13494  if (add_prefix)
13495  {
13496  oa->write_character(to_char_type('['));
13497  }
13498 
13499  bool prefix_required = true;
13500  if (use_type && !j.m_value.array->empty())
13501  {
13502  JSON_ASSERT(use_count);
13503  const CharType first_prefix = ubjson_prefix(j.front());
13504  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13505  [this, first_prefix](const BasicJsonType & v)
13506  {
13507  return ubjson_prefix(v) == first_prefix;
13508  });
13509 
13510  if (same_prefix)
13511  {
13512  prefix_required = false;
13513  oa->write_character(to_char_type('$'));
13514  oa->write_character(first_prefix);
13515  }
13516  }
13517 
13518  if (use_count)
13519  {
13520  oa->write_character(to_char_type('#'));
13521  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13522  }
13523 
13524  for (const auto& el : *j.m_value.array)
13525  {
13526  write_ubjson(el, use_count, use_type, prefix_required);
13527  }
13528 
13529  if (!use_count)
13530  {
13531  oa->write_character(to_char_type(']'));
13532  }
13533 
13534  break;
13535  }
13536 
13537  case value_t::binary:
13538  {
13539  if (add_prefix)
13540  {
13541  oa->write_character(to_char_type('['));
13542  }
13543 
13544  if (use_type && !j.m_value.binary->empty())
13545  {
13546  JSON_ASSERT(use_count);
13547  oa->write_character(to_char_type('$'));
13548  oa->write_character('U');
13549  }
13550 
13551  if (use_count)
13552  {
13553  oa->write_character(to_char_type('#'));
13554  write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13555  }
13556 
13557  if (use_type)
13558  {
13559  oa->write_characters(
13560  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13561  j.m_value.binary->size());
13562  }
13563  else
13564  {
13565  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13566  {
13567  oa->write_character(to_char_type('U'));
13568  oa->write_character(j.m_value.binary->data()[i]);
13569  }
13570  }
13571 
13572  if (!use_count)
13573  {
13574  oa->write_character(to_char_type(']'));
13575  }
13576 
13577  break;
13578  }
13579 
13580  case value_t::object:
13581  {
13582  if (add_prefix)
13583  {
13584  oa->write_character(to_char_type('{'));
13585  }
13586 
13587  bool prefix_required = true;
13588  if (use_type && !j.m_value.object->empty())
13589  {
13590  JSON_ASSERT(use_count);
13591  const CharType first_prefix = ubjson_prefix(j.front());
13592  const bool same_prefix = std::all_of(j.begin(), j.end(),
13593  [this, first_prefix](const BasicJsonType & v)
13594  {
13595  return ubjson_prefix(v) == first_prefix;
13596  });
13597 
13598  if (same_prefix)
13599  {
13600  prefix_required = false;
13601  oa->write_character(to_char_type('$'));
13602  oa->write_character(first_prefix);
13603  }
13604  }
13605 
13606  if (use_count)
13607  {
13608  oa->write_character(to_char_type('#'));
13609  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13610  }
13611 
13612  for (const auto& el : *j.m_value.object)
13613  {
13614  write_number_with_ubjson_prefix(el.first.size(), true);
13615  oa->write_characters(
13616  reinterpret_cast<const CharType*>(el.first.c_str()),
13617  el.first.size());
13618  write_ubjson(el.second, use_count, use_type, prefix_required);
13619  }
13620 
13621  if (!use_count)
13622  {
13623  oa->write_character(to_char_type('}'));
13624  }
13625 
13626  break;
13627  }
13628 
13629  default:
13630  break;
13631  }
13632  }
13633 
13634  private:
13636  // BSON //
13638 
13643  static std::size_t calc_bson_entry_header_size(const string_t& name)
13644  {
13645  const auto it = name.find(static_cast<typename string_t::value_type>(0));
13646  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13647  {
13648  JSON_THROW(out_of_range::create(409,
13649  "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13650  }
13651 
13652  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13653  }
13654 
13658  void write_bson_entry_header(const string_t& name,
13659  const std::uint8_t element_type)
13660  {
13661  oa->write_character(to_char_type(element_type)); // boolean
13662  oa->write_characters(
13663  reinterpret_cast<const CharType*>(name.c_str()),
13664  name.size() + 1u);
13665  }
13666 
13670  void write_bson_boolean(const string_t& name,
13671  const bool value)
13672  {
13673  write_bson_entry_header(name, 0x08);
13674  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13675  }
13676 
13680  void write_bson_double(const string_t& name,
13681  const double value)
13682  {
13683  write_bson_entry_header(name, 0x01);
13684  write_number<double, true>(value);
13685  }
13686 
13690  static std::size_t calc_bson_string_size(const string_t& value)
13691  {
13692  return sizeof(std::int32_t) + value.size() + 1ul;
13693  }
13694 
13698  void write_bson_string(const string_t& name,
13699  const string_t& value)
13700  {
13701  write_bson_entry_header(name, 0x02);
13702 
13703  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13704  oa->write_characters(
13705  reinterpret_cast<const CharType*>(value.c_str()),
13706  value.size() + 1);
13707  }
13708 
13712  void write_bson_null(const string_t& name)
13713  {
13714  write_bson_entry_header(name, 0x0A);
13715  }
13716 
13720  static std::size_t calc_bson_integer_size(const std::int64_t value)
13721  {
13722  return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
13723  ? sizeof(std::int32_t)
13724  : sizeof(std::int64_t);
13725  }
13726 
13730  void write_bson_integer(const string_t& name,
13731  const std::int64_t value)
13732  {
13733  if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
13734  {
13735  write_bson_entry_header(name, 0x10); // int32
13736  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13737  }
13738  else
13739  {
13740  write_bson_entry_header(name, 0x12); // int64
13741  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13742  }
13743  }
13744 
13748  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13749  {
13750  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13751  ? sizeof(std::int32_t)
13752  : sizeof(std::int64_t);
13753  }
13754 
13758  void write_bson_unsigned(const string_t& name,
13759  const std::uint64_t value)
13760  {
13761  if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13762  {
13763  write_bson_entry_header(name, 0x10 /* int32 */);
13764  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13765  }
13766  else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13767  {
13768  write_bson_entry_header(name, 0x12 /* int64 */);
13769  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13770  }
13771  else
13772  {
13773  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13774  }
13775  }
13776 
13780  void write_bson_object_entry(const string_t& name,
13781  const typename BasicJsonType::object_t& value)
13782  {
13783  write_bson_entry_header(name, 0x03); // object
13784  write_bson_object(value);
13785  }
13786 
13790  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13791  {
13792  std::size_t array_index = 0ul;
13793 
13794  const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
13795  {
13796  return result + calc_bson_element_size(std::to_string(array_index++), el);
13797  });
13798 
13799  return sizeof(std::int32_t) + embedded_document_size + 1ul;
13800  }
13801 
13805  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13806  {
13807  return sizeof(std::int32_t) + value.size() + 1ul;
13808  }
13809 
13813  void write_bson_array(const string_t& name,
13814  const typename BasicJsonType::array_t& value)
13815  {
13816  write_bson_entry_header(name, 0x04); // array
13817  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13818 
13819  std::size_t array_index = 0ul;
13820 
13821  for (const auto& el : value)
13822  {
13823  write_bson_element(std::to_string(array_index++), el);
13824  }
13825 
13826  oa->write_character(to_char_type(0x00));
13827  }
13828 
13832  void write_bson_binary(const string_t& name,
13833  const binary_t& value)
13834  {
13835  write_bson_entry_header(name, 0x05);
13836 
13837  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13838  write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13839 
13840  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13841  }
13842 
13847  static std::size_t calc_bson_element_size(const string_t& name,
13848  const BasicJsonType& j)
13849  {
13850  const auto header_size = calc_bson_entry_header_size(name);
13851  switch (j.type())
13852  {
13853  case value_t::object:
13854  return header_size + calc_bson_object_size(*j.m_value.object);
13855 
13856  case value_t::array:
13857  return header_size + calc_bson_array_size(*j.m_value.array);
13858 
13859  case value_t::binary:
13860  return header_size + calc_bson_binary_size(*j.m_value.binary);
13861 
13862  case value_t::boolean:
13863  return header_size + 1ul;
13864 
13865  case value_t::number_float:
13866  return header_size + 8ul;
13867 
13868  case value_t::number_integer:
13869  return header_size + calc_bson_integer_size(j.m_value.number_integer);
13870 
13871  case value_t::number_unsigned:
13872  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13873 
13874  case value_t::string:
13875  return header_size + calc_bson_string_size(*j.m_value.string);
13876 
13877  case value_t::null:
13878  return header_size + 0ul;
13879 
13880  // LCOV_EXCL_START
13881  default:
13882  JSON_ASSERT(false);
13883  return 0ul;
13884  // LCOV_EXCL_STOP
13885  }
13886  }
13887 
13895  void write_bson_element(const string_t& name,
13896  const BasicJsonType& j)
13897  {
13898  switch (j.type())
13899  {
13900  case value_t::object:
13901  return write_bson_object_entry(name, *j.m_value.object);
13902 
13903  case value_t::array:
13904  return write_bson_array(name, *j.m_value.array);
13905 
13906  case value_t::binary:
13907  return write_bson_binary(name, *j.m_value.binary);
13908 
13909  case value_t::boolean:
13910  return write_bson_boolean(name, j.m_value.boolean);
13911 
13912  case value_t::number_float:
13913  return write_bson_double(name, j.m_value.number_float);
13914 
13915  case value_t::number_integer:
13916  return write_bson_integer(name, j.m_value.number_integer);
13917 
13918  case value_t::number_unsigned:
13919  return write_bson_unsigned(name, j.m_value.number_unsigned);
13920 
13921  case value_t::string:
13922  return write_bson_string(name, *j.m_value.string);
13923 
13924  case value_t::null:
13925  return write_bson_null(name);
13926 
13927  // LCOV_EXCL_START
13928  default:
13929  JSON_ASSERT(false);
13930  return;
13931  // LCOV_EXCL_STOP
13932  }
13933  }
13934 
13941  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13942  {
13943  std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13944  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13945  {
13946  return result += calc_bson_element_size(el.first, el.second);
13947  });
13948 
13949  return sizeof(std::int32_t) + document_size + 1ul;
13950  }
13951 
13956  void write_bson_object(const typename BasicJsonType::object_t& value)
13957  {
13958  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13959 
13960  for (const auto& el : value)
13961  {
13962  write_bson_element(el.first, el.second);
13963  }
13964 
13965  oa->write_character(to_char_type(0x00));
13966  }
13967 
13969  // CBOR //
13971 
13972  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13973  {
13974  return to_char_type(0xFA); // Single-Precision Float
13975  }
13976 
13977  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13978  {
13979  return to_char_type(0xFB); // Double-Precision Float
13980  }
13981 
13983  // MsgPack //
13985 
13986  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13987  {
13988  return to_char_type(0xCA); // float 32
13989  }
13990 
13991  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13992  {
13993  return to_char_type(0xCB); // float 64
13994  }
13995 
13997  // UBJSON //
13999 
14000  // UBJSON: write number (floating point)
14001  template<typename NumberType, typename std::enable_if<
14002  std::is_floating_point<NumberType>::value, int>::type = 0>
14003  void write_number_with_ubjson_prefix(const NumberType n,
14004  const bool add_prefix)
14005  {
14006  if (add_prefix)
14007  {
14008  oa->write_character(get_ubjson_float_prefix(n));
14009  }
14010  write_number(n);
14011  }
14012 
14013  // UBJSON: write number (unsigned integer)
14014  template<typename NumberType, typename std::enable_if<
14015  std::is_unsigned<NumberType>::value, int>::type = 0>
14016  void write_number_with_ubjson_prefix(const NumberType n,
14017  const bool add_prefix)
14018  {
14019  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14020  {
14021  if (add_prefix)
14022  {
14023  oa->write_character(to_char_type('i')); // int8
14024  }
14025  write_number(static_cast<std::uint8_t>(n));
14026  }
14027  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14028  {
14029  if (add_prefix)
14030  {
14031  oa->write_character(to_char_type('U')); // uint8
14032  }
14033  write_number(static_cast<std::uint8_t>(n));
14034  }
14035  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14036  {
14037  if (add_prefix)
14038  {
14039  oa->write_character(to_char_type('I')); // int16
14040  }
14041  write_number(static_cast<std::int16_t>(n));
14042  }
14043  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14044  {
14045  if (add_prefix)
14046  {
14047  oa->write_character(to_char_type('l')); // int32
14048  }
14049  write_number(static_cast<std::int32_t>(n));
14050  }
14051  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14052  {
14053  if (add_prefix)
14054  {
14055  oa->write_character(to_char_type('L')); // int64
14056  }
14057  write_number(static_cast<std::int64_t>(n));
14058  }
14059  else
14060  {
14061  if (add_prefix)
14062  {
14063  oa->write_character(to_char_type('H')); // high-precision number
14064  }
14065 
14066  const auto number = BasicJsonType(n).dump();
14067  write_number_with_ubjson_prefix(number.size(), true);
14068  for (std::size_t i = 0; i < number.size(); ++i)
14069  {
14070  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14071  }
14072  }
14073  }
14074 
14075  // UBJSON: write number (signed integer)
14076  template < typename NumberType, typename std::enable_if <
14077  std::is_signed<NumberType>::value&&
14078  !std::is_floating_point<NumberType>::value, int >::type = 0 >
14079  void write_number_with_ubjson_prefix(const NumberType n,
14080  const bool add_prefix)
14081  {
14082  if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14083  {
14084  if (add_prefix)
14085  {
14086  oa->write_character(to_char_type('i')); // int8
14087  }
14088  write_number(static_cast<std::int8_t>(n));
14089  }
14090  else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
14091  {
14092  if (add_prefix)
14093  {
14094  oa->write_character(to_char_type('U')); // uint8
14095  }
14096  write_number(static_cast<std::uint8_t>(n));
14097  }
14098  else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14099  {
14100  if (add_prefix)
14101  {
14102  oa->write_character(to_char_type('I')); // int16
14103  }
14104  write_number(static_cast<std::int16_t>(n));
14105  }
14106  else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14107  {
14108  if (add_prefix)
14109  {
14110  oa->write_character(to_char_type('l')); // int32
14111  }
14112  write_number(static_cast<std::int32_t>(n));
14113  }
14114  else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14115  {
14116  if (add_prefix)
14117  {
14118  oa->write_character(to_char_type('L')); // int64
14119  }
14120  write_number(static_cast<std::int64_t>(n));
14121  }
14122  // LCOV_EXCL_START
14123  else
14124  {
14125  if (add_prefix)
14126  {
14127  oa->write_character(to_char_type('H')); // high-precision number
14128  }
14129 
14130  const auto number = BasicJsonType(n).dump();
14131  write_number_with_ubjson_prefix(number.size(), true);
14132  for (std::size_t i = 0; i < number.size(); ++i)
14133  {
14134  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14135  }
14136  }
14137  // LCOV_EXCL_STOP
14138  }
14139 
14143  CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14144  {
14145  switch (j.type())
14146  {
14147  case value_t::null:
14148  return 'Z';
14149 
14150  case value_t::boolean:
14151  return j.m_value.boolean ? 'T' : 'F';
14152 
14153  case value_t::number_integer:
14154  {
14155  if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14156  {
14157  return 'i';
14158  }
14159  if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14160  {
14161  return 'U';
14162  }
14163  if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14164  {
14165  return 'I';
14166  }
14167  if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14168  {
14169  return 'l';
14170  }
14171  if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14172  {
14173  return 'L';
14174  }
14175  // anything else is treated as high-precision number
14176  return 'H'; // LCOV_EXCL_LINE
14177  }
14178 
14179  case value_t::number_unsigned:
14180  {
14181  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14182  {
14183  return 'i';
14184  }
14185  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14186  {
14187  return 'U';
14188  }
14189  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14190  {
14191  return 'I';
14192  }
14193  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14194  {
14195  return 'l';
14196  }
14197  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14198  {
14199  return 'L';
14200  }
14201  // anything else is treated as high-precision number
14202  return 'H'; // LCOV_EXCL_LINE
14203  }
14204 
14205  case value_t::number_float:
14206  return get_ubjson_float_prefix(j.m_value.number_float);
14207 
14208  case value_t::string:
14209  return 'S';
14210 
14211  case value_t::array: // fallthrough
14212  case value_t::binary:
14213  return '[';
14214 
14215  case value_t::object:
14216  return '{';
14217 
14218  default: // discarded values
14219  return 'N';
14220  }
14221  }
14222 
14223  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14224  {
14225  return 'd'; // float 32
14226  }
14227 
14228  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14229  {
14230  return 'D'; // float 64
14231  }
14232 
14234  // Utility functions //
14236 
14237  /*
14238  @brief write a number to output input
14239  @param[in] n number of type @a NumberType
14240  @tparam NumberType the type of the number
14241  @tparam OutputIsLittleEndian Set to true if output data is
14242  required to be little endian
14243 
14244  @note This function needs to respect the system's endianess, because bytes
14245  in CBOR, MessagePack, and UBJSON are stored in network order (big
14246  endian) and therefore need reordering on little endian systems.
14247  */
14248  template<typename NumberType, bool OutputIsLittleEndian = false>
14249  void write_number(const NumberType n)
14250  {
14251  // step 1: write number to array of length NumberType
14252  std::array<CharType, sizeof(NumberType)> vec;
14253  std::memcpy(vec.data(), &n, sizeof(NumberType));
14254 
14255  // step 2: write array to output (with possible reordering)
14256  if (is_little_endian != OutputIsLittleEndian)
14257  {
14258  // reverse byte order prior to conversion if necessary
14259  std::reverse(vec.begin(), vec.end());
14260  }
14261 
14262  oa->write_characters(vec.data(), sizeof(NumberType));
14263  }
14264 
14265  void write_compact_float(const number_float_t n, detail::input_format_t format)
14266  {
14267  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14268  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14269  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14270  {
14271  oa->write_character(format == detail::input_format_t::cbor
14272  ? get_cbor_float_prefix(static_cast<float>(n))
14273  : get_msgpack_float_prefix(static_cast<float>(n)));
14274  write_number(static_cast<float>(n));
14275  }
14276  else
14277  {
14278  oa->write_character(format == detail::input_format_t::cbor
14279  ? get_cbor_float_prefix(n)
14280  : get_msgpack_float_prefix(n));
14281  write_number(n);
14282  }
14283  }
14284 
14285  public:
14286  // The following to_char_type functions are implement the conversion
14287  // between uint8_t and CharType. In case CharType is not unsigned,
14288  // such a conversion is required to allow values greater than 128.
14289  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14290  template < typename C = CharType,
14291  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14292  static constexpr CharType to_char_type(std::uint8_t x) noexcept
14293  {
14294  return *reinterpret_cast<char*>(&x);
14295  }
14296 
14297  template < typename C = CharType,
14298  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14299  static CharType to_char_type(std::uint8_t x) noexcept
14300  {
14301  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14302  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14303  CharType result;
14304  std::memcpy(&result, &x, sizeof(x));
14305  return result;
14306  }
14307 
14308  template<typename C = CharType,
14309  enable_if_t<std::is_unsigned<C>::value>* = nullptr>
14310  static constexpr CharType to_char_type(std::uint8_t x) noexcept
14311  {
14312  return x;
14313  }
14314 
14315  template < typename InputCharType, typename C = CharType,
14316  enable_if_t <
14317  std::is_signed<C>::value &&
14318  std::is_signed<char>::value &&
14319  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14320  > * = nullptr >
14321  static constexpr CharType to_char_type(InputCharType x) noexcept
14322  {
14323  return x;
14324  }
14325 
14326  private:
14328  const bool is_little_endian = little_endianess();
14329 
14331  output_adapter_t<CharType> oa = nullptr;
14332 };
14333 } // namespace detail
14334 } // namespace nlohmann
14335 
14336 // #include <nlohmann/detail/output/output_adapters.hpp>
14337 
14338 // #include <nlohmann/detail/output/serializer.hpp>
14339 
14340 
14341 #include <algorithm> // reverse, remove, fill, find, none_of
14342 #include <array> // array
14343 #include <clocale> // localeconv, lconv
14344 #include <cmath> // labs, isfinite, isnan, signbit
14345 #include <cstddef> // size_t, ptrdiff_t
14346 #include <cstdint> // uint8_t
14347 #include <cstdio> // snprintf
14348 #include <limits> // numeric_limits
14349 #include <string> // string, char_traits
14350 #include <type_traits> // is_same
14351 #include <utility> // move
14352 
14353 // #include <nlohmann/detail/conversions/to_chars.hpp>
14354 
14355 
14356 #include <array> // array
14357 #include <cmath> // signbit, isfinite
14358 #include <cstdint> // intN_t, uintN_t
14359 #include <cstring> // memcpy, memmove
14360 #include <limits> // numeric_limits
14361 #include <type_traits> // conditional
14362 
14363 // #include <nlohmann/detail/macro_scope.hpp>
14364 
14365 
14366 namespace nlohmann
14367 {
14368 namespace detail
14369 {
14370 
14390 namespace dtoa_impl
14391 {
14392 
14393 template<typename Target, typename Source>
14394 Target reinterpret_bits(const Source source)
14395 {
14396  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14397 
14398  Target target;
14399  std::memcpy(&target, &source, sizeof(Source));
14400  return target;
14401 }
14402 
14403 struct diyfp // f * 2^e
14404 {
14405  static constexpr int kPrecision = 64; // = q
14406 
14407  std::uint64_t f = 0;
14408  int e = 0;
14409 
14410  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14411 
14416  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14417  {
14418  JSON_ASSERT(x.e == y.e);
14419  JSON_ASSERT(x.f >= y.f);
14420 
14421  return {x.f - y.f, x.e};
14422  }
14423 
14428  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14429  {
14430  static_assert(kPrecision == 64, "internal error");
14431 
14432  // Computes:
14433  // f = round((x.f * y.f) / 2^q)
14434  // e = x.e + y.e + q
14435 
14436  // Emulate the 64-bit * 64-bit multiplication:
14437  //
14438  // p = u * v
14439  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14440  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
14441  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
14442  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
14443  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
14444  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
14445  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
14446  //
14447  // (Since Q might be larger than 2^32 - 1)
14448  //
14449  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14450  //
14451  // (Q_hi + H does not overflow a 64-bit int)
14452  //
14453  // = p_lo + 2^64 p_hi
14454 
14455  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14456  const std::uint64_t u_hi = x.f >> 32u;
14457  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14458  const std::uint64_t v_hi = y.f >> 32u;
14459 
14460  const std::uint64_t p0 = u_lo * v_lo;
14461  const std::uint64_t p1 = u_lo * v_hi;
14462  const std::uint64_t p2 = u_hi * v_lo;
14463  const std::uint64_t p3 = u_hi * v_hi;
14464 
14465  const std::uint64_t p0_hi = p0 >> 32u;
14466  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14467  const std::uint64_t p1_hi = p1 >> 32u;
14468  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14469  const std::uint64_t p2_hi = p2 >> 32u;
14470 
14471  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14472 
14473  // The full product might now be computed as
14474  //
14475  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14476  // p_lo = p0_lo + (Q << 32)
14477  //
14478  // But in this particular case here, the full p_lo is not required.
14479  // Effectively we only need to add the highest bit in p_lo to p_hi (and
14480  // Q_hi + 1 does not overflow).
14481 
14482  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14483 
14484  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14485 
14486  return {h, x.e + y.e + 64};
14487  }
14488 
14493  static diyfp normalize(diyfp x) noexcept
14494  {
14495  JSON_ASSERT(x.f != 0);
14496 
14497  while ((x.f >> 63u) == 0)
14498  {
14499  x.f <<= 1u;
14500  x.e--;
14501  }
14502 
14503  return x;
14504  }
14505 
14510  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14511  {
14512  const int delta = x.e - target_exponent;
14513 
14514  JSON_ASSERT(delta >= 0);
14515  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14516 
14517  return {x.f << delta, target_exponent};
14518  }
14519 };
14520 
14521 struct boundaries
14522 {
14523  diyfp w;
14524  diyfp minus;
14525  diyfp plus;
14526 };
14527 
14534 template<typename FloatType>
14535 boundaries compute_boundaries(FloatType value)
14536 {
14537  JSON_ASSERT(std::isfinite(value));
14538  JSON_ASSERT(value > 0);
14539 
14540  // Convert the IEEE representation into a diyfp.
14541  //
14542  // If v is denormal:
14543  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
14544  // If v is normalized:
14545  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14546 
14547  static_assert(std::numeric_limits<FloatType>::is_iec559,
14548  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14549 
14550  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14551  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14552  constexpr int kMinExp = 1 - kBias;
14553  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14554 
14555  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14556 
14557  const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14558  const std::uint64_t E = bits >> (kPrecision - 1);
14559  const std::uint64_t F = bits & (kHiddenBit - 1);
14560 
14561  const bool is_denormal = E == 0;
14562  const diyfp v = is_denormal
14563  ? diyfp(F, kMinExp)
14564  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14565 
14566  // Compute the boundaries m- and m+ of the floating-point value
14567  // v = f * 2^e.
14568  //
14569  // Determine v- and v+, the floating-point predecessor and successor if v,
14570  // respectively.
14571  //
14572  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14573  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14574  //
14575  // v+ = v + 2^e
14576  //
14577  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14578  // between m- and m+ round to v, regardless of how the input rounding
14579  // algorithm breaks ties.
14580  //
14581  // ---+-------------+-------------+-------------+-------------+--- (A)
14582  // v- m- v m+ v+
14583  //
14584  // -----------------+------+------+-------------+-------------+--- (B)
14585  // v- m- v m+ v+
14586 
14587  const bool lower_boundary_is_closer = F == 0 && E > 1;
14588  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14589  const diyfp m_minus = lower_boundary_is_closer
14590  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14591  : diyfp(2 * v.f - 1, v.e - 1); // (A)
14592 
14593  // Determine the normalized w+ = m+.
14594  const diyfp w_plus = diyfp::normalize(m_plus);
14595 
14596  // Determine w- = m- such that e_(w-) = e_(w+).
14597  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14598 
14599  return {diyfp::normalize(v), w_minus, w_plus};
14600 }
14601 
14602 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14603 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14604 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14605 //
14606 // alpha <= e = e_c + e_w + q <= gamma
14607 //
14608 // or
14609 //
14610 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14611 // <= f_c * f_w * 2^gamma
14612 //
14613 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14614 //
14615 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14616 //
14617 // or
14618 //
14619 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14620 //
14621 // The choice of (alpha,gamma) determines the size of the table and the form of
14622 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14623 // in practice:
14624 //
14625 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14626 // processed independently: An integral part p1, and a fractional part p2:
14627 //
14628 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14629 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14630 // = p1 + p2 * 2^e
14631 //
14632 // The conversion of p1 into decimal form requires a series of divisions and
14633 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14634 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14635 // achieved by choosing
14636 //
14637 // -e >= 32 or e <= -32 := gamma
14638 //
14639 // In order to convert the fractional part
14640 //
14641 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14642 //
14643 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14644 // d[-i] are extracted in order:
14645 //
14646 // (10 * p2) div 2^-e = d[-1]
14647 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14648 //
14649 // The multiplication by 10 must not overflow. It is sufficient to choose
14650 //
14651 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14652 //
14653 // Since p2 = f mod 2^-e < 2^-e,
14654 //
14655 // -e <= 60 or e >= -60 := alpha
14656 
14657 constexpr int kAlpha = -60;
14658 constexpr int kGamma = -32;
14659 
14660 struct cached_power // c = f * 2^e ~= 10^k
14661 {
14662  std::uint64_t f;
14663  int e;
14664  int k;
14665 };
14666 
14674 inline cached_power get_cached_power_for_binary_exponent(int e)
14675 {
14676  // Now
14677  //
14678  // alpha <= e_c + e + q <= gamma (1)
14679  // ==> f_c * 2^alpha <= c * 2^e * 2^q
14680  //
14681  // and since the c's are normalized, 2^(q-1) <= f_c,
14682  //
14683  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14684  // ==> 2^(alpha - e - 1) <= c
14685  //
14686  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14687  //
14688  // k = ceil( log_10( 2^(alpha - e - 1) ) )
14689  // = ceil( (alpha - e - 1) * log_10(2) )
14690  //
14691  // From the paper:
14692  // "In theory the result of the procedure could be wrong since c is rounded,
14693  // and the computation itself is approximated [...]. In practice, however,
14694  // this simple function is sufficient."
14695  //
14696  // For IEEE double precision floating-point numbers converted into
14697  // normalized diyfp's w = f * 2^e, with q = 64,
14698  //
14699  // e >= -1022 (min IEEE exponent)
14700  // -52 (p - 1)
14701  // -52 (p - 1, possibly normalize denormal IEEE numbers)
14702  // -11 (normalize the diyfp)
14703  // = -1137
14704  //
14705  // and
14706  //
14707  // e <= +1023 (max IEEE exponent)
14708  // -52 (p - 1)
14709  // -11 (normalize the diyfp)
14710  // = 960
14711  //
14712  // This binary exponent range [-1137,960] results in a decimal exponent
14713  // range [-307,324]. One does not need to store a cached power for each
14714  // k in this range. For each such k it suffices to find a cached power
14715  // such that the exponent of the product lies in [alpha,gamma].
14716  // This implies that the difference of the decimal exponents of adjacent
14717  // table entries must be less than or equal to
14718  //
14719  // floor( (gamma - alpha) * log_10(2) ) = 8.
14720  //
14721  // (A smaller distance gamma-alpha would require a larger table.)
14722 
14723  // NB:
14724  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14725 
14726  constexpr int kCachedPowersMinDecExp = -300;
14727  constexpr int kCachedPowersDecStep = 8;
14728 
14729  static constexpr std::array<cached_power, 79> kCachedPowers =
14730  {
14731  {
14732  { 0xAB70FE17C79AC6CA, -1060, -300 },
14733  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14734  { 0xBE5691EF416BD60C, -1007, -284 },
14735  { 0x8DD01FAD907FFC3C, -980, -276 },
14736  { 0xD3515C2831559A83, -954, -268 },
14737  { 0x9D71AC8FADA6C9B5, -927, -260 },
14738  { 0xEA9C227723EE8BCB, -901, -252 },
14739  { 0xAECC49914078536D, -874, -244 },
14740  { 0x823C12795DB6CE57, -847, -236 },
14741  { 0xC21094364DFB5637, -821, -228 },
14742  { 0x9096EA6F3848984F, -794, -220 },
14743  { 0xD77485CB25823AC7, -768, -212 },
14744  { 0xA086CFCD97BF97F4, -741, -204 },
14745  { 0xEF340A98172AACE5, -715, -196 },
14746  { 0xB23867FB2A35B28E, -688, -188 },
14747  { 0x84C8D4DFD2C63F3B, -661, -180 },
14748  { 0xC5DD44271AD3CDBA, -635, -172 },
14749  { 0x936B9FCEBB25C996, -608, -164 },
14750  { 0xDBAC6C247D62A584, -582, -156 },
14751  { 0xA3AB66580D5FDAF6, -555, -148 },
14752  { 0xF3E2F893DEC3F126, -529, -140 },
14753  { 0xB5B5ADA8AAFF80B8, -502, -132 },
14754  { 0x87625F056C7C4A8B, -475, -124 },
14755  { 0xC9BCFF6034C13053, -449, -116 },
14756  { 0x964E858C91BA2655, -422, -108 },
14757  { 0xDFF9772470297EBD, -396, -100 },
14758  { 0xA6DFBD9FB8E5B88F, -369, -92 },
14759  { 0xF8A95FCF88747D94, -343, -84 },
14760  { 0xB94470938FA89BCF, -316, -76 },
14761  { 0x8A08F0F8BF0F156B, -289, -68 },
14762  { 0xCDB02555653131B6, -263, -60 },
14763  { 0x993FE2C6D07B7FAC, -236, -52 },
14764  { 0xE45C10C42A2B3B06, -210, -44 },
14765  { 0xAA242499697392D3, -183, -36 },
14766  { 0xFD87B5F28300CA0E, -157, -28 },
14767  { 0xBCE5086492111AEB, -130, -20 },
14768  { 0x8CBCCC096F5088CC, -103, -12 },
14769  { 0xD1B71758E219652C, -77, -4 },
14770  { 0x9C40000000000000, -50, 4 },
14771  { 0xE8D4A51000000000, -24, 12 },
14772  { 0xAD78EBC5AC620000, 3, 20 },
14773  { 0x813F3978F8940984, 30, 28 },
14774  { 0xC097CE7BC90715B3, 56, 36 },
14775  { 0x8F7E32CE7BEA5C70, 83, 44 },
14776  { 0xD5D238A4ABE98068, 109, 52 },
14777  { 0x9F4F2726179A2245, 136, 60 },
14778  { 0xED63A231D4C4FB27, 162, 68 },
14779  { 0xB0DE65388CC8ADA8, 189, 76 },
14780  { 0x83C7088E1AAB65DB, 216, 84 },
14781  { 0xC45D1DF942711D9A, 242, 92 },
14782  { 0x924D692CA61BE758, 269, 100 },
14783  { 0xDA01EE641A708DEA, 295, 108 },
14784  { 0xA26DA3999AEF774A, 322, 116 },
14785  { 0xF209787BB47D6B85, 348, 124 },
14786  { 0xB454E4A179DD1877, 375, 132 },
14787  { 0x865B86925B9BC5C2, 402, 140 },
14788  { 0xC83553C5C8965D3D, 428, 148 },
14789  { 0x952AB45CFA97A0B3, 455, 156 },
14790  { 0xDE469FBD99A05FE3, 481, 164 },
14791  { 0xA59BC234DB398C25, 508, 172 },
14792  { 0xF6C69A72A3989F5C, 534, 180 },
14793  { 0xB7DCBF5354E9BECE, 561, 188 },
14794  { 0x88FCF317F22241E2, 588, 196 },
14795  { 0xCC20CE9BD35C78A5, 614, 204 },
14796  { 0x98165AF37B2153DF, 641, 212 },
14797  { 0xE2A0B5DC971F303A, 667, 220 },
14798  { 0xA8D9D1535CE3B396, 694, 228 },
14799  { 0xFB9B7CD9A4A7443C, 720, 236 },
14800  { 0xBB764C4CA7A44410, 747, 244 },
14801  { 0x8BAB8EEFB6409C1A, 774, 252 },
14802  { 0xD01FEF10A657842C, 800, 260 },
14803  { 0x9B10A4E5E9913129, 827, 268 },
14804  { 0xE7109BFBA19C0C9D, 853, 276 },
14805  { 0xAC2820D9623BF429, 880, 284 },
14806  { 0x80444B5E7AA7CF85, 907, 292 },
14807  { 0xBF21E44003ACDD2D, 933, 300 },
14808  { 0x8E679C2F5E44FF8F, 960, 308 },
14809  { 0xD433179D9C8CB841, 986, 316 },
14810  { 0x9E19DB92B4E31BA9, 1013, 324 },
14811  }
14812  };
14813 
14814  // This computation gives exactly the same results for k as
14815  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14816  // for |e| <= 1500, but doesn't require floating-point operations.
14817  // NB: log_10(2) ~= 78913 / 2^18
14818  JSON_ASSERT(e >= -1500);
14819  JSON_ASSERT(e <= 1500);
14820  const int f = kAlpha - e - 1;
14821  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14822 
14823  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14824  JSON_ASSERT(index >= 0);
14825  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14826 
14827  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14828  JSON_ASSERT(kAlpha <= cached.e + e + 64);
14829  JSON_ASSERT(kGamma >= cached.e + e + 64);
14830 
14831  return cached;
14832 }
14833 
14838 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14839 {
14840  // LCOV_EXCL_START
14841  if (n >= 1000000000)
14842  {
14843  pow10 = 1000000000;
14844  return 10;
14845  }
14846  // LCOV_EXCL_STOP
14847  else if (n >= 100000000)
14848  {
14849  pow10 = 100000000;
14850  return 9;
14851  }
14852  else if (n >= 10000000)
14853  {
14854  pow10 = 10000000;
14855  return 8;
14856  }
14857  else if (n >= 1000000)
14858  {
14859  pow10 = 1000000;
14860  return 7;
14861  }
14862  else if (n >= 100000)
14863  {
14864  pow10 = 100000;
14865  return 6;
14866  }
14867  else if (n >= 10000)
14868  {
14869  pow10 = 10000;
14870  return 5;
14871  }
14872  else if (n >= 1000)
14873  {
14874  pow10 = 1000;
14875  return 4;
14876  }
14877  else if (n >= 100)
14878  {
14879  pow10 = 100;
14880  return 3;
14881  }
14882  else if (n >= 10)
14883  {
14884  pow10 = 10;
14885  return 2;
14886  }
14887  else
14888  {
14889  pow10 = 1;
14890  return 1;
14891  }
14892 }
14893 
14894 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14895  std::uint64_t rest, std::uint64_t ten_k)
14896 {
14897  JSON_ASSERT(len >= 1);
14898  JSON_ASSERT(dist <= delta);
14899  JSON_ASSERT(rest <= delta);
14900  JSON_ASSERT(ten_k > 0);
14901 
14902  // <--------------------------- delta ---->
14903  // <---- dist --------->
14904  // --------------[------------------+-------------------]--------------
14905  // M- w M+
14906  //
14907  // ten_k
14908  // <------>
14909  // <---- rest ---->
14910  // --------------[------------------+----+--------------]--------------
14911  // w V
14912  // = buf * 10^k
14913  //
14914  // ten_k represents a unit-in-the-last-place in the decimal representation
14915  // stored in buf.
14916  // Decrement buf by ten_k while this takes buf closer to w.
14917 
14918  // The tests are written in this order to avoid overflow in unsigned
14919  // integer arithmetic.
14920 
14921  while (rest < dist
14922  && delta - rest >= ten_k
14923  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14924  {
14925  JSON_ASSERT(buf[len - 1] != '0');
14926  buf[len - 1]--;
14927  rest += ten_k;
14928  }
14929 }
14930 
14935 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14936  diyfp M_minus, diyfp w, diyfp M_plus)
14937 {
14938  static_assert(kAlpha >= -60, "internal error");
14939  static_assert(kGamma <= -32, "internal error");
14940 
14941  // Generates the digits (and the exponent) of a decimal floating-point
14942  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14943  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14944  //
14945  // <--------------------------- delta ---->
14946  // <---- dist --------->
14947  // --------------[------------------+-------------------]--------------
14948  // M- w M+
14949  //
14950  // Grisu2 generates the digits of M+ from left to right and stops as soon as
14951  // V is in [M-,M+].
14952 
14953  JSON_ASSERT(M_plus.e >= kAlpha);
14954  JSON_ASSERT(M_plus.e <= kGamma);
14955 
14956  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14957  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
14958 
14959  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14960  //
14961  // M+ = f * 2^e
14962  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14963  // = ((p1 ) * 2^-e + (p2 )) * 2^e
14964  // = p1 + p2 * 2^e
14965 
14966  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14967 
14968  auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
14969  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
14970 
14971  // 1)
14972  //
14973  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14974 
14975  JSON_ASSERT(p1 > 0);
14976 
14977  std::uint32_t pow10;
14978  const int k = find_largest_pow10(p1, pow10);
14979 
14980  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14981  //
14982  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14983  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
14984  //
14985  // M+ = p1 + p2 * 2^e
14986  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
14987  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14988  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
14989  //
14990  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14991  //
14992  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14993  //
14994  // but stop as soon as
14995  //
14996  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14997 
14998  int n = k;
14999  while (n > 0)
15000  {
15001  // Invariants:
15002  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15003  // pow10 = 10^(n-1) <= p1 < 10^n
15004  //
15005  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15006  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15007  //
15008  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15009  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15010  //
15011  JSON_ASSERT(d <= 9);
15012  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15013  //
15014  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15015  //
15016  p1 = r;
15017  n--;
15018  //
15019  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15020  // pow10 = 10^n
15021  //
15022 
15023  // Now check if enough digits have been generated.
15024  // Compute
15025  //
15026  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15027  //
15028  // Note:
15029  // Since rest and delta share the same exponent e, it suffices to
15030  // compare the significands.
15031  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15032  if (rest <= delta)
15033  {
15034  // V = buffer * 10^n, with M- <= V <= M+.
15035 
15036  decimal_exponent += n;
15037 
15038  // We may now just stop. But instead look if the buffer could be
15039  // decremented to bring V closer to w.
15040  //
15041  // pow10 = 10^n is now 1 ulp in the decimal representation V.
15042  // The rounding procedure works with diyfp's with an implicit
15043  // exponent of e.
15044  //
15045  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15046  //
15047  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15048  grisu2_round(buffer, length, dist, delta, rest, ten_n);
15049 
15050  return;
15051  }
15052 
15053  pow10 /= 10;
15054  //
15055  // pow10 = 10^(n-1) <= p1 < 10^n
15056  // Invariants restored.
15057  }
15058 
15059  // 2)
15060  //
15061  // The digits of the integral part have been generated:
15062  //
15063  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15064  // = buffer + p2 * 2^e
15065  //
15066  // Now generate the digits of the fractional part p2 * 2^e.
15067  //
15068  // Note:
15069  // No decimal point is generated: the exponent is adjusted instead.
15070  //
15071  // p2 actually represents the fraction
15072  //
15073  // p2 * 2^e
15074  // = p2 / 2^-e
15075  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15076  //
15077  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15078  //
15079  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15080  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15081  //
15082  // using
15083  //
15084  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15085  // = ( d) * 2^-e + ( r)
15086  //
15087  // or
15088  // 10^m * p2 * 2^e = d + r * 2^e
15089  //
15090  // i.e.
15091  //
15092  // M+ = buffer + p2 * 2^e
15093  // = buffer + 10^-m * (d + r * 2^e)
15094  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15095  //
15096  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15097 
15098  JSON_ASSERT(p2 > delta);
15099 
15100  int m = 0;
15101  for (;;)
15102  {
15103  // Invariant:
15104  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15105  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15106  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15107  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15108  //
15109  JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15110  p2 *= 10;
15111  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15112  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15113  //
15114  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15115  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15116  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15117  //
15118  JSON_ASSERT(d <= 9);
15119  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15120  //
15121  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15122  //
15123  p2 = r;
15124  m++;
15125  //
15126  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15127  // Invariant restored.
15128 
15129  // Check if enough digits have been generated.
15130  //
15131  // 10^-m * p2 * 2^e <= delta * 2^e
15132  // p2 * 2^e <= 10^m * delta * 2^e
15133  // p2 <= 10^m * delta
15134  delta *= 10;
15135  dist *= 10;
15136  if (p2 <= delta)
15137  {
15138  break;
15139  }
15140  }
15141 
15142  // V = buffer * 10^-m, with M- <= V <= M+.
15143 
15144  decimal_exponent -= m;
15145 
15146  // 1 ulp in the decimal representation is now 10^-m.
15147  // Since delta and dist are now scaled by 10^m, we need to do the
15148  // same with ulp in order to keep the units in sync.
15149  //
15150  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15151  //
15152  const std::uint64_t ten_m = one.f;
15153  grisu2_round(buffer, length, dist, delta, p2, ten_m);
15154 
15155  // By construction this algorithm generates the shortest possible decimal
15156  // number (Loitsch, Theorem 6.2) which rounds back to w.
15157  // For an input number of precision p, at least
15158  //
15159  // N = 1 + ceil(p * log_10(2))
15160  //
15161  // decimal digits are sufficient to identify all binary floating-point
15162  // numbers (Matula, "In-and-Out conversions").
15163  // This implies that the algorithm does not produce more than N decimal
15164  // digits.
15165  //
15166  // N = 17 for p = 53 (IEEE double precision)
15167  // N = 9 for p = 24 (IEEE single precision)
15168 }
15169 
15175 JSON_HEDLEY_NON_NULL(1)
15176 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15177  diyfp m_minus, diyfp v, diyfp m_plus)
15178 {
15179  JSON_ASSERT(m_plus.e == m_minus.e);
15180  JSON_ASSERT(m_plus.e == v.e);
15181 
15182  // --------(-----------------------+-----------------------)-------- (A)
15183  // m- v m+
15184  //
15185  // --------------------(-----------+-----------------------)-------- (B)
15186  // m- v m+
15187  //
15188  // First scale v (and m- and m+) such that the exponent is in the range
15189  // [alpha, gamma].
15190 
15191  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15192 
15193  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15194 
15195  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15196  const diyfp w = diyfp::mul(v, c_minus_k);
15197  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15198  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15199 
15200  // ----(---+---)---------------(---+---)---------------(---+---)----
15201  // w- w w+
15202  // = c*m- = c*v = c*m+
15203  //
15204  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15205  // w+ are now off by a small amount.
15206  // In fact:
15207  //
15208  // w - v * 10^k < 1 ulp
15209  //
15210  // To account for this inaccuracy, add resp. subtract 1 ulp.
15211  //
15212  // --------+---[---------------(---+---)---------------]---+--------
15213  // w- M- w M+ w+
15214  //
15215  // Now any number in [M-, M+] (bounds included) will round to w when input,
15216  // regardless of how the input rounding algorithm breaks ties.
15217  //
15218  // And digit_gen generates the shortest possible such number in [M-, M+].
15219  // Note that this does not mean that Grisu2 always generates the shortest
15220  // possible number in the interval (m-, m+).
15221  const diyfp M_minus(w_minus.f + 1, w_minus.e);
15222  const diyfp M_plus (w_plus.f - 1, w_plus.e );
15223 
15224  decimal_exponent = -cached.k; // = -(-k) = k
15225 
15226  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15227 }
15228 
15234 template<typename FloatType>
15235 JSON_HEDLEY_NON_NULL(1)
15236 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15237 {
15238  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15239  "internal error: not enough precision");
15240 
15241  JSON_ASSERT(std::isfinite(value));
15242  JSON_ASSERT(value > 0);
15243 
15244  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15245  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15246  // decimal representations are not exactly "short".
15247  //
15248  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15249  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15250  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15251  // does.
15252  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15253  // representation using the corresponding std::from_chars function recovers value exactly". That
15254  // indicates that single precision floating-point numbers should be recovered using
15255  // 'std::strtof'.
15256  //
15257  // NB: If the neighbors are computed for single-precision numbers, there is a single float
15258  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15259  // value is off by 1 ulp.
15260 #if 0
15261  const boundaries w = compute_boundaries(static_cast<double>(value));
15262 #else
15263  const boundaries w = compute_boundaries(value);
15264 #endif
15265 
15266  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15267 }
15268 
15274 JSON_HEDLEY_NON_NULL(1)
15275 
15276 inline char* append_exponent(char* buf, int e)
15277 {
15278  JSON_ASSERT(e > -1000);
15279  JSON_ASSERT(e < 1000);
15280 
15281  if (e < 0)
15282  {
15283  e = -e;
15284  *buf++ = '-';
15285  }
15286  else
15287  {
15288  *buf++ = '+';
15289  }
15290 
15291  auto k = static_cast<std::uint32_t>(e);
15292  if (k < 10)
15293  {
15294  // Always print at least two digits in the exponent.
15295  // This is for compatibility with printf("%g").
15296  *buf++ = '0';
15297  *buf++ = static_cast<char>('0' + k);
15298  }
15299  else if (k < 100)
15300  {
15301  *buf++ = static_cast<char>('0' + k / 10);
15302  k %= 10;
15303  *buf++ = static_cast<char>('0' + k);
15304  }
15305  else
15306  {
15307  *buf++ = static_cast<char>('0' + k / 100);
15308  k %= 100;
15309  *buf++ = static_cast<char>('0' + k / 10);
15310  k %= 10;
15311  *buf++ = static_cast<char>('0' + k);
15312  }
15313 
15314  return buf;
15315 }
15316 
15326 JSON_HEDLEY_NON_NULL(1)
15327 
15328 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15329  int min_exp, int max_exp)
15330 {
15331  JSON_ASSERT(min_exp < 0);
15332  JSON_ASSERT(max_exp > 0);
15333 
15334  const int k = len;
15335  const int n = len + decimal_exponent;
15336 
15337  // v = buf * 10^(n-k)
15338  // k is the length of the buffer (number of decimal digits)
15339  // n is the position of the decimal point relative to the start of the buffer.
15340 
15341  if (k <= n && n <= max_exp)
15342  {
15343  // digits[000]
15344  // len <= max_exp + 2
15345 
15346  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15347  // Make it look like a floating-point number (#362, #378)
15348  buf[n + 0] = '.';
15349  buf[n + 1] = '0';
15350  return buf + (static_cast<size_t>(n) + 2);
15351  }
15352 
15353  if (0 < n && n <= max_exp)
15354  {
15355  // dig.its
15356  // len <= max_digits10 + 1
15357 
15358  JSON_ASSERT(k > n);
15359 
15360  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15361  buf[n] = '.';
15362  return buf + (static_cast<size_t>(k) + 1U);
15363  }
15364 
15365  if (min_exp < n && n <= 0)
15366  {
15367  // 0.[000]digits
15368  // len <= 2 + (-min_exp - 1) + max_digits10
15369 
15370  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15371  buf[0] = '0';
15372  buf[1] = '.';
15373  std::memset(buf + 2, '0', static_cast<size_t>(-n));
15374  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15375  }
15376 
15377  if (k == 1)
15378  {
15379  // dE+123
15380  // len <= 1 + 5
15381 
15382  buf += 1;
15383  }
15384  else
15385  {
15386  // d.igitsE+123
15387  // len <= max_digits10 + 1 + 5
15388 
15389  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15390  buf[1] = '.';
15391  buf += 1 + static_cast<size_t>(k);
15392  }
15393 
15394  *buf++ = 'e';
15395  return append_exponent(buf, n - 1);
15396 }
15397 
15398 } // namespace dtoa_impl
15399 
15410 template<typename FloatType>
15411 JSON_HEDLEY_NON_NULL(1, 2)
15412 
15413 char* to_chars(char* first, const char* last, FloatType value)
15414 {
15415  static_cast<void>(last); // maybe unused - fix warning
15416  JSON_ASSERT(std::isfinite(value));
15417 
15418  // Use signbit(value) instead of (value < 0) since signbit works for -0.
15419  if (std::signbit(value))
15420  {
15421  value = -value;
15422  *first++ = '-';
15423  }
15424 
15425  if (value == 0) // +-0
15426  {
15427  *first++ = '0';
15428  // Make it look like a floating-point number (#362, #378)
15429  *first++ = '.';
15430  *first++ = '0';
15431  return first;
15432  }
15433 
15434  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15435 
15436  // Compute v = buffer * 10^decimal_exponent.
15437  // The decimal digits are stored in the buffer, which needs to be interpreted
15438  // as an unsigned decimal integer.
15439  // len is the length of the buffer, i.e. the number of decimal digits.
15440  int len = 0;
15441  int decimal_exponent = 0;
15442  dtoa_impl::grisu2(first, len, decimal_exponent, value);
15443 
15444  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15445 
15446  // Format the buffer like printf("%.*g", prec, value)
15447  constexpr int kMinExp = -4;
15448  // Use digits10 here to increase compatibility with version 2.
15449  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15450 
15451  JSON_ASSERT(last - first >= kMaxExp + 2);
15452  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15453  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15454 
15455  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15456 }
15457 
15458 } // namespace detail
15459 } // namespace nlohmann
15460 
15461 // #include <nlohmann/detail/exceptions.hpp>
15462 
15463 // #include <nlohmann/detail/macro_scope.hpp>
15464 
15465 // #include <nlohmann/detail/meta/cpp_future.hpp>
15466 
15467 // #include <nlohmann/detail/output/binary_writer.hpp>
15468 
15469 // #include <nlohmann/detail/output/output_adapters.hpp>
15470 
15471 // #include <nlohmann/detail/value_t.hpp>
15472 
15473 
15474 namespace nlohmann
15475 {
15476 namespace detail
15477 {
15479 // serialization //
15481 
15483 enum class error_handler_t
15484 {
15485  strict,
15486  replace,
15487  ignore
15488 };
15489 
15490 template<typename BasicJsonType>
15491 class serializer
15492 {
15493  using string_t = typename BasicJsonType::string_t;
15494  using number_float_t = typename BasicJsonType::number_float_t;
15495  using number_integer_t = typename BasicJsonType::number_integer_t;
15496  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15497  using binary_char_t = typename BasicJsonType::binary_t::value_type;
15498  static constexpr std::uint8_t UTF8_ACCEPT = 0;
15499  static constexpr std::uint8_t UTF8_REJECT = 1;
15500 
15501  public:
15507  serializer(output_adapter_t<char> s, const char ichar,
15508  error_handler_t error_handler_ = error_handler_t::strict)
15509  : o(std::move(s))
15510  , loc(std::localeconv())
15511  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15512  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15513  , indent_char(ichar)
15514  , indent_string(512, indent_char)
15515  , error_handler(error_handler_)
15516  {}
15517 
15518  // delete because of pointer members
15519  serializer(const serializer&) = delete;
15520  serializer& operator=(const serializer&) = delete;
15521  serializer(serializer&&) = delete;
15522  serializer& operator=(serializer&&) = delete;
15523  ~serializer() = default;
15524 
15547  void dump(const BasicJsonType& val,
15548  const bool pretty_print,
15549  const bool ensure_ascii,
15550  const unsigned int indent_step,
15551  const unsigned int current_indent = 0)
15552  {
15553  switch (val.m_type)
15554  {
15555  case value_t::object:
15556  {
15557  if (val.m_value.object->empty())
15558  {
15559  o->write_characters("{}", 2);
15560  return;
15561  }
15562 
15563  if (pretty_print)
15564  {
15565  o->write_characters("{\n", 2);
15566 
15567  // variable to hold indentation for recursive calls
15568  const auto new_indent = current_indent + indent_step;
15569  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15570  {
15571  indent_string.resize(indent_string.size() * 2, ' ');
15572  }
15573 
15574  // first n-1 elements
15575  auto i = val.m_value.object->cbegin();
15576  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15577  {
15578  o->write_characters(indent_string.c_str(), new_indent);
15579  o->write_character('\"');
15580  dump_escaped(i->first, ensure_ascii);
15581  o->write_characters("\": ", 3);
15582  dump(i->second, true, ensure_ascii, indent_step, new_indent);
15583  o->write_characters(",\n", 2);
15584  }
15585 
15586  // last element
15587  JSON_ASSERT(i != val.m_value.object->cend());
15588  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15589  o->write_characters(indent_string.c_str(), new_indent);
15590  o->write_character('\"');
15591  dump_escaped(i->first, ensure_ascii);
15592  o->write_characters("\": ", 3);
15593  dump(i->second, true, ensure_ascii, indent_step, new_indent);
15594 
15595  o->write_character('\n');
15596  o->write_characters(indent_string.c_str(), current_indent);
15597  o->write_character('}');
15598  }
15599  else
15600  {
15601  o->write_character('{');
15602 
15603  // first n-1 elements
15604  auto i = val.m_value.object->cbegin();
15605  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15606  {
15607  o->write_character('\"');
15608  dump_escaped(i->first, ensure_ascii);
15609  o->write_characters("\":", 2);
15610  dump(i->second, false, ensure_ascii, indent_step, current_indent);
15611  o->write_character(',');
15612  }
15613 
15614  // last element
15615  JSON_ASSERT(i != val.m_value.object->cend());
15616  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15617  o->write_character('\"');
15618  dump_escaped(i->first, ensure_ascii);
15619  o->write_characters("\":", 2);
15620  dump(i->second, false, ensure_ascii, indent_step, current_indent);
15621 
15622  o->write_character('}');
15623  }
15624 
15625  return;
15626  }
15627 
15628  case value_t::array:
15629  {
15630  if (val.m_value.array->empty())
15631  {
15632  o->write_characters("[]", 2);
15633  return;
15634  }
15635 
15636  if (pretty_print)
15637  {
15638  o->write_characters("[\n", 2);
15639 
15640  // variable to hold indentation for recursive calls
15641  const auto new_indent = current_indent + indent_step;
15642  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15643  {
15644  indent_string.resize(indent_string.size() * 2, ' ');
15645  }
15646 
15647  // first n-1 elements
15648  for (auto i = val.m_value.array->cbegin();
15649  i != val.m_value.array->cend() - 1; ++i)
15650  {
15651  o->write_characters(indent_string.c_str(), new_indent);
15652  dump(*i, true, ensure_ascii, indent_step, new_indent);
15653  o->write_characters(",\n", 2);
15654  }
15655 
15656  // last element
15657  JSON_ASSERT(!val.m_value.array->empty());
15658  o->write_characters(indent_string.c_str(), new_indent);
15659  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15660 
15661  o->write_character('\n');
15662  o->write_characters(indent_string.c_str(), current_indent);
15663  o->write_character(']');
15664  }
15665  else
15666  {
15667  o->write_character('[');
15668 
15669  // first n-1 elements
15670  for (auto i = val.m_value.array->cbegin();
15671  i != val.m_value.array->cend() - 1; ++i)
15672  {
15673  dump(*i, false, ensure_ascii, indent_step, current_indent);
15674  o->write_character(',');
15675  }
15676 
15677  // last element
15678  JSON_ASSERT(!val.m_value.array->empty());
15679  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15680 
15681  o->write_character(']');
15682  }
15683 
15684  return;
15685  }
15686 
15687  case value_t::string:
15688  {
15689  o->write_character('\"');
15690  dump_escaped(*val.m_value.string, ensure_ascii);
15691  o->write_character('\"');
15692  return;
15693  }
15694 
15695  case value_t::binary:
15696  {
15697  if (pretty_print)
15698  {
15699  o->write_characters("{\n", 2);
15700 
15701  // variable to hold indentation for recursive calls
15702  const auto new_indent = current_indent + indent_step;
15703  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15704  {
15705  indent_string.resize(indent_string.size() * 2, ' ');
15706  }
15707 
15708  o->write_characters(indent_string.c_str(), new_indent);
15709 
15710  o->write_characters("\"bytes\": [", 10);
15711 
15712  if (!val.m_value.binary->empty())
15713  {
15714  for (auto i = val.m_value.binary->cbegin();
15715  i != val.m_value.binary->cend() - 1; ++i)
15716  {
15717  dump_integer(*i);
15718  o->write_characters(", ", 2);
15719  }
15720  dump_integer(val.m_value.binary->back());
15721  }
15722 
15723  o->write_characters("],\n", 3);
15724  o->write_characters(indent_string.c_str(), new_indent);
15725 
15726  o->write_characters("\"subtype\": ", 11);
15727  if (val.m_value.binary->has_subtype())
15728  {
15729  dump_integer(val.m_value.binary->subtype());
15730  }
15731  else
15732  {
15733  o->write_characters("null", 4);
15734  }
15735  o->write_character('\n');
15736  o->write_characters(indent_string.c_str(), current_indent);
15737  o->write_character('}');
15738  }
15739  else
15740  {
15741  o->write_characters("{\"bytes\":[", 10);
15742 
15743  if (!val.m_value.binary->empty())
15744  {
15745  for (auto i = val.m_value.binary->cbegin();
15746  i != val.m_value.binary->cend() - 1; ++i)
15747  {
15748  dump_integer(*i);
15749  o->write_character(',');
15750  }
15751  dump_integer(val.m_value.binary->back());
15752  }
15753 
15754  o->write_characters("],\"subtype\":", 12);
15755  if (val.m_value.binary->has_subtype())
15756  {
15757  dump_integer(val.m_value.binary->subtype());
15758  o->write_character('}');
15759  }
15760  else
15761  {
15762  o->write_characters("null}", 5);
15763  }
15764  }
15765  return;
15766  }
15767 
15768  case value_t::boolean:
15769  {
15770  if (val.m_value.boolean)
15771  {
15772  o->write_characters("true", 4);
15773  }
15774  else
15775  {
15776  o->write_characters("false", 5);
15777  }
15778  return;
15779  }
15780 
15781  case value_t::number_integer:
15782  {
15783  dump_integer(val.m_value.number_integer);
15784  return;
15785  }
15786 
15787  case value_t::number_unsigned:
15788  {
15789  dump_integer(val.m_value.number_unsigned);
15790  return;
15791  }
15792 
15793  case value_t::number_float:
15794  {
15795  dump_float(val.m_value.number_float);
15796  return;
15797  }
15798 
15799  case value_t::discarded:
15800  {
15801  o->write_characters("<discarded>", 11);
15802  return;
15803  }
15804 
15805  case value_t::null:
15806  {
15807  o->write_characters("null", 4);
15808  return;
15809  }
15810 
15811  default: // LCOV_EXCL_LINE
15812  JSON_ASSERT(false); // LCOV_EXCL_LINE
15813  }
15814  }
15815 
15816  JSON_PRIVATE_UNLESS_TESTED:
15831  void dump_escaped(const string_t& s, const bool ensure_ascii)
15832  {
15833  std::uint32_t codepoint;
15834  std::uint8_t state = UTF8_ACCEPT;
15835  std::size_t bytes = 0; // number of bytes written to string_buffer
15836 
15837  // number of bytes written at the point of the last valid byte
15838  std::size_t bytes_after_last_accept = 0;
15839  std::size_t undumped_chars = 0;
15840 
15841  for (std::size_t i = 0; i < s.size(); ++i)
15842  {
15843  const auto byte = static_cast<uint8_t>(s[i]);
15844 
15845  switch (decode(state, codepoint, byte))
15846  {
15847  case UTF8_ACCEPT: // decode found a new code point
15848  {
15849  switch (codepoint)
15850  {
15851  case 0x08: // backspace
15852  {
15853  string_buffer[bytes++] = '\\';
15854  string_buffer[bytes++] = 'b';
15855  break;
15856  }
15857 
15858  case 0x09: // horizontal tab
15859  {
15860  string_buffer[bytes++] = '\\';
15861  string_buffer[bytes++] = 't';
15862  break;
15863  }
15864 
15865  case 0x0A: // newline
15866  {
15867  string_buffer[bytes++] = '\\';
15868  string_buffer[bytes++] = 'n';
15869  break;
15870  }
15871 
15872  case 0x0C: // formfeed
15873  {
15874  string_buffer[bytes++] = '\\';
15875  string_buffer[bytes++] = 'f';
15876  break;
15877  }
15878 
15879  case 0x0D: // carriage return
15880  {
15881  string_buffer[bytes++] = '\\';
15882  string_buffer[bytes++] = 'r';
15883  break;
15884  }
15885 
15886  case 0x22: // quotation mark
15887  {
15888  string_buffer[bytes++] = '\\';
15889  string_buffer[bytes++] = '\"';
15890  break;
15891  }
15892 
15893  case 0x5C: // reverse solidus
15894  {
15895  string_buffer[bytes++] = '\\';
15896  string_buffer[bytes++] = '\\';
15897  break;
15898  }
15899 
15900  default:
15901  {
15902  // escape control characters (0x00..0x1F) or, if
15903  // ensure_ascii parameter is used, non-ASCII characters
15904  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15905  {
15906  if (codepoint <= 0xFFFF)
15907  {
15908  (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15909  static_cast<std::uint16_t>(codepoint));
15910  bytes += 6;
15911  }
15912  else
15913  {
15914  (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15915  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15916  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15917  bytes += 12;
15918  }
15919  }
15920  else
15921  {
15922  // copy byte to buffer (all previous bytes
15923  // been copied have in default case above)
15924  string_buffer[bytes++] = s[i];
15925  }
15926  break;
15927  }
15928  }
15929 
15930  // write buffer and reset index; there must be 13 bytes
15931  // left, as this is the maximal number of bytes to be
15932  // written ("\uxxxx\uxxxx\0") for one code point
15933  if (string_buffer.size() - bytes < 13)
15934  {
15935  o->write_characters(string_buffer.data(), bytes);
15936  bytes = 0;
15937  }
15938 
15939  // remember the byte position of this accept
15940  bytes_after_last_accept = bytes;
15941  undumped_chars = 0;
15942  break;
15943  }
15944 
15945  case UTF8_REJECT: // decode found invalid UTF-8 byte
15946  {
15947  switch (error_handler)
15948  {
15949  case error_handler_t::strict:
15950  {
15951  std::string sn(3, '\0');
15952  (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15953  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15954  }
15955 
15956  case error_handler_t::ignore:
15957  case error_handler_t::replace:
15958  {
15959  // in case we saw this character the first time, we
15960  // would like to read it again, because the byte
15961  // may be OK for itself, but just not OK for the
15962  // previous sequence
15963  if (undumped_chars > 0)
15964  {
15965  --i;
15966  }
15967 
15968  // reset length buffer to the last accepted index;
15969  // thus removing/ignoring the invalid characters
15970  bytes = bytes_after_last_accept;
15971 
15972  if (error_handler == error_handler_t::replace)
15973  {
15974  // add a replacement character
15975  if (ensure_ascii)
15976  {
15977  string_buffer[bytes++] = '\\';
15978  string_buffer[bytes++] = 'u';
15979  string_buffer[bytes++] = 'f';
15980  string_buffer[bytes++] = 'f';
15981  string_buffer[bytes++] = 'f';
15982  string_buffer[bytes++] = 'd';
15983  }
15984  else
15985  {
15986  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15987  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15988  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15989  }
15990 
15991  // write buffer and reset index; there must be 13 bytes
15992  // left, as this is the maximal number of bytes to be
15993  // written ("\uxxxx\uxxxx\0") for one code point
15994  if (string_buffer.size() - bytes < 13)
15995  {
15996  o->write_characters(string_buffer.data(), bytes);
15997  bytes = 0;
15998  }
15999 
16000  bytes_after_last_accept = bytes;
16001  }
16002 
16003  undumped_chars = 0;
16004 
16005  // continue processing the string
16006  state = UTF8_ACCEPT;
16007  break;
16008  }
16009 
16010  default: // LCOV_EXCL_LINE
16011  JSON_ASSERT(false); // LCOV_EXCL_LINE
16012  }
16013  break;
16014  }
16015 
16016  default: // decode found yet incomplete multi-byte code point
16017  {
16018  if (!ensure_ascii)
16019  {
16020  // code point will not be escaped - copy byte to buffer
16021  string_buffer[bytes++] = s[i];
16022  }
16023  ++undumped_chars;
16024  break;
16025  }
16026  }
16027  }
16028 
16029  // we finished processing the string
16030  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16031  {
16032  // write buffer
16033  if (bytes > 0)
16034  {
16035  o->write_characters(string_buffer.data(), bytes);
16036  }
16037  }
16038  else
16039  {
16040  // we finish reading, but do not accept: string was incomplete
16041  switch (error_handler)
16042  {
16043  case error_handler_t::strict:
16044  {
16045  std::string sn(3, '\0');
16046  (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16047  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16048  }
16049 
16050  case error_handler_t::ignore:
16051  {
16052  // write all accepted bytes
16053  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16054  break;
16055  }
16056 
16057  case error_handler_t::replace:
16058  {
16059  // write all accepted bytes
16060  o->write_characters(string_buffer.data(), bytes_after_last_accept);
16061  // add a replacement character
16062  if (ensure_ascii)
16063  {
16064  o->write_characters("\\ufffd", 6);
16065  }
16066  else
16067  {
16068  o->write_characters("\xEF\xBF\xBD", 3);
16069  }
16070  break;
16071  }
16072 
16073  default: // LCOV_EXCL_LINE
16074  JSON_ASSERT(false); // LCOV_EXCL_LINE
16075  }
16076  }
16077  }
16078 
16079  private:
16088  inline unsigned int count_digits(number_unsigned_t x) noexcept
16089  {
16090  unsigned int n_digits = 1;
16091  for (;;)
16092  {
16093  if (x < 10)
16094  {
16095  return n_digits;
16096  }
16097  if (x < 100)
16098  {
16099  return n_digits + 1;
16100  }
16101  if (x < 1000)
16102  {
16103  return n_digits + 2;
16104  }
16105  if (x < 10000)
16106  {
16107  return n_digits + 3;
16108  }
16109  x = x / 10000u;
16110  n_digits += 4;
16111  }
16112  }
16113 
16123  template < typename NumberType, detail::enable_if_t <
16124  std::is_same<NumberType, number_unsigned_t>::value ||
16125  std::is_same<NumberType, number_integer_t>::value ||
16126  std::is_same<NumberType, binary_char_t>::value,
16127  int > = 0 >
16128  void dump_integer(NumberType x)
16129  {
16130  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16131  {
16132  {
16133  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16134  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16135  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16136  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16137  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16138  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16139  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16140  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16141  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16142  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16143  }
16144  };
16145 
16146  // special case for "0"
16147  if (x == 0)
16148  {
16149  o->write_character('0');
16150  return;
16151  }
16152 
16153  // use a pointer to fill the buffer
16154  auto buffer_ptr = number_buffer.begin();
16155 
16156  const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16157  number_unsigned_t abs_value;
16158 
16159  unsigned int n_chars;
16160 
16161  if (is_negative)
16162  {
16163  *buffer_ptr = '-';
16164  abs_value = remove_sign(static_cast<number_integer_t>(x));
16165 
16166  // account one more byte for the minus sign
16167  n_chars = 1 + count_digits(abs_value);
16168  }
16169  else
16170  {
16171  abs_value = static_cast<number_unsigned_t>(x);
16172  n_chars = count_digits(abs_value);
16173  }
16174 
16175  // spare 1 byte for '\0'
16176  JSON_ASSERT(n_chars < number_buffer.size() - 1);
16177 
16178  // jump to the end to generate the string from backward
16179  // so we later avoid reversing the result
16180  buffer_ptr += n_chars;
16181 
16182  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16183  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16184  while (abs_value >= 100)
16185  {
16186  const auto digits_index = static_cast<unsigned>((abs_value % 100));
16187  abs_value /= 100;
16188  *(--buffer_ptr) = digits_to_99[digits_index][1];
16189  *(--buffer_ptr) = digits_to_99[digits_index][0];
16190  }
16191 
16192  if (abs_value >= 10)
16193  {
16194  const auto digits_index = static_cast<unsigned>(abs_value);
16195  *(--buffer_ptr) = digits_to_99[digits_index][1];
16196  *(--buffer_ptr) = digits_to_99[digits_index][0];
16197  }
16198  else
16199  {
16200  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16201  }
16202 
16203  o->write_characters(number_buffer.data(), n_chars);
16204  }
16205 
16214  void dump_float(number_float_t x)
16215  {
16216  // NaN / inf
16217  if (!std::isfinite(x))
16218  {
16219  o->write_characters("null", 4);
16220  return;
16221  }
16222 
16223  // If number_float_t is an IEEE-754 single or double precision number,
16224  // use the Grisu2 algorithm to produce short numbers which are
16225  // guaranteed to round-trip, using strtof and strtod, resp.
16226  //
16227  // NB: The test below works if <long double> == <double>.
16228  static constexpr bool is_ieee_single_or_double
16229  = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
16230  (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
16231 
16232  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16233  }
16234 
16235  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16236  {
16237  char* begin = number_buffer.data();
16238  char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16239 
16240  o->write_characters(begin, static_cast<size_t>(end - begin));
16241  }
16242 
16243  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16244  {
16245  // get number of digits for a float -> text -> float round-trip
16246  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16247 
16248  // the actual conversion
16249  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16250 
16251  // negative value indicates an error
16252  JSON_ASSERT(len > 0);
16253  // check if buffer was large enough
16254  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16255 
16256  // erase thousands separator
16257  if (thousands_sep != '\0')
16258  {
16259  const auto end = std::remove(number_buffer.begin(),
16260  number_buffer.begin() + len, thousands_sep);
16261  std::fill(end, number_buffer.end(), '\0');
16262  JSON_ASSERT((end - number_buffer.begin()) <= len);
16263  len = (end - number_buffer.begin());
16264  }
16265 
16266  // convert decimal point to '.'
16267  if (decimal_point != '\0' && decimal_point != '.')
16268  {
16269  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16270  if (dec_pos != number_buffer.end())
16271  {
16272  *dec_pos = '.';
16273  }
16274  }
16275 
16276  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16277 
16278  // determine if need to append ".0"
16279  const bool value_is_int_like =
16280  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16281  [](char c)
16282  {
16283  return c == '.' || c == 'e';
16284  });
16285 
16286  if (value_is_int_like)
16287  {
16288  o->write_characters(".0", 2);
16289  }
16290  }
16291 
16313  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16314  {
16315  static const std::array<std::uint8_t, 400> utf8d =
16316  {
16317  {
16318  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
16319  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
16320  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
16321  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
16322  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
16323  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
16324  8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
16325  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16326  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16327  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16328  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
16329  1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
16330  1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
16331  1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
16332  }
16333  };
16334 
16335  const std::uint8_t type = utf8d[byte];
16336 
16337  codep = (state != UTF8_ACCEPT)
16338  ? (byte & 0x3fu) | (codep << 6u)
16339  : (0xFFu >> type) & (byte);
16340 
16341  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16342  JSON_ASSERT(index < 400);
16343  state = utf8d[index];
16344  return state;
16345  }
16346 
16347  /*
16348  * Overload to make the compiler happy while it is instantiating
16349  * dump_integer for number_unsigned_t.
16350  * Must never be called.
16351  */
16352  number_unsigned_t remove_sign(number_unsigned_t x)
16353  {
16354  JSON_ASSERT(false); // LCOV_EXCL_LINE
16355  return x; // LCOV_EXCL_LINE
16356  }
16357 
16358  /*
16359  * Helper function for dump_integer
16360  *
16361  * This function takes a negative signed integer and returns its absolute
16362  * value as unsigned integer. The plus/minus shuffling is necessary as we can
16363  * not directly remove the sign of an arbitrary signed integer as the
16364  * absolute values of INT_MIN and INT_MAX are usually not the same. See
16365  * #1708 for details.
16366  */
16367  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16368  {
16369  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
16370  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16371  }
16372 
16373  private:
16375  output_adapter_t<char> o = nullptr;
16376 
16378  std::array<char, 64> number_buffer{{}};
16379 
16381  const std::lconv* loc = nullptr;
16383  const char thousands_sep = '\0';
16385  const char decimal_point = '\0';
16386 
16388  std::array<char, 512> string_buffer{{}};
16389 
16391  const char indent_char;
16393  string_t indent_string;
16394 
16396  const error_handler_t error_handler;
16397 };
16398 } // namespace detail
16399 } // namespace nlohmann
16400 
16401 // #include <nlohmann/detail/value_t.hpp>
16402 
16403 // #include <nlohmann/json_fwd.hpp>
16404 
16405 // #include <nlohmann/ordered_map.hpp>
16406 
16407 
16408 #include <functional> // less
16409 #include <memory> // allocator
16410 #include <utility> // pair
16411 #include <vector> // vector
16412 
16413 // #include <nlohmann/detail/macro_scope.hpp>
16414 
16415 
16416 namespace nlohmann
16417 {
16418 
16421 template <class Key, class T, class IgnoredLess = std::less<Key>,
16422  class Allocator = std::allocator<std::pair<const Key, T>>>
16423  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16424 {
16425  using key_type = Key;
16426  using mapped_type = T;
16427  using Container = std::vector<std::pair<const Key, T>, Allocator>;
16428  using typename Container::iterator;
16429  using typename Container::const_iterator;
16430  using typename Container::size_type;
16431  using typename Container::value_type;
16432 
16433  // Explicit constructors instead of `using Container::Container`
16434  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
16435  ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16436  template <class It>
16437  ordered_map(It first, It last, const Allocator& alloc = Allocator())
16438  : Container{first, last, alloc} {}
16439  ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16440  : Container{init, alloc} {}
16441 
16442  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16443  {
16444  for (auto it = this->begin(); it != this->end(); ++it)
16445  {
16446  if (it->first == key)
16447  {
16448  return {it, false};
16449  }
16450  }
16451  Container::emplace_back(key, t);
16452  return {--this->end(), true};
16453  }
16454 
16455  T& operator[](const Key& key)
16456  {
16457  return emplace(key, T{}).first->second;
16458  }
16459 
16460  const T& operator[](const Key& key) const
16461  {
16462  return at(key);
16463  }
16464 
16465  T& at(const Key& key)
16466  {
16467  for (auto it = this->begin(); it != this->end(); ++it)
16468  {
16469  if (it->first == key)
16470  {
16471  return it->second;
16472  }
16473  }
16474 
16475  JSON_THROW(std::out_of_range("key not found"));
16476  }
16477 
16478  const T& at(const Key& key) const
16479  {
16480  for (auto it = this->begin(); it != this->end(); ++it)
16481  {
16482  if (it->first == key)
16483  {
16484  return it->second;
16485  }
16486  }
16487 
16488  JSON_THROW(std::out_of_range("key not found"));
16489  }
16490 
16491  size_type erase(const Key& key)
16492  {
16493  for (auto it = this->begin(); it != this->end(); ++it)
16494  {
16495  if (it->first == key)
16496  {
16497  // Since we cannot move const Keys, re-construct them in place
16498  for (auto next = it; ++next != this->end(); ++it)
16499  {
16500  it->~value_type(); // Destroy but keep allocation
16501  new (&*it) value_type{std::move(*next)};
16502  }
16503  Container::pop_back();
16504  return 1;
16505  }
16506  }
16507  return 0;
16508  }
16509 
16510  iterator erase(iterator pos)
16511  {
16512  auto it = pos;
16513 
16514  // Since we cannot move const Keys, re-construct them in place
16515  for (auto next = it; ++next != this->end(); ++it)
16516  {
16517  it->~value_type(); // Destroy but keep allocation
16518  new (&*it) value_type{std::move(*next)};
16519  }
16520  Container::pop_back();
16521  return pos;
16522  }
16523 
16524  size_type count(const Key& key) const
16525  {
16526  for (auto it = this->begin(); it != this->end(); ++it)
16527  {
16528  if (it->first == key)
16529  {
16530  return 1;
16531  }
16532  }
16533  return 0;
16534  }
16535 
16536  iterator find(const Key& key)
16537  {
16538  for (auto it = this->begin(); it != this->end(); ++it)
16539  {
16540  if (it->first == key)
16541  {
16542  return it;
16543  }
16544  }
16545  return Container::end();
16546  }
16547 
16548  const_iterator find(const Key& key) const
16549  {
16550  for (auto it = this->begin(); it != this->end(); ++it)
16551  {
16552  if (it->first == key)
16553  {
16554  return it;
16555  }
16556  }
16557  return Container::end();
16558  }
16559 
16560  std::pair<iterator, bool> insert( value_type&& value )
16561  {
16562  return emplace(value.first, std::move(value.second));
16563  }
16564 
16565  std::pair<iterator, bool> insert( const value_type& value )
16566  {
16567  for (auto it = this->begin(); it != this->end(); ++it)
16568  {
16569  if (it->first == value.first)
16570  {
16571  return {it, false};
16572  }
16573  }
16574  Container::push_back(value);
16575  return {--this->end(), true};
16576  }
16577 };
16578 
16579 } // namespace nlohmann
16580 
16581 
16587 namespace nlohmann
16588 {
16589 
16674 NLOHMANN_BASIC_JSON_TPL_DECLARATION
16676 {
16677  private:
16678  template<detail::value_t> friend struct detail::external_constructor;
16679  friend ::nlohmann::json_pointer<basic_json>;
16680 
16681  template<typename BasicJsonType, typename InputType>
16682  friend class ::nlohmann::detail::parser;
16683  friend ::nlohmann::detail::serializer<basic_json>;
16684  template<typename BasicJsonType>
16685  friend class ::nlohmann::detail::iter_impl;
16686  template<typename BasicJsonType, typename CharType>
16687  friend class ::nlohmann::detail::binary_writer;
16688  template<typename BasicJsonType, typename InputType, typename SAX>
16689  friend class ::nlohmann::detail::binary_reader;
16690  template<typename BasicJsonType>
16691  friend class ::nlohmann::detail::json_sax_dom_parser;
16692  template<typename BasicJsonType>
16693  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16694 
16696  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16697 
16698  JSON_PRIVATE_UNLESS_TESTED:
16699  // convenience aliases for types residing in namespace detail;
16700  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16701 
16702  template<typename InputAdapterType>
16703  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16704  InputAdapterType adapter,
16705  detail::parser_callback_t<basic_json>cb = nullptr,
16706  const bool allow_exceptions = true,
16707  const bool ignore_comments = false
16708  )
16709  {
16710  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16711  std::move(cb), allow_exceptions, ignore_comments);
16712  }
16713 
16714  private:
16715  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16716  template<typename BasicJsonType>
16717  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16718  template<typename BasicJsonType>
16719  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16720  template<typename Iterator>
16721  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16722  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16723 
16724  template<typename CharType>
16725  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16726 
16727  template<typename InputType>
16728  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16729  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16730 
16731  JSON_PRIVATE_UNLESS_TESTED:
16732  using serializer = ::nlohmann::detail::serializer<basic_json>;
16733 
16734  public:
16735  using value_t = detail::value_t;
16738  template<typename T, typename SFINAE>
16739  using json_serializer = JSONSerializer<T, SFINAE>;
16741  using error_handler_t = detail::error_handler_t;
16743  using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16745  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16746 
16747  using input_format_t = detail::input_format_t;
16750 
16752  // exceptions //
16754 
16758 
16760  using exception = detail::exception;
16762  using parse_error = detail::parse_error;
16764  using invalid_iterator = detail::invalid_iterator;
16766  using type_error = detail::type_error;
16768  using out_of_range = detail::out_of_range;
16770  using other_error = detail::other_error;
16771 
16773 
16774 
16776  // container types //
16778 
16783 
16786 
16790  using const_reference = const value_type&;
16791 
16793  using difference_type = std::ptrdiff_t;
16795  using size_type = std::size_t;
16796 
16798  using allocator_type = AllocatorType<basic_json>;
16799 
16801  using pointer = typename std::allocator_traits<allocator_type>::pointer;
16803  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16804 
16806  using iterator = iter_impl<basic_json>;
16808  using const_iterator = iter_impl<const basic_json>;
16810  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16812  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16813 
16815 
16816 
16821  {
16822  return allocator_type();
16823  }
16824 
16851 
16852  static basic_json meta()
16853  {
16854  basic_json result;
16855 
16856  result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16857  result["name"] = "JSON for Modern C++";
16858  result["url"] = "https://github.com/nlohmann/json";
16859  result["version"]["string"] =
16860  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16861  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16862  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16863  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16864  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16865  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16866 
16867 #ifdef _WIN32
16868  result["platform"] = "win32";
16869 #elif defined __linux__
16870  result["platform"] = "linux";
16871 #elif defined __APPLE__
16872  result["platform"] = "apple";
16873 #elif defined __unix__
16874  result["platform"] = "unix";
16875 #else
16876  result["platform"] = "unknown";
16877 #endif
16878 
16879 #if defined(__ICC) || defined(__INTEL_COMPILER)
16880  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16881 #elif defined(__clang__)
16882  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16883 #elif defined(__GNUC__) || defined(__GNUG__)
16884  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16885 #elif defined(__HP_cc) || defined(__HP_aCC)
16886  result["compiler"] = "hp"
16887 #elif defined(__IBMCPP__)
16888  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16889 #elif defined(_MSC_VER)
16890  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16891 #elif defined(__PGI)
16892  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16893 #elif defined(__SUNPRO_CC)
16894  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16895 #else
16896  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16897 #endif
16898 
16899 #ifdef __cplusplus
16900  result["compiler"]["c++"] = std::to_string(__cplusplus);
16901 #else
16902  result["compiler"]["c++"] = "unknown";
16903 #endif
16904  return result;
16905  }
16906 
16907 
16909  // JSON value data types //
16911 
16916 
16917 #if defined(JSON_HAS_CPP_14)
16918  // Use transparent comparator if possible, combined with perfect forwarding
16919  // on find() and count() calls prevents unnecessary string construction.
16920  using object_comparator_t = std::less<>;
16921 #else
16922  using object_comparator_t = std::less<StringType>;
16923 #endif
16924 
17008  using object_t = ObjectType<StringType,
17009  basic_json,
17011  AllocatorType<std::pair<const StringType,
17012  basic_json>>>;
17013 
17058  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17059 
17111  using string_t = StringType;
17112 
17137  using boolean_t = BooleanType;
17138 
17209  using number_integer_t = NumberIntegerType;
17210 
17280  using number_unsigned_t = NumberUnsignedType;
17281 
17348  using number_float_t = NumberFloatType;
17349 
17421 
17422  private:
17423 
17425  template<typename T, typename... Args>
17426 
17427  static T* create(Args&& ... args)
17428  {
17429  AllocatorType<T> alloc;
17430  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17431 
17432  auto deleter = [&](T * object)
17433  {
17434  AllocatorTraits::deallocate(alloc, object, 1);
17435  };
17436  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17437  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17438  JSON_ASSERT(object != nullptr);
17439  return object.release();
17440  }
17441 
17443  // JSON value storage //
17445 
17446  JSON_PRIVATE_UNLESS_TESTED:
17472  union json_value
17473  {
17475  object_t* object;
17477  array_t* array;
17479  string_t* string;
17481  binary_t* binary;
17483  boolean_t boolean;
17485  number_integer_t number_integer;
17487  number_unsigned_t number_unsigned;
17489  number_float_t number_float;
17490 
17492  json_value() = default;
17494  json_value(boolean_t v) noexcept : boolean(v) {}
17496  json_value(number_integer_t v) noexcept : number_integer(v) {}
17498  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17500  json_value(number_float_t v) noexcept : number_float(v) {}
17502  json_value(value_t t)
17503  {
17504  switch (t)
17505  {
17506  case value_t::object:
17507  {
17508  object = create<object_t>();
17509  break;
17510  }
17511 
17512  case value_t::array:
17513  {
17514  array = create<array_t>();
17515  break;
17516  }
17517 
17518  case value_t::string:
17519  {
17520  string = create<string_t>("");
17521  break;
17522  }
17523 
17524  case value_t::binary:
17525  {
17526  binary = create<binary_t>();
17527  break;
17528  }
17529 
17530  case value_t::boolean:
17531  {
17532  boolean = boolean_t(false);
17533  break;
17534  }
17535 
17536  case value_t::number_integer:
17537  {
17538  number_integer = number_integer_t(0);
17539  break;
17540  }
17541 
17542  case value_t::number_unsigned:
17543  {
17544  number_unsigned = number_unsigned_t(0);
17545  break;
17546  }
17547 
17548  case value_t::number_float:
17549  {
17550  number_float = number_float_t(0.0);
17551  break;
17552  }
17553 
17554  case value_t::null:
17555  {
17556  object = nullptr; // silence warning, see #821
17557  break;
17558  }
17559 
17560  default:
17561  {
17562  object = nullptr; // silence warning, see #821
17563  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17564  {
17565  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17566  }
17567  break;
17568  }
17569  }
17570  }
17571 
17573  json_value(const string_t& value)
17574  {
17575  string = create<string_t>(value);
17576  }
17577 
17579  json_value(string_t&& value)
17580  {
17581  string = create<string_t>(std::move(value));
17582  }
17583 
17585  json_value(const object_t& value)
17586  {
17587  object = create<object_t>(value);
17588  }
17589 
17591  json_value(object_t&& value)
17592  {
17593  object = create<object_t>(std::move(value));
17594  }
17595 
17597  json_value(const array_t& value)
17598  {
17599  array = create<array_t>(value);
17600  }
17601 
17603  json_value(array_t&& value)
17604  {
17605  array = create<array_t>(std::move(value));
17606  }
17607 
17609  json_value(const typename binary_t::container_type& value)
17610  {
17611  binary = create<binary_t>(value);
17612  }
17613 
17615  json_value(typename binary_t::container_type&& value)
17616  {
17617  binary = create<binary_t>(std::move(value));
17618  }
17619 
17621  json_value(const binary_t& value)
17622  {
17623  binary = create<binary_t>(value);
17624  }
17625 
17627  json_value(binary_t&& value)
17628  {
17629  binary = create<binary_t>(std::move(value));
17630  }
17631 
17632  void destroy(value_t t) noexcept
17633  {
17634  // flatten the current json_value to a heap-allocated stack
17635  std::vector<basic_json> stack;
17636 
17637  // move the top-level items to stack
17638  if (t == value_t::array)
17639  {
17640  stack.reserve(array->size());
17641  std::move(array->begin(), array->end(), std::back_inserter(stack));
17642  }
17643  else if (t == value_t::object)
17644  {
17645  stack.reserve(object->size());
17646  for (auto&& it : *object)
17647  {
17648  stack.push_back(std::move(it.second));
17649  }
17650  }
17651 
17652  while (!stack.empty())
17653  {
17654  // move the last item to local variable to be processed
17655  basic_json current_item(std::move(stack.back()));
17656  stack.pop_back();
17657 
17658  // if current_item is array/object, move
17659  // its children to the stack to be processed later
17660  if (current_item.is_array())
17661  {
17662  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17663  std::back_inserter(stack));
17664 
17665  current_item.m_value.array->clear();
17666  }
17667  else if (current_item.is_object())
17668  {
17669  for (auto&& it : *current_item.m_value.object)
17670  {
17671  stack.push_back(std::move(it.second));
17672  }
17673 
17674  current_item.m_value.object->clear();
17675  }
17676 
17677  // it's now safe that current_item get destructed
17678  // since it doesn't have any children
17679  }
17680 
17681  switch (t)
17682  {
17683  case value_t::object:
17684  {
17685  AllocatorType<object_t> alloc;
17686  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17687  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17688  break;
17689  }
17690 
17691  case value_t::array:
17692  {
17693  AllocatorType<array_t> alloc;
17694  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17695  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17696  break;
17697  }
17698 
17699  case value_t::string:
17700  {
17701  AllocatorType<string_t> alloc;
17702  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17703  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17704  break;
17705  }
17706 
17707  case value_t::binary:
17708  {
17709  AllocatorType<binary_t> alloc;
17710  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17711  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17712  break;
17713  }
17714 
17715  default:
17716  {
17717  break;
17718  }
17719  }
17720  }
17721  };
17722 
17723  private:
17733  void assert_invariant() const noexcept
17734  {
17735  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17736  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17737  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17738  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17739  }
17740 
17741  public:
17743  // JSON parser callback //
17745 
17761  using parse_event_t = detail::parse_event_t;
17762 
17812  using parser_callback_t = detail::parser_callback_t<basic_json>;
17813 
17815  // constructors //
17817 
17822 
17853  basic_json(const value_t v)
17854  : m_type(v), m_value(v)
17855  {
17856  assert_invariant();
17857  }
17858 
17877  basic_json(std::nullptr_t = nullptr) noexcept
17878  : basic_json(value_t::null)
17879  {
17880  assert_invariant();
17881  }
17882 
17946  template < typename CompatibleType,
17947  typename U = detail::uncvref_t<CompatibleType>,
17948  detail::enable_if_t <
17949  !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
17950  basic_json(CompatibleType && val) noexcept(noexcept(
17951  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17952  std::forward<CompatibleType>(val))))
17953  {
17954  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17955  assert_invariant();
17956  }
17957 
17984  template < typename BasicJsonType,
17985  detail::enable_if_t <
17986  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
17987  basic_json(const BasicJsonType& val)
17988  {
17989  using other_boolean_t = typename BasicJsonType::boolean_t;
17990  using other_number_float_t = typename BasicJsonType::number_float_t;
17991  using other_number_integer_t = typename BasicJsonType::number_integer_t;
17992  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17993  using other_string_t = typename BasicJsonType::string_t;
17994  using other_object_t = typename BasicJsonType::object_t;
17995  using other_array_t = typename BasicJsonType::array_t;
17996  using other_binary_t = typename BasicJsonType::binary_t;
17997 
17998  switch (val.type())
17999  {
18000  case value_t::boolean:
18001  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18002  break;
18003  case value_t::number_float:
18004  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18005  break;
18006  case value_t::number_integer:
18007  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18008  break;
18009  case value_t::number_unsigned:
18010  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18011  break;
18012  case value_t::string:
18013  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18014  break;
18015  case value_t::object:
18016  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18017  break;
18018  case value_t::array:
18019  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18020  break;
18021  case value_t::binary:
18022  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18023  break;
18024  case value_t::null:
18025  *this = nullptr;
18026  break;
18027  case value_t::discarded:
18028  m_type = value_t::discarded;
18029  break;
18030  default: // LCOV_EXCL_LINE
18031  JSON_ASSERT(false); // LCOV_EXCL_LINE
18032  }
18033  assert_invariant();
18034  }
18035 
18111  bool type_deduction = true,
18112  value_t manual_type = value_t::array)
18113  {
18114  // check if each element is an array with two elements whose first
18115  // element is a string
18116  bool is_an_object = std::all_of(init.begin(), init.end(),
18117  [](const detail::json_ref<basic_json>& element_ref)
18118  {
18119  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18120  });
18121 
18122  // adjust type if type deduction is not wanted
18123  if (!type_deduction)
18124  {
18125  // if array is wanted, do not create an object though possible
18126  if (manual_type == value_t::array)
18127  {
18128  is_an_object = false;
18129  }
18130 
18131  // if object is wanted but impossible, throw an exception
18132  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18133  {
18134  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18135  }
18136  }
18137 
18138  if (is_an_object)
18139  {
18140  // the initializer list is a list of pairs -> create object
18141  m_type = value_t::object;
18142  m_value = value_t::object;
18143 
18144  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18145  {
18146  auto element = element_ref.moved_or_copied();
18147  m_value.object->emplace(
18148  std::move(*((*element.m_value.array)[0].m_value.string)),
18149  std::move((*element.m_value.array)[1]));
18150  });
18151  }
18152  else
18153  {
18154  // the initializer list describes an array -> create array
18155  m_type = value_t::array;
18156  m_value.array = create<array_t>(init.begin(), init.end());
18157  }
18158 
18159  assert_invariant();
18160  }
18161 
18189 
18190  static basic_json binary(const typename binary_t::container_type& init)
18191  {
18192  auto res = basic_json();
18193  res.m_type = value_t::binary;
18194  res.m_value = init;
18195  return res;
18196  }
18197 
18226 
18227  static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18228  {
18229  auto res = basic_json();
18230  res.m_type = value_t::binary;
18231  res.m_value = binary_t(init, subtype);
18232  return res;
18233  }
18234 
18236 
18238  {
18239  auto res = basic_json();
18240  res.m_type = value_t::binary;
18241  res.m_value = std::move(init);
18242  return res;
18243  }
18244 
18246 
18247  static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18248  {
18249  auto res = basic_json();
18250  res.m_type = value_t::binary;
18251  res.m_value = binary_t(std::move(init), subtype);
18252  return res;
18253  }
18254 
18292 
18294  {
18295  return basic_json(init, false, value_t::array);
18296  }
18297 
18336 
18338  {
18339  return basic_json(init, false, value_t::object);
18340  }
18341 
18365  : m_type(value_t::array)
18366  {
18367  m_value.array = create<array_t>(cnt, val);
18368  assert_invariant();
18369  }
18370 
18426  template < class InputIT, typename std::enable_if <
18427  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18428  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18429  basic_json(InputIT first, InputIT last)
18430  {
18431  JSON_ASSERT(first.m_object != nullptr);
18432  JSON_ASSERT(last.m_object != nullptr);
18433 
18434  // make sure iterator fits the current value
18435  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18436  {
18437  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18438  }
18439 
18440  // copy type from first iterator
18441  m_type = first.m_object->m_type;
18442 
18443  // check if iterator range is complete for primitive values
18444  switch (m_type)
18445  {
18446  case value_t::boolean:
18447  case value_t::number_float:
18448  case value_t::number_integer:
18449  case value_t::number_unsigned:
18450  case value_t::string:
18451  {
18452  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18453  || !last.m_it.primitive_iterator.is_end()))
18454  {
18455  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18456  }
18457  break;
18458  }
18459 
18460  default:
18461  break;
18462  }
18463 
18464  switch (m_type)
18465  {
18466  case value_t::number_integer:
18467  {
18468  m_value.number_integer = first.m_object->m_value.number_integer;
18469  break;
18470  }
18471 
18472  case value_t::number_unsigned:
18473  {
18474  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18475  break;
18476  }
18477 
18478  case value_t::number_float:
18479  {
18480  m_value.number_float = first.m_object->m_value.number_float;
18481  break;
18482  }
18483 
18484  case value_t::boolean:
18485  {
18486  m_value.boolean = first.m_object->m_value.boolean;
18487  break;
18488  }
18489 
18490  case value_t::string:
18491  {
18492  m_value = *first.m_object->m_value.string;
18493  break;
18494  }
18495 
18496  case value_t::object:
18497  {
18498  m_value.object = create<object_t>(first.m_it.object_iterator,
18499  last.m_it.object_iterator);
18500  break;
18501  }
18502 
18503  case value_t::array:
18504  {
18505  m_value.array = create<array_t>(first.m_it.array_iterator,
18506  last.m_it.array_iterator);
18507  break;
18508  }
18509 
18510  case value_t::binary:
18511  {
18512  m_value = *first.m_object->m_value.binary;
18513  break;
18514  }
18515 
18516  default:
18517  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18518  std::string(first.m_object->type_name())));
18519  }
18520 
18521  assert_invariant();
18522  }
18523 
18524 
18526  // other constructors and destructor //
18528 
18529  template<typename JsonRef,
18530  detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18531  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18532  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18533 
18559  basic_json(const basic_json& other)
18560  : m_type(other.m_type)
18561  {
18562  // check of passed value is valid
18563  other.assert_invariant();
18564 
18565  switch (m_type)
18566  {
18567  case value_t::object:
18568  {
18569  m_value = *other.m_value.object;
18570  break;
18571  }
18572 
18573  case value_t::array:
18574  {
18575  m_value = *other.m_value.array;
18576  break;
18577  }
18578 
18579  case value_t::string:
18580  {
18581  m_value = *other.m_value.string;
18582  break;
18583  }
18584 
18585  case value_t::boolean:
18586  {
18587  m_value = other.m_value.boolean;
18588  break;
18589  }
18590 
18591  case value_t::number_integer:
18592  {
18593  m_value = other.m_value.number_integer;
18594  break;
18595  }
18596 
18597  case value_t::number_unsigned:
18598  {
18599  m_value = other.m_value.number_unsigned;
18600  break;
18601  }
18602 
18603  case value_t::number_float:
18604  {
18605  m_value = other.m_value.number_float;
18606  break;
18607  }
18608 
18609  case value_t::binary:
18610  {
18611  m_value = *other.m_value.binary;
18612  break;
18613  }
18614 
18615  default:
18616  break;
18617  }
18618 
18619  assert_invariant();
18620  }
18621 
18648  basic_json(basic_json&& other) noexcept
18649  : m_type(std::move(other.m_type)),
18650  m_value(std::move(other.m_value))
18651  {
18652  // check that passed value is valid
18653  other.assert_invariant();
18654 
18655  // invalidate payload
18656  other.m_type = value_t::null;
18657  other.m_value = {};
18658 
18659  assert_invariant();
18660  }
18661 
18685  basic_json& operator=(basic_json other) noexcept (
18686  std::is_nothrow_move_constructible<value_t>::value&&
18687  std::is_nothrow_move_assignable<value_t>::value&&
18688  std::is_nothrow_move_constructible<json_value>::value&&
18689  std::is_nothrow_move_assignable<json_value>::value
18690  )
18691  {
18692  // check that passed value is valid
18693  other.assert_invariant();
18694 
18695  using std::swap;
18696  swap(m_type, other.m_type);
18697  swap(m_value, other.m_value);
18698 
18699  assert_invariant();
18700  return *this;
18701  }
18702 
18718  ~basic_json() noexcept
18719  {
18720  assert_invariant();
18721  m_value.destroy(m_type);
18722  }
18723 
18725 
18726  public:
18728  // object inspection //
18730 
18734 
18782  string_t dump(const int indent = -1,
18783  const char indent_char = ' ',
18784  const bool ensure_ascii = false,
18785  const error_handler_t error_handler = error_handler_t::strict) const
18786  {
18787  string_t result;
18788  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18789 
18790  if (indent >= 0)
18791  {
18792  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18793  }
18794  else
18795  {
18796  s.dump(*this, false, ensure_ascii, 0);
18797  }
18798 
18799  return result;
18800  }
18801 
18835  constexpr value_t type() const noexcept
18836  {
18837  return m_type;
18838  }
18839 
18866  constexpr bool is_primitive() const noexcept
18867  {
18868  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18869  }
18870 
18893  constexpr bool is_structured() const noexcept
18894  {
18895  return is_array() || is_object();
18896  }
18897 
18915  constexpr bool is_null() const noexcept
18916  {
18917  return m_type == value_t::null;
18918  }
18919 
18937  constexpr bool is_boolean() const noexcept
18938  {
18939  return m_type == value_t::boolean;
18940  }
18941 
18967  constexpr bool is_number() const noexcept
18968  {
18969  return is_number_integer() || is_number_float();
18970  }
18971 
18996  constexpr bool is_number_integer() const noexcept
18997  {
18998  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18999  }
19000 
19024  constexpr bool is_number_unsigned() const noexcept
19025  {
19026  return m_type == value_t::number_unsigned;
19027  }
19028 
19052  constexpr bool is_number_float() const noexcept
19053  {
19054  return m_type == value_t::number_float;
19055  }
19056 
19074  constexpr bool is_object() const noexcept
19075  {
19076  return m_type == value_t::object;
19077  }
19078 
19096  constexpr bool is_array() const noexcept
19097  {
19098  return m_type == value_t::array;
19099  }
19100 
19118  constexpr bool is_string() const noexcept
19119  {
19120  return m_type == value_t::string;
19121  }
19122 
19140  constexpr bool is_binary() const noexcept
19141  {
19142  return m_type == value_t::binary;
19143  }
19144 
19167  constexpr bool is_discarded() const noexcept
19168  {
19169  return m_type == value_t::discarded;
19170  }
19171 
19193  constexpr operator value_t() const noexcept
19194  {
19195  return m_type;
19196  }
19197 
19199 
19200  private:
19202  // value access //
19204 
19206  boolean_t get_impl(boolean_t* /*unused*/) const
19207  {
19208  if (JSON_HEDLEY_LIKELY(is_boolean()))
19209  {
19210  return m_value.boolean;
19211  }
19212 
19213  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19214  }
19215 
19217  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19218  {
19219  return is_object() ? m_value.object : nullptr;
19220  }
19221 
19223  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19224  {
19225  return is_object() ? m_value.object : nullptr;
19226  }
19227 
19229  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19230  {
19231  return is_array() ? m_value.array : nullptr;
19232  }
19233 
19235  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19236  {
19237  return is_array() ? m_value.array : nullptr;
19238  }
19239 
19241  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19242  {
19243  return is_string() ? m_value.string : nullptr;
19244  }
19245 
19247  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19248  {
19249  return is_string() ? m_value.string : nullptr;
19250  }
19251 
19253  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19254  {
19255  return is_boolean() ? &m_value.boolean : nullptr;
19256  }
19257 
19259  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19260  {
19261  return is_boolean() ? &m_value.boolean : nullptr;
19262  }
19263 
19265  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19266  {
19267  return is_number_integer() ? &m_value.number_integer : nullptr;
19268  }
19269 
19271  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19272  {
19273  return is_number_integer() ? &m_value.number_integer : nullptr;
19274  }
19275 
19277  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19278  {
19279  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19280  }
19281 
19283  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19284  {
19285  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19286  }
19287 
19289  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19290  {
19291  return is_number_float() ? &m_value.number_float : nullptr;
19292  }
19293 
19295  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19296  {
19297  return is_number_float() ? &m_value.number_float : nullptr;
19298  }
19299 
19301  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19302  {
19303  return is_binary() ? m_value.binary : nullptr;
19304  }
19305 
19307  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19308  {
19309  return is_binary() ? m_value.binary : nullptr;
19310  }
19311 
19323  template<typename ReferenceType, typename ThisType>
19324  static ReferenceType get_ref_impl(ThisType& obj)
19325  {
19326  // delegate the call to get_ptr<>()
19327  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19328 
19329  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19330  {
19331  return *ptr;
19332  }
19333 
19334  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19335  }
19336 
19337  public:
19341 
19356  template<typename BasicJsonType, detail::enable_if_t<
19357  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19358  int> = 0>
19359  basic_json get() const
19360  {
19361  return *this;
19362  }
19363 
19379  template < typename BasicJsonType, detail::enable_if_t <
19380  !std::is_same<BasicJsonType, basic_json>::value&&
19381  detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19382  BasicJsonType get() const
19383  {
19384  return *this;
19385  }
19386 
19426  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19427  detail::enable_if_t <
19428  !detail::is_basic_json<ValueType>::value &&
19429  detail::has_from_json<basic_json_t, ValueType>::value &&
19430  !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19431  int > = 0 >
19432  ValueType get() const noexcept(noexcept(
19433  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19434  {
19435  // we cannot static_assert on ValueTypeCV being non-const, because
19436  // there is support for get<const basic_json_t>(), which is why we
19437  // still need the uncvref
19438  static_assert(!std::is_reference<ValueTypeCV>::value,
19439  "get() cannot be used with reference types, you might want to use get_ref()");
19440  static_assert(std::is_default_constructible<ValueType>::value,
19441  "types must be DefaultConstructible when used with get()");
19442 
19443  ValueType ret;
19444  JSONSerializer<ValueType>::from_json(*this, ret);
19445  return ret;
19446  }
19447 
19479  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19480  detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19481  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19482  int > = 0 >
19483  ValueType get() const noexcept(noexcept(
19484  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19485  {
19486  static_assert(!std::is_reference<ValueTypeCV>::value,
19487  "get() cannot be used with reference types, you might want to use get_ref()");
19488  return JSONSerializer<ValueType>::from_json(*this);
19489  }
19490 
19524  template < typename ValueType,
19525  detail::enable_if_t <
19526  !detail::is_basic_json<ValueType>::value&&
19527  detail::has_from_json<basic_json_t, ValueType>::value,
19528  int > = 0 >
19529  ValueType & get_to(ValueType& v) const noexcept(noexcept(
19530  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19531  {
19532  JSONSerializer<ValueType>::from_json(*this, v);
19533  return v;
19534  }
19535 
19536  // specialization to allow to call get_to with a basic_json value
19537  // see https://github.com/nlohmann/json/issues/2175
19538  template<typename ValueType,
19539  detail::enable_if_t <
19540  detail::is_basic_json<ValueType>::value,
19541  int> = 0>
19542  ValueType & get_to(ValueType& v) const
19543  {
19544  v = *this;
19545  return v;
19546  }
19547 
19548  template <
19549  typename T, std::size_t N,
19550  typename Array = T (&)[N],
19551  detail::enable_if_t <
19552  detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19553  Array get_to(T (&v)[N]) const
19554  noexcept(noexcept(JSONSerializer<Array>::from_json(
19555  std::declval<const basic_json_t&>(), v)))
19556  {
19557  JSONSerializer<Array>::from_json(*this, v);
19558  return v;
19559  }
19560 
19561 
19588  template<typename PointerType, typename std::enable_if<
19589  std::is_pointer<PointerType>::value, int>::type = 0>
19590  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19591  {
19592  // delegate the call to get_impl_ptr<>()
19593  return get_impl_ptr(static_cast<PointerType>(nullptr));
19594  }
19595 
19600  template < typename PointerType, typename std::enable_if <
19601  std::is_pointer<PointerType>::value&&
19602  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
19603  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19604  {
19605  // delegate the call to get_impl_ptr<>() const
19606  return get_impl_ptr(static_cast<PointerType>(nullptr));
19607  }
19608 
19636  template<typename PointerType, typename std::enable_if<
19637  std::is_pointer<PointerType>::value, int>::type = 0>
19638  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19639  {
19640  // delegate the call to get_ptr
19641  return get_ptr<PointerType>();
19642  }
19643 
19648  template<typename PointerType, typename std::enable_if<
19649  std::is_pointer<PointerType>::value, int>::type = 0>
19650  constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19651  {
19652  // delegate the call to get_ptr
19653  return get_ptr<PointerType>();
19654  }
19655 
19682  template<typename ReferenceType, typename std::enable_if<
19683  std::is_reference<ReferenceType>::value, int>::type = 0>
19684  ReferenceType get_ref()
19685  {
19686  // delegate call to get_ref_impl
19687  return get_ref_impl<ReferenceType>(*this);
19688  }
19689 
19694  template < typename ReferenceType, typename std::enable_if <
19695  std::is_reference<ReferenceType>::value&&
19696  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19697  ReferenceType get_ref() const
19698  {
19699  // delegate call to get_ref_impl
19700  return get_ref_impl<ReferenceType>(*this);
19701  }
19702 
19732  template < typename ValueType, typename std::enable_if <
19733  !std::is_pointer<ValueType>::value&&
19734  !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19735  !std::is_same<ValueType, typename string_t::value_type>::value&&
19736  !detail::is_basic_json<ValueType>::value
19737  && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19738 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19739  && !std::is_same<ValueType, typename std::string_view>::value
19740 #endif
19741  && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19742  , int >::type = 0 >
19743  JSON_EXPLICIT operator ValueType() const
19744  {
19745  // delegate the call to get<>() const
19746  return get<ValueType>();
19747  }
19748 
19759  {
19760  if (!is_binary())
19761  {
19762  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19763  }
19764 
19765  return *get_ptr<binary_t*>();
19766  }
19767 
19769  const binary_t& get_binary() const
19770  {
19771  if (!is_binary())
19772  {
19773  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19774  }
19775 
19776  return *get_ptr<const binary_t*>();
19777  }
19778 
19780 
19781 
19783  // element access //
19785 
19789 
19817  {
19818  // at only works for arrays
19819  if (JSON_HEDLEY_LIKELY(is_array()))
19820  {
19821  JSON_TRY
19822  {
19823  return m_value.array->at(idx);
19824  }
19825  JSON_CATCH (std::out_of_range&)
19826  {
19827  // create better exception explanation
19828  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19829  }
19830  }
19831  else
19832  {
19833  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19834  }
19835  }
19836 
19863  const_reference at(size_type idx) const
19864  {
19865  // at only works for arrays
19866  if (JSON_HEDLEY_LIKELY(is_array()))
19867  {
19868  JSON_TRY
19869  {
19870  return m_value.array->at(idx);
19871  }
19872  JSON_CATCH (std::out_of_range&)
19873  {
19874  // create better exception explanation
19875  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19876  }
19877  }
19878  else
19879  {
19880  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19881  }
19882  }
19883 
19914  reference at(const typename object_t::key_type& key)
19915  {
19916  // at only works for objects
19917  if (JSON_HEDLEY_LIKELY(is_object()))
19918  {
19919  JSON_TRY
19920  {
19921  return m_value.object->at(key);
19922  }
19923  JSON_CATCH (std::out_of_range&)
19924  {
19925  // create better exception explanation
19926  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19927  }
19928  }
19929  else
19930  {
19931  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19932  }
19933  }
19934 
19965  const_reference at(const typename object_t::key_type& key) const
19966  {
19967  // at only works for objects
19968  if (JSON_HEDLEY_LIKELY(is_object()))
19969  {
19970  JSON_TRY
19971  {
19972  return m_value.object->at(key);
19973  }
19974  JSON_CATCH (std::out_of_range&)
19975  {
19976  // create better exception explanation
19977  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19978  }
19979  }
19980  else
19981  {
19982  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19983  }
19984  }
19985 
20012  {
20013  // implicitly convert null value to an empty array
20014  if (is_null())
20015  {
20016  m_type = value_t::array;
20017  m_value.array = create<array_t>();
20018  assert_invariant();
20019  }
20020 
20021  // operator[] only works for arrays
20022  if (JSON_HEDLEY_LIKELY(is_array()))
20023  {
20024  // fill up array with null values if given idx is outside range
20025  if (idx >= m_value.array->size())
20026  {
20027  m_value.array->insert(m_value.array->end(),
20028  idx - m_value.array->size() + 1,
20029  basic_json());
20030  }
20031 
20032  return m_value.array->operator[](idx);
20033  }
20034 
20035  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20036  }
20037 
20058  {
20059  // const operator[] only works for arrays
20060  if (JSON_HEDLEY_LIKELY(is_array()))
20061  {
20062  return m_value.array->operator[](idx);
20063  }
20064 
20065  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20066  }
20095  reference operator[](const typename object_t::key_type& key)
20096  {
20097  // implicitly convert null value to an empty object
20098  if (is_null())
20099  {
20100  m_type = value_t::object;
20101  m_value.object = create<object_t>();
20102  assert_invariant();
20103  }
20104 
20105  // operator[] only works for objects
20106  if (JSON_HEDLEY_LIKELY(is_object()))
20107  {
20108  return m_value.object->operator[](key);
20109  }
20110 
20111  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20112  }
20113 
20144  const_reference operator[](const typename object_t::key_type& key) const
20145  {
20146  // const operator[] only works for objects
20147  if (JSON_HEDLEY_LIKELY(is_object()))
20148  {
20149  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20150  return m_value.object->find(key)->second;
20151  }
20152 
20153  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20154  }
20155 
20183  template<typename T>
20184  JSON_HEDLEY_NON_NULL(2)
20185  reference operator[](T* key)
20186  {
20187  // implicitly convert null to object
20188  if (is_null())
20189  {
20190  m_type = value_t::object;
20191  m_value = value_t::object;
20192  assert_invariant();
20193  }
20194 
20195  // at only works for objects
20196  if (JSON_HEDLEY_LIKELY(is_object()))
20197  {
20198  return m_value.object->operator[](key);
20199  }
20200 
20201  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20202  }
20203 
20234  template<typename T>
20235  JSON_HEDLEY_NON_NULL(2)
20236  const_reference operator[](T* key) const
20237  {
20238  // at only works for objects
20239  if (JSON_HEDLEY_LIKELY(is_object()))
20240  {
20241  JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20242  return m_value.object->find(key)->second;
20243  }
20244 
20245  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20246  }
20247 
20298  // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20299  template < class ValueType, typename std::enable_if <
20300  detail::is_getable<basic_json_t, ValueType>::value
20301  && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20302  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20303  {
20304  // at only works for objects
20305  if (JSON_HEDLEY_LIKELY(is_object()))
20306  {
20307  // if key is found, return value and given default value otherwise
20308  const auto it = find(key);
20309  if (it != end())
20310  {
20311  return it->template get<ValueType>();
20312  }
20313 
20314  return default_value;
20315  }
20316 
20317  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20318  }
20319 
20324  string_t value(const typename object_t::key_type& key, const char* default_value) const
20325  {
20326  return value(key, string_t(default_value));
20327  }
20328 
20372  template<class ValueType, typename std::enable_if<
20373  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20374  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20375  {
20376  // at only works for objects
20377  if (JSON_HEDLEY_LIKELY(is_object()))
20378  {
20379  // if pointer resolves a value, return it or use default value
20380  JSON_TRY
20381  {
20382  return ptr.get_checked(this).template get<ValueType>();
20383  }
20384  JSON_INTERNAL_CATCH (out_of_range&)
20385  {
20386  return default_value;
20387  }
20388  }
20389 
20390  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20391  }
20392 
20397  JSON_HEDLEY_NON_NULL(3)
20398  string_t value(const json_pointer& ptr, const char* default_value) const
20399  {
20400  return value(ptr, string_t(default_value));
20401  }
20402 
20428  reference front()
20429  {
20430  return *begin();
20431  }
20432 
20436  const_reference front() const
20437  {
20438  return *cbegin();
20439  }
20440 
20472  reference back()
20473  {
20474  auto tmp = end();
20475  --tmp;
20476  return *tmp;
20477  }
20478 
20483  {
20484  auto tmp = cend();
20485  --tmp;
20486  return *tmp;
20487  }
20488 
20535  template < class IteratorType, typename std::enable_if <
20536  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20537  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20538  = 0 >
20539  IteratorType erase(IteratorType pos)
20540  {
20541  // make sure iterator fits the current value
20542  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20543  {
20544  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20545  }
20546 
20547  IteratorType result = end();
20548 
20549  switch (m_type)
20550  {
20551  case value_t::boolean:
20552  case value_t::number_float:
20553  case value_t::number_integer:
20554  case value_t::number_unsigned:
20555  case value_t::string:
20556  case value_t::binary:
20557  {
20558  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20559  {
20560  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20561  }
20562 
20563  if (is_string())
20564  {
20565  AllocatorType<string_t> alloc;
20566  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20567  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20568  m_value.string = nullptr;
20569  }
20570  else if (is_binary())
20571  {
20572  AllocatorType<binary_t> alloc;
20573  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20574  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20575  m_value.binary = nullptr;
20576  }
20577 
20578  m_type = value_t::null;
20579  assert_invariant();
20580  break;
20581  }
20582 
20583  case value_t::object:
20584  {
20585  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20586  break;
20587  }
20588 
20589  case value_t::array:
20590  {
20591  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20592  break;
20593  }
20594 
20595  default:
20596  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20597  }
20598 
20599  return result;
20600  }
20601 
20648  template < class IteratorType, typename std::enable_if <
20649  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20650  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20651  = 0 >
20652  IteratorType erase(IteratorType first, IteratorType last)
20653  {
20654  // make sure iterator fits the current value
20655  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20656  {
20657  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20658  }
20659 
20660  IteratorType result = end();
20661 
20662  switch (m_type)
20663  {
20664  case value_t::boolean:
20665  case value_t::number_float:
20666  case value_t::number_integer:
20667  case value_t::number_unsigned:
20668  case value_t::string:
20669  case value_t::binary:
20670  {
20671  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20672  || !last.m_it.primitive_iterator.is_end()))
20673  {
20674  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20675  }
20676 
20677  if (is_string())
20678  {
20679  AllocatorType<string_t> alloc;
20680  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20681  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20682  m_value.string = nullptr;
20683  }
20684  else if (is_binary())
20685  {
20686  AllocatorType<binary_t> alloc;
20687  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20688  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20689  m_value.binary = nullptr;
20690  }
20691 
20692  m_type = value_t::null;
20693  assert_invariant();
20694  break;
20695  }
20696 
20697  case value_t::object:
20698  {
20699  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20700  last.m_it.object_iterator);
20701  break;
20702  }
20703 
20704  case value_t::array:
20705  {
20706  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20707  last.m_it.array_iterator);
20708  break;
20709  }
20710 
20711  default:
20712  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20713  }
20714 
20715  return result;
20716  }
20717 
20747  size_type erase(const typename object_t::key_type& key)
20748  {
20749  // this erase only works for objects
20750  if (JSON_HEDLEY_LIKELY(is_object()))
20751  {
20752  return m_value.object->erase(key);
20753  }
20754 
20755  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20756  }
20782  void erase(const size_type idx)
20783  {
20784  // this erase only works for arrays
20785  if (JSON_HEDLEY_LIKELY(is_array()))
20786  {
20787  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20788  {
20789  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20790  }
20791 
20792  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20793  }
20794  else
20795  {
20796  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20797  }
20798  }
20799 
20801 
20802 
20804  // lookup //
20806 
20809 
20834  template<typename KeyT>
20835  iterator find(KeyT&& key)
20836  {
20837  auto result = end();
20838 
20839  if (is_object())
20840  {
20841  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20842  }
20843 
20844  return result;
20845  }
20846 
20851  template<typename KeyT>
20852  const_iterator find(KeyT&& key) const
20853  {
20854  auto result = cend();
20855 
20856  if (is_object())
20857  {
20858  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20859  }
20860 
20861  return result;
20862  }
20863 
20885  template<typename KeyT>
20886  size_type count(KeyT&& key) const
20887  {
20888  // return 0 for all nonobject types
20889  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20890  }
20891 
20917  template < typename KeyT, typename std::enable_if <
20918  !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
20919  bool contains(KeyT && key) const
20920  {
20921  return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20922  }
20923 
20950  bool contains(const json_pointer& ptr) const
20951  {
20952  return ptr.contains(this);
20953  }
20954 
20956 
20957 
20959  // iterators //
20961 
20964 
20989  iterator begin() noexcept
20990  {
20991  iterator result(this);
20992  result.set_begin();
20993  return result;
20994  }
20995 
20999  const_iterator begin() const noexcept
21000  {
21001  return cbegin();
21002  }
21003 
21029  const_iterator cbegin() const noexcept
21030  {
21031  const_iterator result(this);
21032  result.set_begin();
21033  return result;
21034  }
21035 
21060  iterator end() noexcept
21061  {
21062  iterator result(this);
21063  result.set_end();
21064  return result;
21065  }
21066 
21070  const_iterator end() const noexcept
21071  {
21072  return cend();
21073  }
21074 
21100  const_iterator cend() const noexcept
21101  {
21102  const_iterator result(this);
21103  result.set_end();
21104  return result;
21105  }
21106 
21130  reverse_iterator rbegin() noexcept
21131  {
21132  return reverse_iterator(end());
21133  }
21134 
21138  const_reverse_iterator rbegin() const noexcept
21139  {
21140  return crbegin();
21141  }
21142 
21167  reverse_iterator rend() noexcept
21168  {
21169  return reverse_iterator(begin());
21170  }
21171 
21175  const_reverse_iterator rend() const noexcept
21176  {
21177  return crend();
21178  }
21179 
21204  const_reverse_iterator crbegin() const noexcept
21205  {
21206  return const_reverse_iterator(cend());
21207  }
21208 
21233  const_reverse_iterator crend() const noexcept
21234  {
21235  return const_reverse_iterator(cbegin());
21236  }
21237 
21238  public:
21296  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21297  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21298  {
21299  return ref.items();
21300  }
21301 
21305  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21306  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21307  {
21308  return ref.items();
21309  }
21310 
21379  iteration_proxy<iterator> items() noexcept
21380  {
21381  return iteration_proxy<iterator>(*this);
21382  }
21383 
21387  iteration_proxy<const_iterator> items() const noexcept
21388  {
21389  return iteration_proxy<const_iterator>(*this);
21390  }
21391 
21393 
21394 
21396  // capacity //
21398 
21401 
21444  bool empty() const noexcept
21445  {
21446  switch (m_type)
21447  {
21448  case value_t::null:
21449  {
21450  // null values are empty
21451  return true;
21452  }
21453 
21454  case value_t::array:
21455  {
21456  // delegate call to array_t::empty()
21457  return m_value.array->empty();
21458  }
21459 
21460  case value_t::object:
21461  {
21462  // delegate call to object_t::empty()
21463  return m_value.object->empty();
21464  }
21465 
21466  default:
21467  {
21468  // all other types are nonempty
21469  return false;
21470  }
21471  }
21472  }
21473 
21517  size_type size() const noexcept
21518  {
21519  switch (m_type)
21520  {
21521  case value_t::null:
21522  {
21523  // null values are empty
21524  return 0;
21525  }
21526 
21527  case value_t::array:
21528  {
21529  // delegate call to array_t::size()
21530  return m_value.array->size();
21531  }
21532 
21533  case value_t::object:
21534  {
21535  // delegate call to object_t::size()
21536  return m_value.object->size();
21537  }
21538 
21539  default:
21540  {
21541  // all other types have size 1
21542  return 1;
21543  }
21544  }
21545  }
21546 
21588  size_type max_size() const noexcept
21589  {
21590  switch (m_type)
21591  {
21592  case value_t::array:
21593  {
21594  // delegate call to array_t::max_size()
21595  return m_value.array->max_size();
21596  }
21597 
21598  case value_t::object:
21599  {
21600  // delegate call to object_t::max_size()
21601  return m_value.object->max_size();
21602  }
21603 
21604  default:
21605  {
21606  // all other types have max_size() == size()
21607  return size();
21608  }
21609  }
21610  }
21611 
21613 
21614 
21616  // modifiers //
21618 
21621 
21659  void clear() noexcept
21660  {
21661  switch (m_type)
21662  {
21663  case value_t::number_integer:
21664  {
21665  m_value.number_integer = 0;
21666  break;
21667  }
21668 
21669  case value_t::number_unsigned:
21670  {
21671  m_value.number_unsigned = 0;
21672  break;
21673  }
21674 
21675  case value_t::number_float:
21676  {
21677  m_value.number_float = 0.0;
21678  break;
21679  }
21680 
21681  case value_t::boolean:
21682  {
21683  m_value.boolean = false;
21684  break;
21685  }
21686 
21687  case value_t::string:
21688  {
21689  m_value.string->clear();
21690  break;
21691  }
21692 
21693  case value_t::binary:
21694  {
21695  m_value.binary->clear();
21696  break;
21697  }
21698 
21699  case value_t::array:
21700  {
21701  m_value.array->clear();
21702  break;
21703  }
21704 
21705  case value_t::object:
21706  {
21707  m_value.object->clear();
21708  break;
21709  }
21710 
21711  default:
21712  break;
21713  }
21714  }
21715 
21736  void push_back(basic_json&& val)
21737  {
21738  // push_back only works for null objects or arrays
21739  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21740  {
21741  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21742  }
21743 
21744  // transform null object into an array
21745  if (is_null())
21746  {
21747  m_type = value_t::array;
21748  m_value = value_t::array;
21749  assert_invariant();
21750  }
21751 
21752  // add element to array (move semantics)
21753  m_value.array->push_back(std::move(val));
21754  // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21755  }
21756 
21762  {
21763  push_back(std::move(val));
21764  return *this;
21765  }
21766 
21771  void push_back(const basic_json& val)
21772  {
21773  // push_back only works for null objects or arrays
21774  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21775  {
21776  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21777  }
21778 
21779  // transform null object into an array
21780  if (is_null())
21781  {
21782  m_type = value_t::array;
21783  m_value = value_t::array;
21784  assert_invariant();
21785  }
21786 
21787  // add element to array
21788  m_value.array->push_back(val);
21789  }
21790 
21795  reference operator+=(const basic_json& val)
21796  {
21797  push_back(val);
21798  return *this;
21799  }
21800 
21821  void push_back(const typename object_t::value_type& val)
21822  {
21823  // push_back only works for null objects or objects
21824  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21825  {
21826  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21827  }
21828 
21829  // transform null object into an object
21830  if (is_null())
21831  {
21832  m_type = value_t::object;
21833  m_value = value_t::object;
21834  assert_invariant();
21835  }
21836 
21837  // add element to array
21838  m_value.object->insert(val);
21839  }
21840 
21845  reference operator+=(const typename object_t::value_type& val)
21846  {
21847  push_back(val);
21848  return *this;
21849  }
21850 
21876  void push_back(initializer_list_t init)
21877  {
21878  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21879  {
21880  basic_json&& key = init.begin()->moved_or_copied();
21881  push_back(typename object_t::value_type(
21882  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21883  }
21884  else
21885  {
21887  }
21888  }
21889 
21895  {
21896  push_back(init);
21897  return *this;
21898  }
21899 
21923  template<class... Args>
21924  reference emplace_back(Args&& ... args)
21925  {
21926  // emplace_back only works for null objects or arrays
21927  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21928  {
21929  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21930  }
21931 
21932  // transform null object into an array
21933  if (is_null())
21934  {
21935  m_type = value_t::array;
21936  m_value = value_t::array;
21937  assert_invariant();
21938  }
21939 
21940  // add element to array (perfect forwarding)
21941 #ifdef JSON_HAS_CPP_17
21942  return m_value.array->emplace_back(std::forward<Args>(args)...);
21943 #else
21944  m_value.array->emplace_back(std::forward<Args>(args)...);
21945  return m_value.array->back();
21946 #endif
21947  }
21948 
21976  template<class... Args>
21977  std::pair<iterator, bool> emplace(Args&& ... args)
21978  {
21979  // emplace only works for null objects or arrays
21980  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21981  {
21982  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21983  }
21984 
21985  // transform null object into an object
21986  if (is_null())
21987  {
21988  m_type = value_t::object;
21989  m_value = value_t::object;
21990  assert_invariant();
21991  }
21992 
21993  // add element to array (perfect forwarding)
21994  auto res = m_value.object->emplace(std::forward<Args>(args)...);
21995  // create result iterator and set iterator to the result of emplace
21996  auto it = begin();
21997  it.m_it.object_iterator = res.first;
21998 
21999  // return pair of iterator and boolean
22000  return {it, res.second};
22001  }
22002 
22006  template<typename... Args>
22007  iterator insert_iterator(const_iterator pos, Args&& ... args)
22008  {
22009  iterator result(this);
22010  JSON_ASSERT(m_value.array != nullptr);
22011 
22012  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22013  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22014  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22015 
22016  // This could have been written as:
22017  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22018  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22019 
22020  return result;
22021  }
22022 
22045  iterator insert(const_iterator pos, const basic_json& val)
22046  {
22047  // insert only works for arrays
22048  if (JSON_HEDLEY_LIKELY(is_array()))
22049  {
22050  // check if iterator pos fits to this JSON value
22051  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22052  {
22053  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22054  }
22056  // insert to array and return iterator
22057  return insert_iterator(pos, val);
22058  }
22059 
22060  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22061  }
22062 
22068  {
22069  return insert(pos, val);
22070  }
22071 
22096  iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22097  {
22098  // insert only works for arrays
22099  if (JSON_HEDLEY_LIKELY(is_array()))
22100  {
22101  // check if iterator pos fits to this JSON value
22102  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22103  {
22104  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22105  }
22107  // insert to array and return iterator
22108  return insert_iterator(pos, cnt, val);
22109  }
22110 
22111  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22112  }
22113 
22145  {
22146  // insert only works for arrays
22147  if (JSON_HEDLEY_UNLIKELY(!is_array()))
22148  {
22149  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22150  }
22151 
22152  // check if iterator pos fits to this JSON value
22153  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22154  {
22155  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22156  }
22157 
22158  // check if range iterators belong to the same JSON object
22159  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22160  {
22161  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22162  }
22163 
22164  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22165  {
22166  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22167  }
22168 
22169  // insert to array and return iterator
22170  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22171  }
22172 
22198  {
22199  // insert only works for arrays
22200  if (JSON_HEDLEY_UNLIKELY(!is_array()))
22201  {
22202  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22203  }
22204 
22205  // check if iterator pos fits to this JSON value
22206  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22207  {
22208  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22209  }
22210 
22211  // insert to array and return iterator
22212  return insert_iterator(pos, ilist.begin(), ilist.end());
22213  }
22214 
22238  void insert(const_iterator first, const_iterator last)
22239  {
22240  // insert only works for objects
22241  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22242  {
22243  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22244  }
22245 
22246  // check if range iterators belong to the same JSON object
22247  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22248  {
22249  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22250  }
22251 
22252  // passed iterators must belong to objects
22253  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22254  {
22255  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22256  }
22257 
22258  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22259  }
22260 
22280  void update(const_reference j)
22281  {
22282  // implicitly convert null value to an empty object
22283  if (is_null())
22284  {
22285  m_type = value_t::object;
22286  m_value.object = create<object_t>();
22287  assert_invariant();
22288  }
22289 
22290  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22291  {
22292  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22293  }
22294  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22295  {
22296  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22297  }
22298 
22299  for (auto it = j.cbegin(); it != j.cend(); ++it)
22300  {
22301  m_value.object->operator[](it.key()) = it.value();
22302  }
22303  }
22304 
22331  void update(const_iterator first, const_iterator last)
22332  {
22333  // implicitly convert null value to an empty object
22334  if (is_null())
22335  {
22336  m_type = value_t::object;
22337  m_value.object = create<object_t>();
22338  assert_invariant();
22339  }
22340 
22341  if (JSON_HEDLEY_UNLIKELY(!is_object()))
22342  {
22343  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22344  }
22345 
22346  // check if range iterators belong to the same JSON object
22347  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22348  {
22349  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22350  }
22351 
22352  // passed iterators must belong to objects
22353  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22354  || !last.m_object->is_object()))
22355  {
22356  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22357  }
22358 
22359  for (auto it = first; it != last; ++it)
22360  {
22361  m_value.object->operator[](it.key()) = it.value();
22362  }
22363  }
22364 
22382  void swap(reference other) noexcept (
22383  std::is_nothrow_move_constructible<value_t>::value&&
22384  std::is_nothrow_move_assignable<value_t>::value&&
22385  std::is_nothrow_move_constructible<json_value>::value&&
22386  std::is_nothrow_move_assignable<json_value>::value
22387  )
22388  {
22389  std::swap(m_type, other.m_type);
22390  std::swap(m_value, other.m_value);
22391  assert_invariant();
22392  }
22393 
22412  friend void swap(reference left, reference right) noexcept (
22413  std::is_nothrow_move_constructible<value_t>::value&&
22414  std::is_nothrow_move_assignable<value_t>::value&&
22415  std::is_nothrow_move_constructible<json_value>::value&&
22416  std::is_nothrow_move_assignable<json_value>::value
22417  )
22418  {
22419  left.swap(right);
22420  }
22421 
22442  void swap(array_t& other)
22443  {
22444  // swap only works for arrays
22445  if (JSON_HEDLEY_LIKELY(is_array()))
22446  {
22447  std::swap(*(m_value.array), other);
22448  }
22449  else
22450  {
22451  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22452  }
22453  }
22454 
22475  void swap(object_t& other)
22476  {
22477  // swap only works for objects
22478  if (JSON_HEDLEY_LIKELY(is_object()))
22479  {
22480  std::swap(*(m_value.object), other);
22481  }
22482  else
22483  {
22484  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22485  }
22486  }
22487 
22508  void swap(string_t& other)
22509  {
22510  // swap only works for strings
22511  if (JSON_HEDLEY_LIKELY(is_string()))
22512  {
22513  std::swap(*(m_value.string), other);
22514  }
22515  else
22516  {
22517  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22518  }
22519  }
22520 
22541  void swap(binary_t& other)
22542  {
22543  // swap only works for strings
22544  if (JSON_HEDLEY_LIKELY(is_binary()))
22545  {
22546  std::swap(*(m_value.binary), other);
22547  }
22548  else
22549  {
22550  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22551  }
22552  }
22553 
22555  void swap(typename binary_t::container_type& other)
22556  {
22557  // swap only works for strings
22558  if (JSON_HEDLEY_LIKELY(is_binary()))
22559  {
22560  std::swap(*(m_value.binary), other);
22561  }
22562  else
22563  {
22564  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22565  }
22566  }
22567 
22569 
22570  public:
22572  // lexicographical comparison operators //
22574 
22577 
22633  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22634  {
22635  const auto lhs_type = lhs.type();
22636  const auto rhs_type = rhs.type();
22637 
22638  if (lhs_type == rhs_type)
22639  {
22640  switch (lhs_type)
22641  {
22642  case value_t::array:
22643  return *lhs.m_value.array == *rhs.m_value.array;
22644 
22645  case value_t::object:
22646  return *lhs.m_value.object == *rhs.m_value.object;
22647 
22648  case value_t::null:
22649  return true;
22650 
22651  case value_t::string:
22652  return *lhs.m_value.string == *rhs.m_value.string;
22653 
22654  case value_t::boolean:
22655  return lhs.m_value.boolean == rhs.m_value.boolean;
22656 
22657  case value_t::number_integer:
22658  return lhs.m_value.number_integer == rhs.m_value.number_integer;
22659 
22660  case value_t::number_unsigned:
22661  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22662 
22663  case value_t::number_float:
22664  return lhs.m_value.number_float == rhs.m_value.number_float;
22665 
22666  case value_t::binary:
22667  return *lhs.m_value.binary == *rhs.m_value.binary;
22668 
22669  default:
22670  return false;
22671  }
22672  }
22673  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22674  {
22675  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22676  }
22677  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22678  {
22679  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22680  }
22681  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22682  {
22683  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22684  }
22685  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22686  {
22687  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22688  }
22689  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22690  {
22691  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22692  }
22693  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22694  {
22695  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22696  }
22697 
22698  return false;
22699  }
22700 
22705  template<typename ScalarType, typename std::enable_if<
22706  std::is_scalar<ScalarType>::value, int>::type = 0>
22707  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22708  {
22709  return lhs == basic_json(rhs);
22710  }
22711 
22716  template<typename ScalarType, typename std::enable_if<
22717  std::is_scalar<ScalarType>::value, int>::type = 0>
22718  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22719  {
22720  return basic_json(lhs) == rhs;
22721  }
22722 
22741  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22742  {
22743  return !(lhs == rhs);
22744  }
22745 
22750  template<typename ScalarType, typename std::enable_if<
22751  std::is_scalar<ScalarType>::value, int>::type = 0>
22752  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22753  {
22754  return lhs != basic_json(rhs);
22755  }
22756 
22761  template<typename ScalarType, typename std::enable_if<
22762  std::is_scalar<ScalarType>::value, int>::type = 0>
22763  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22764  {
22765  return basic_json(lhs) != rhs;
22766  }
22767 
22794  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22795  {
22796  const auto lhs_type = lhs.type();
22797  const auto rhs_type = rhs.type();
22798 
22799  if (lhs_type == rhs_type)
22800  {
22801  switch (lhs_type)
22802  {
22803  case value_t::array:
22804  // note parentheses are necessary, see
22805  // https://github.com/nlohmann/json/issues/1530
22806  return (*lhs.m_value.array) < (*rhs.m_value.array);
22807 
22808  case value_t::object:
22809  return (*lhs.m_value.object) < (*rhs.m_value.object);
22810 
22811  case value_t::null:
22812  return false;
22813 
22814  case value_t::string:
22815  return (*lhs.m_value.string) < (*rhs.m_value.string);
22816 
22817  case value_t::boolean:
22818  return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22819 
22820  case value_t::number_integer:
22821  return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22822 
22823  case value_t::number_unsigned:
22824  return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22825 
22826  case value_t::number_float:
22827  return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22828 
22829  case value_t::binary:
22830  return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22831 
22832  default:
22833  return false;
22834  }
22835  }
22836  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22837  {
22838  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22839  }
22840  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22841  {
22842  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22843  }
22844  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22845  {
22846  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22847  }
22848  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22849  {
22850  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22851  }
22852  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22853  {
22854  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22855  }
22856  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22857  {
22858  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22859  }
22860 
22861  // We only reach this line if we cannot compare values. In that case,
22862  // we compare types. Note we have to call the operator explicitly,
22863  // because MSVC has problems otherwise.
22864  return operator<(lhs_type, rhs_type);
22865  }
22866 
22871  template<typename ScalarType, typename std::enable_if<
22872  std::is_scalar<ScalarType>::value, int>::type = 0>
22873  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22874  {
22875  return lhs < basic_json(rhs);
22876  }
22877 
22882  template<typename ScalarType, typename std::enable_if<
22883  std::is_scalar<ScalarType>::value, int>::type = 0>
22884  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22885  {
22886  return basic_json(lhs) < rhs;
22887  }
22888 
22908  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22909  {
22910  return !(rhs < lhs);
22911  }
22912 
22917  template<typename ScalarType, typename std::enable_if<
22918  std::is_scalar<ScalarType>::value, int>::type = 0>
22919  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22920  {
22921  return lhs <= basic_json(rhs);
22922  }
22923 
22928  template<typename ScalarType, typename std::enable_if<
22929  std::is_scalar<ScalarType>::value, int>::type = 0>
22930  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22931  {
22932  return basic_json(lhs) <= rhs;
22933  }
22934 
22954  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22955  {
22956  return !(lhs <= rhs);
22957  }
22958 
22963  template<typename ScalarType, typename std::enable_if<
22964  std::is_scalar<ScalarType>::value, int>::type = 0>
22965  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22966  {
22967  return lhs > basic_json(rhs);
22968  }
22969 
22974  template<typename ScalarType, typename std::enable_if<
22975  std::is_scalar<ScalarType>::value, int>::type = 0>
22976  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22977  {
22978  return basic_json(lhs) > rhs;
22979  }
22980 
23000  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23001  {
23002  return !(lhs < rhs);
23003  }
23004 
23009  template<typename ScalarType, typename std::enable_if<
23010  std::is_scalar<ScalarType>::value, int>::type = 0>
23011  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
23012  {
23013  return lhs >= basic_json(rhs);
23014  }
23015 
23020  template<typename ScalarType, typename std::enable_if<
23021  std::is_scalar<ScalarType>::value, int>::type = 0>
23022  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23023  {
23024  return basic_json(lhs) >= rhs;
23025  }
23026 
23028 
23030  // serialization //
23035 
23067  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23068  {
23069  // read width member and use it as indentation parameter if nonzero
23070  const bool pretty_print = o.width() > 0;
23071  const auto indentation = pretty_print ? o.width() : 0;
23072 
23073  // reset width to 0 for subsequent calls to this stream
23074  o.width(0);
23075 
23076  // do the actual serialization
23077  serializer s(detail::output_adapter<char>(o), o.fill());
23078  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23079  return o;
23080  }
23081 
23090  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
23091  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23092  {
23093  return o << j;
23094  }
23095 
23097 
23098 
23100  // deserialization //
23102 
23105 
23157  template<typename InputType>
23158 
23159  static basic_json parse(InputType&& i,
23160  const parser_callback_t cb = nullptr,
23161  const bool allow_exceptions = true,
23162  const bool ignore_comments = false)
23163  {
23164  basic_json result;
23165  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23166  return result;
23167  }
23168 
23195  template<typename IteratorType>
23196 
23197  static basic_json parse(IteratorType first,
23198  IteratorType last,
23199  const parser_callback_t cb = nullptr,
23200  const bool allow_exceptions = true,
23201  const bool ignore_comments = false)
23202  {
23203  basic_json result;
23204  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23205  return result;
23206  }
23208 
23209  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
23210  static basic_json parse(detail::span_input_adapter&& i,
23211  const parser_callback_t cb = nullptr,
23212  const bool allow_exceptions = true,
23213  const bool ignore_comments = false)
23214  {
23215  basic_json result;
23216  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23217  return result;
23218  }
23219 
23250  template<typename InputType>
23251  static bool accept(InputType&& i,
23252  const bool ignore_comments = false)
23253  {
23254  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23255  }
23256 
23257  template<typename IteratorType>
23258  static bool accept(IteratorType first, IteratorType last,
23259  const bool ignore_comments = false)
23260  {
23261  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23262  }
23263 
23264 
23265  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
23266  static bool accept(detail::span_input_adapter&& i,
23267  const bool ignore_comments = false)
23268  {
23269  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23270  }
23271 
23312  template <typename InputType, typename SAX>
23313  JSON_HEDLEY_NON_NULL(2)
23314  static bool sax_parse(InputType&& i, SAX* sax,
23316  const bool strict = true,
23317  const bool ignore_comments = false)
23318  {
23319  auto ia = detail::input_adapter(std::forward<InputType>(i));
23320  return format == input_format_t::json
23321  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23322  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23323  }
23325  template<class IteratorType, class SAX>
23326  JSON_HEDLEY_NON_NULL(3)
23327  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23328  input_format_t format = input_format_t::json,
23329  const bool strict = true,
23330  const bool ignore_comments = false)
23331  {
23332  auto ia = detail::input_adapter(std::move(first), std::move(last));
23333  return format == input_format_t::json
23334  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23335  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23336  }
23338  template <typename SAX>
23339  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23340  JSON_HEDLEY_NON_NULL(2)
23341  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23342  input_format_t format = input_format_t::json,
23343  const bool strict = true,
23344  const bool ignore_comments = false)
23345  {
23346  auto ia = i.get();
23347  return format == input_format_t::json
23348  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23349  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23350  }
23360  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
23361  friend std::istream& operator<<(basic_json& j, std::istream& i)
23362  {
23363  return operator>>(i, j);
23364  }
23365 
23391  friend std::istream& operator>>(std::istream& i, basic_json& j)
23392  {
23393  parser(detail::input_adapter(i)).parse(false, j);
23394  return i;
23395  }
23396 
23398 
23400  // convenience functions //
23402 
23434 
23435  const char* type_name() const noexcept
23436  {
23437  {
23438  switch (m_type)
23439  {
23440  case value_t::null:
23441  return "null";
23442  case value_t::object:
23443  return "object";
23444  case value_t::array:
23445  return "array";
23446  case value_t::string:
23447  return "string";
23448  case value_t::boolean:
23449  return "boolean";
23450  case value_t::binary:
23451  return "binary";
23452  case value_t::discarded:
23453  return "discarded";
23454  default:
23455  return "number";
23456  }
23457  }
23458  }
23459 
23460 
23461  JSON_PRIVATE_UNLESS_TESTED:
23463  // member variables //
23465 
23467  value_t m_type = value_t::null;
23468 
23470  json_value m_value = {};
23473  // binary serialization/deserialization //
23475 
23478 
23479  public:
23574  static std::vector<uint8_t> to_cbor(const basic_json& j)
23575  {
23576  std::vector<uint8_t> result;
23577  to_cbor(j, result);
23578  return result;
23579  }
23580 
23581  static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23582  {
23583  binary_writer<uint8_t>(o).write_cbor(j);
23584  }
23585 
23586  static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23587  {
23588  binary_writer<char>(o).write_cbor(j);
23589  }
23590 
23669  static std::vector<uint8_t> to_msgpack(const basic_json& j)
23670  {
23671  std::vector<uint8_t> result;
23672  to_msgpack(j, result);
23673  return result;
23674  }
23675 
23676  static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23677  {
23678  binary_writer<uint8_t>(o).write_msgpack(j);
23679  }
23680 
23681  static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23682  {
23683  binary_writer<char>(o).write_msgpack(j);
23684  }
23685 
23772  static std::vector<uint8_t> to_ubjson(const basic_json& j,
23773  const bool use_size = false,
23774  const bool use_type = false)
23775  {
23776  std::vector<uint8_t> result;
23777  to_ubjson(j, result, use_size, use_type);
23778  return result;
23779  }
23780 
23781  static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23782  const bool use_size = false, const bool use_type = false)
23783  {
23784  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23785  }
23786 
23787  static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23788  const bool use_size = false, const bool use_type = false)
23789  {
23790  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23791  }
23792 
23793 
23850  static std::vector<uint8_t> to_bson(const basic_json& j)
23851  {
23852  std::vector<uint8_t> result;
23853  to_bson(j, result);
23854  return result;
23855  }
23856 
23865  static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23866  {
23867  binary_writer<uint8_t>(o).write_bson(j);
23868  }
23869 
23873  static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23874  {
23875  binary_writer<char>(o).write_bson(j);
23876  }
23877 
23878 
23981  template<typename InputType>
23982 
23983  static basic_json from_cbor(InputType&& i,
23984  const bool strict = true,
23985  const bool allow_exceptions = true,
23986  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23987  {
23988  basic_json result;
23989  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23990  auto ia = detail::input_adapter(std::forward<InputType>(i));
23991  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23992  return res ? result : basic_json(value_t::discarded);
23993  }
23994 
23998  template<typename IteratorType>
23999 
24000  static basic_json from_cbor(IteratorType first, IteratorType last,
24001  const bool strict = true,
24002  const bool allow_exceptions = true,
24003  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24004  {
24005  basic_json result;
24006  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24007  auto ia = detail::input_adapter(std::move(first), std::move(last));
24008  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24009  return res ? result : basic_json(value_t::discarded);
24010  }
24011 
24012  template<typename T>
24013 
24014  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24015  static basic_json from_cbor(const T* ptr, std::size_t len,
24016  const bool strict = true,
24017  const bool allow_exceptions = true,
24018  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24019  {
24020  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24021  }
24022 
24023 
24024 
24025  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
24026  static basic_json from_cbor(detail::span_input_adapter&& i,
24027  const bool strict = true,
24028  const bool allow_exceptions = true,
24029  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24030  {
24031  basic_json result;
24032  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24033  auto ia = i.get();
24034  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24035  return res ? result : basic_json(value_t::discarded);
24036  }
24037 
24124  template<typename InputType>
24125 
24126  static basic_json from_msgpack(InputType&& i,
24127  const bool strict = true,
24128  const bool allow_exceptions = true)
24129  {
24130  basic_json result;
24131  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24132  auto ia = detail::input_adapter(std::forward<InputType>(i));
24133  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24134  return res ? result : basic_json(value_t::discarded);
24135  }
24140  template<typename IteratorType>
24141 
24142  static basic_json from_msgpack(IteratorType first, IteratorType last,
24143  const bool strict = true,
24144  const bool allow_exceptions = true)
24145  {
24146  basic_json result;
24147  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24148  auto ia = detail::input_adapter(std::move(first), std::move(last));
24149  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24150  return res ? result : basic_json(value_t::discarded);
24151  }
24153 
24154  template<typename T>
24155 
24156  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24157  static basic_json from_msgpack(const T* ptr, std::size_t len,
24158  const bool strict = true,
24159  const bool allow_exceptions = true)
24160  {
24161  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24162  }
24163 
24164 
24165  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
24166  static basic_json from_msgpack(detail::span_input_adapter&& i,
24167  const bool strict = true,
24168  const bool allow_exceptions = true)
24169  {
24170  basic_json result;
24171  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24172  auto ia = i.get();
24173  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24174  return res ? result : basic_json(value_t::discarded);
24175  }
24177 
24240  template<typename InputType>
24241 
24242  static basic_json from_ubjson(InputType&& i,
24243  const bool strict = true,
24244  const bool allow_exceptions = true)
24245  {
24246  basic_json result;
24247  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24248  auto ia = detail::input_adapter(std::forward<InputType>(i));
24249  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24250  return res ? result : basic_json(value_t::discarded);
24251  }
24256  template<typename IteratorType>
24257 
24258  static basic_json from_ubjson(IteratorType first, IteratorType last,
24259  const bool strict = true,
24260  const bool allow_exceptions = true)
24261  {
24262  basic_json result;
24263  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24264  auto ia = detail::input_adapter(std::move(first), std::move(last));
24265  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24266  return res ? result : basic_json(value_t::discarded);
24267  }
24269  template<typename T>
24270 
24271  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24272  static basic_json from_ubjson(const T* ptr, std::size_t len,
24273  const bool strict = true,
24274  const bool allow_exceptions = true)
24275  {
24276  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24277  }
24278 
24279 
24280  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
24281  static basic_json from_ubjson(detail::span_input_adapter&& i,
24282  const bool strict = true,
24283  const bool allow_exceptions = true)
24284  {
24285  basic_json result;
24286  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24287  auto ia = i.get();
24288  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24289  return res ? result : basic_json(value_t::discarded);
24290  }
24292 
24353  template<typename InputType>
24354 
24355  static basic_json from_bson(InputType&& i,
24356  const bool strict = true,
24357  const bool allow_exceptions = true)
24358  {
24359  basic_json result;
24360  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24361  auto ia = detail::input_adapter(std::forward<InputType>(i));
24362  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24363  return res ? result : basic_json(value_t::discarded);
24364  }
24369  template<typename IteratorType>
24370 
24371  static basic_json from_bson(IteratorType first, IteratorType last,
24372  const bool strict = true,
24373  const bool allow_exceptions = true)
24374  {
24375  basic_json result;
24376  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24377  auto ia = detail::input_adapter(std::move(first), std::move(last));
24378  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24379  return res ? result : basic_json(value_t::discarded);
24380  }
24382  template<typename T>
24383 
24384  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24385  static basic_json from_bson(const T* ptr, std::size_t len,
24386  const bool strict = true,
24387  const bool allow_exceptions = true)
24388  {
24389  return from_bson(ptr, ptr + len, strict, allow_exceptions);
24390  }
24391 
24392 
24393  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
24394  static basic_json from_bson(detail::span_input_adapter&& i,
24395  const bool strict = true,
24396  const bool allow_exceptions = true)
24397  {
24398  basic_json result;
24399  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24400  auto ia = i.get();
24401  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24402  return res ? result : basic_json(value_t::discarded);
24403  }
24405 
24407  // JSON Pointer support //
24409 
24412 
24446  reference operator[](const json_pointer& ptr)
24447  {
24448  return ptr.get_unchecked(this);
24449  }
24450 
24474  const_reference operator[](const json_pointer& ptr) const
24475  {
24476  return ptr.get_unchecked(this);
24477  }
24478 
24517  reference at(const json_pointer& ptr)
24518  {
24519  return ptr.get_checked(this);
24520  }
24521 
24560  const_reference at(const json_pointer& ptr) const
24561  {
24562  return ptr.get_checked(this);
24563  }
24564 
24587  basic_json flatten() const
24588  {
24589  basic_json result(value_t::object);
24590  json_pointer::flatten("", *this, result);
24591  return result;
24592  }
24593 
24624  basic_json unflatten() const
24625  {
24626  return json_pointer::unflatten(*this);
24627  }
24628 
24630 
24632  // JSON Patch functions //
24637 
24685  basic_json patch(const basic_json& json_patch) const
24686  {
24687  // make a working copy to apply the patch to
24688  basic_json result = *this;
24689 
24690  // the valid JSON Patch operations
24691  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24692 
24693  const auto get_op = [](const std::string & op)
24694  {
24695  if (op == "add")
24696  {
24697  return patch_operations::add;
24698  }
24699  if (op == "remove")
24700  {
24701  return patch_operations::remove;
24702  }
24703  if (op == "replace")
24704  {
24705  return patch_operations::replace;
24706  }
24707  if (op == "move")
24708  {
24709  return patch_operations::move;
24710  }
24711  if (op == "copy")
24712  {
24713  return patch_operations::copy;
24714  }
24715  if (op == "test")
24716  {
24717  return patch_operations::test;
24718  }
24719 
24720  return patch_operations::invalid;
24721  };
24722 
24723  // wrapper for "add" operation; add value at ptr
24724  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24725  {
24726  // adding to the root of the target document means replacing it
24727  if (ptr.empty())
24728  {
24729  result = val;
24730  return;
24731  }
24732 
24733  // make sure the top element of the pointer exists
24734  json_pointer top_pointer = ptr.top();
24735  if (top_pointer != ptr)
24736  {
24737  result.at(top_pointer);
24738  }
24739 
24740  // get reference to parent of JSON pointer ptr
24741  const auto last_path = ptr.back();
24742  ptr.pop_back();
24743  basic_json& parent = result[ptr];
24744 
24745  switch (parent.m_type)
24746  {
24747  case value_t::null:
24748  case value_t::object:
24749  {
24750  // use operator[] to add value
24751  parent[last_path] = val;
24752  break;
24753  }
24754 
24755  case value_t::array:
24756  {
24757  if (last_path == "-")
24758  {
24759  // special case: append to back
24760  parent.push_back(val);
24761  }
24762  else
24763  {
24764  const auto idx = json_pointer::array_index(last_path);
24765  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24766  {
24767  // avoid undefined behavior
24768  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24769  }
24770 
24771  // default case: insert add offset
24772  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24773  }
24774  break;
24775  }
24776 
24777  // if there exists a parent it cannot be primitive
24778  default: // LCOV_EXCL_LINE
24779  JSON_ASSERT(false); // LCOV_EXCL_LINE
24780  }
24781  };
24782 
24783  // wrapper for "remove" operation; remove value at ptr
24784  const auto operation_remove = [&result](json_pointer & ptr)
24785  {
24786  // get reference to parent of JSON pointer ptr
24787  const auto last_path = ptr.back();
24788  ptr.pop_back();
24789  basic_json& parent = result.at(ptr);
24790 
24791  // remove child
24792  if (parent.is_object())
24793  {
24794  // perform range check
24795  auto it = parent.find(last_path);
24796  if (JSON_HEDLEY_LIKELY(it != parent.end()))
24797  {
24798  parent.erase(it);
24799  }
24800  else
24801  {
24802  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24803  }
24804  }
24805  else if (parent.is_array())
24806  {
24807  // note erase performs range check
24808  parent.erase(json_pointer::array_index(last_path));
24809  }
24810  };
24811 
24812  // type check: top level value must be an array
24813  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24814  {
24815  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24816  }
24817 
24818  // iterate and apply the operations
24819  for (const auto& val : json_patch)
24820  {
24821  // wrapper to get a value for an operation
24822  const auto get_value = [&val](const std::string & op,
24823  const std::string & member,
24824  bool string_type) -> basic_json &
24825  {
24826  // find value
24827  auto it = val.m_value.object->find(member);
24828 
24829  // context-sensitive error message
24830  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24831 
24832  // check if desired value is present
24833  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24834  {
24835  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24836  }
24837 
24838  // check if result is of type string
24839  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24840  {
24841  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24842  }
24843 
24844  // no error: return value
24845  return it->second;
24846  };
24847 
24848  // type check: every element of the array must be an object
24849  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24850  {
24851  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24852  }
24853 
24854  // collect mandatory members
24855  const auto op = get_value("op", "op", true).template get<std::string>();
24856  const auto path = get_value(op, "path", true).template get<std::string>();
24857  json_pointer ptr(path);
24858 
24859  switch (get_op(op))
24860  {
24861  case patch_operations::add:
24862  {
24863  operation_add(ptr, get_value("add", "value", false));
24864  break;
24865  }
24866 
24867  case patch_operations::remove:
24868  {
24869  operation_remove(ptr);
24870  break;
24871  }
24872 
24873  case patch_operations::replace:
24874  {
24875  // the "path" location must exist - use at()
24876  result.at(ptr) = get_value("replace", "value", false);
24877  break;
24878  }
24879 
24880  case patch_operations::move:
24881  {
24882  const auto from_path = get_value("move", "from", true).template get<std::string>();
24883  json_pointer from_ptr(from_path);
24884 
24885  // the "from" location must exist - use at()
24886  basic_json v = result.at(from_ptr);
24887 
24888  // The move operation is functionally identical to a
24889  // "remove" operation on the "from" location, followed
24890  // immediately by an "add" operation at the target
24891  // location with the value that was just removed.
24892  operation_remove(from_ptr);
24893  operation_add(ptr, v);
24894  break;
24895  }
24896 
24897  case patch_operations::copy:
24898  {
24899  const auto from_path = get_value("copy", "from", true).template get<std::string>();
24900  const json_pointer from_ptr(from_path);
24901 
24902  // the "from" location must exist - use at()
24903  basic_json v = result.at(from_ptr);
24904 
24905  // The copy is functionally identical to an "add"
24906  // operation at the target location using the value
24907  // specified in the "from" member.
24908  operation_add(ptr, v);
24909  break;
24910  }
24911 
24912  case patch_operations::test:
24913  {
24914  bool success = false;
24915  JSON_TRY
24916  {
24917  // check if "value" matches the one at "path"
24918  // the "path" location must exist - use at()
24919  success = (result.at(ptr) == get_value("test", "value", false));
24920  }
24921  JSON_INTERNAL_CATCH (out_of_range&)
24922  {
24923  // ignore out of range errors: success remains false
24924  }
24925 
24926  // throw an exception if test fails
24927  if (JSON_HEDLEY_UNLIKELY(!success))
24928  {
24929  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24930  }
24931 
24932  break;
24933  }
24934 
24935  default:
24936  {
24937  // op must be "add", "remove", "replace", "move", "copy", or
24938  // "test"
24939  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24940  }
24941  }
24942  }
24943 
24944  return result;
24945  }
24946 
24980 
24981  static basic_json diff(const basic_json& source, const basic_json& target,
24982  const std::string& path = "")
24983  {
24984  // the patch
24985  basic_json result(value_t::array);
24986 
24987  // if the values are the same, return empty patch
24988  if (source == target)
24989  {
24990  return result;
24991  }
24992 
24993  if (source.type() != target.type())
24994  {
24995  // different types: replace value
24996  result.push_back(
24997  {
24998  {"op", "replace"}, {"path", path}, {"value", target}
24999  });
25000  return result;
25001  }
25002 
25003  switch (source.type())
25004  {
25005  case value_t::array:
25006  {
25007  // first pass: traverse common elements
25008  std::size_t i = 0;
25009  while (i < source.size() && i < target.size())
25010  {
25011  // recursive call to compare array values at index i
25012  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25013  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25014  ++i;
25015  }
25016 
25017  // i now reached the end of at least one array
25018  // in a second pass, traverse the remaining elements
25019 
25020  // remove my remaining elements
25021  const auto end_index = static_cast<difference_type>(result.size());
25022  while (i < source.size())
25023  {
25024  // add operations in reverse order to avoid invalid
25025  // indices
25026  result.insert(result.begin() + end_index, object(
25027  {
25028  {"op", "remove"},
25029  {"path", path + "/" + std::to_string(i)}
25030  }));
25031  ++i;
25032  }
25033 
25034  // add other remaining elements
25035  while (i < target.size())
25036  {
25037  result.push_back(
25038  {
25039  {"op", "add"},
25040  {"path", path + "/-"},
25041  {"value", target[i]}
25042  });
25043  ++i;
25044  }
25045 
25046  break;
25047  }
25048 
25049  case value_t::object:
25050  {
25051  // first pass: traverse this object's elements
25052  for (auto it = source.cbegin(); it != source.cend(); ++it)
25053  {
25054  // escape the key name to be used in a JSON patch
25055  const auto key = json_pointer::escape(it.key());
25056 
25057  if (target.find(it.key()) != target.end())
25058  {
25059  // recursive call to compare object values at key it
25060  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25061  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25062  }
25063  else
25064  {
25065  // found a key that is not in o -> remove it
25066  result.push_back(object(
25067  {
25068  {"op", "remove"}, {"path", path + "/" + key}
25069  }));
25070  }
25071  }
25072 
25073  // second pass: traverse other object's elements
25074  for (auto it = target.cbegin(); it != target.cend(); ++it)
25075  {
25076  if (source.find(it.key()) == source.end())
25077  {
25078  // found a key that is not in this -> add it
25079  const auto key = json_pointer::escape(it.key());
25080  result.push_back(
25081  {
25082  {"op", "add"}, {"path", path + "/" + key},
25083  {"value", it.value()}
25084  });
25085  }
25086  }
25087 
25088  break;
25089  }
25090 
25091  default:
25092  {
25093  // both primitive type: replace value
25094  result.push_back(
25095  {
25096  {"op", "replace"}, {"path", path}, {"value", target}
25097  });
25098  break;
25099  }
25100  }
25101 
25102  return result;
25103  }
25104 
25106 
25108  // JSON Merge Patch functions //
25110 
25113 
25156  void merge_patch(const basic_json& apply_patch)
25157  {
25158  if (apply_patch.is_object())
25159  {
25160  if (!is_object())
25161  {
25162  *this = object();
25163  }
25164  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25165  {
25166  if (it.value().is_null())
25167  {
25168  erase(it.key());
25169  }
25170  else
25171  {
25172  operator[](it.key()).merge_patch(it.value());
25173  }
25174  }
25175  }
25176  else
25177  {
25178  *this = apply_patch;
25179  }
25180  }
25181 
25183 };
25184 
25194 NLOHMANN_BASIC_JSON_TPL_DECLARATION
25195 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25196 {
25197  return j.dump();
25198 }
25199 } // namespace nlohmann
25200 
25202 // nonmember support //
25204 
25205 // specialization of std::swap, and std::hash
25206 namespace std
25207 {
25208 
25210 template<>
25211 struct hash<nlohmann::json>
25212 {
25218  std::size_t operator()(const nlohmann::json& j) const
25219  {
25220  return nlohmann::detail::hash(j);
25221  }
25222 };
25223 
25227 template<>
25228 struct less<::nlohmann::detail::value_t>
25229 {
25234  bool operator()(nlohmann::detail::value_t lhs,
25235  nlohmann::detail::value_t rhs) const noexcept
25236  {
25237  return nlohmann::detail::operator<(lhs, rhs);
25238  }
25239 };
25240 
25241 // C++20 prohibit function specialization in the std namespace.
25242 #ifndef JSON_HAS_CPP_20
25243 
25249 template<>
25250 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25251  is_nothrow_move_constructible<nlohmann::json>::value&&
25252  is_nothrow_move_assignable<nlohmann::json>::value
25253  )
25254 {
25255  j1.swap(j2);
25256 }
25257 
25258 #endif
25259 
25260 } // namespace std
25261 
25275 JSON_HEDLEY_NON_NULL(1)
25276 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25277 {
25278  return nlohmann::json::parse(s, s + n);
25279 }
25280 
25294 JSON_HEDLEY_NON_NULL(1)
25295 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25296 {
25297  return nlohmann::json::json_pointer(std::string(s, n));
25298 }
25299 
25300 // #include <nlohmann/detail/macro_unscope.hpp>
25301 
25302 
25303 // restore GCC/clang diagnostic settings
25304 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25305  #pragma GCC diagnostic pop
25306 #endif
25307 #if defined(__clang__)
25308  #pragma GCC diagnostic pop
25309 #endif
25310 
25311 // clean up
25312 #undef JSON_ASSERT
25313 #undef JSON_INTERNAL_CATCH
25314 #undef JSON_CATCH
25315 #undef JSON_THROW
25316 #undef JSON_TRY
25317 #undef JSON_PRIVATE_UNLESS_TESTED
25318 #undef JSON_HAS_CPP_14
25319 #undef JSON_HAS_CPP_17
25320 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25321 #undef NLOHMANN_BASIC_JSON_TPL
25322 #undef JSON_EXPLICIT
25323 
25324 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25325 #undef JSON_HEDLEY_ALWAYS_INLINE
25326 #undef JSON_HEDLEY_ARM_VERSION
25327 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25328 #undef JSON_HEDLEY_ARRAY_PARAM
25329 #undef JSON_HEDLEY_ASSUME
25330 #undef JSON_HEDLEY_BEGIN_C_DECLS
25331 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25332 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25333 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25334 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25335 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25336 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25337 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25338 #undef JSON_HEDLEY_COMPCERT_VERSION
25339 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25340 #undef JSON_HEDLEY_CONCAT
25341 #undef JSON_HEDLEY_CONCAT3
25342 #undef JSON_HEDLEY_CONCAT3_EX
25343 #undef JSON_HEDLEY_CONCAT_EX
25344 #undef JSON_HEDLEY_CONST
25345 #undef JSON_HEDLEY_CONSTEXPR
25346 #undef JSON_HEDLEY_CONST_CAST
25347 #undef JSON_HEDLEY_CPP_CAST
25348 #undef JSON_HEDLEY_CRAY_VERSION
25349 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25350 #undef JSON_HEDLEY_C_DECL
25351 #undef JSON_HEDLEY_DEPRECATED
25352 #undef JSON_HEDLEY_DEPRECATED_FOR
25353 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25354 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25355 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25356 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25357 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25358 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25359 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25360 #undef JSON_HEDLEY_DMC_VERSION
25361 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25362 #undef JSON_HEDLEY_EMPTY_BASES
25363 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25364 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25365 #undef JSON_HEDLEY_END_C_DECLS
25366 #undef JSON_HEDLEY_FLAGS
25367 #undef JSON_HEDLEY_FLAGS_CAST
25368 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25369 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25370 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25371 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25372 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25373 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25374 #undef JSON_HEDLEY_GCC_HAS_WARNING
25375 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25376 #undef JSON_HEDLEY_GCC_VERSION
25377 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25378 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25379 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25380 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25381 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25382 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25383 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25384 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25385 #undef JSON_HEDLEY_GNUC_VERSION
25386 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25387 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25388 #undef JSON_HEDLEY_HAS_BUILTIN
25389 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25390 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25391 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25392 #undef JSON_HEDLEY_HAS_EXTENSION
25393 #undef JSON_HEDLEY_HAS_FEATURE
25394 #undef JSON_HEDLEY_HAS_WARNING
25395 #undef JSON_HEDLEY_IAR_VERSION
25396 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25397 #undef JSON_HEDLEY_IBM_VERSION
25398 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25399 #undef JSON_HEDLEY_IMPORT
25400 #undef JSON_HEDLEY_INLINE
25401 #undef JSON_HEDLEY_INTEL_VERSION
25402 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25403 #undef JSON_HEDLEY_IS_CONSTANT
25404 #undef JSON_HEDLEY_IS_CONSTEXPR_
25405 #undef JSON_HEDLEY_LIKELY
25406 #undef JSON_HEDLEY_MALLOC
25407 #undef JSON_HEDLEY_MESSAGE
25408 #undef JSON_HEDLEY_MSVC_VERSION
25409 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25410 #undef JSON_HEDLEY_NEVER_INLINE
25411 #undef JSON_HEDLEY_NON_NULL
25412 #undef JSON_HEDLEY_NO_ESCAPE
25413 #undef JSON_HEDLEY_NO_RETURN
25414 #undef JSON_HEDLEY_NO_THROW
25415 #undef JSON_HEDLEY_NULL
25416 #undef JSON_HEDLEY_PELLES_VERSION
25417 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25418 #undef JSON_HEDLEY_PGI_VERSION
25419 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25420 #undef JSON_HEDLEY_PREDICT
25421 #undef JSON_HEDLEY_PRINTF_FORMAT
25422 #undef JSON_HEDLEY_PRIVATE
25423 #undef JSON_HEDLEY_PUBLIC
25424 #undef JSON_HEDLEY_PURE
25425 #undef JSON_HEDLEY_REINTERPRET_CAST
25426 #undef JSON_HEDLEY_REQUIRE
25427 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25428 #undef JSON_HEDLEY_REQUIRE_MSG
25429 #undef JSON_HEDLEY_RESTRICT
25430 #undef
25431 #undef JSON_HEDLEY_SENTINEL
25432 #undef JSON_HEDLEY_STATIC_ASSERT
25433 #undef JSON_HEDLEY_STATIC_CAST
25434 #undef JSON_HEDLEY_STRINGIFY
25435 #undef JSON_HEDLEY_STRINGIFY_EX
25436 #undef JSON_HEDLEY_SUNPRO_VERSION
25437 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25438 #undef JSON_HEDLEY_TINYC_VERSION
25439 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25440 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25441 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25442 #undef JSON_HEDLEY_TI_CL2000_VERSION
25443 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25444 #undef JSON_HEDLEY_TI_CL430_VERSION
25445 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25446 #undef JSON_HEDLEY_TI_CL6X_VERSION
25447 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25448 #undef JSON_HEDLEY_TI_CL7X_VERSION
25449 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25450 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25451 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25452 #undef JSON_HEDLEY_TI_VERSION
25453 #undef JSON_HEDLEY_TI_VERSION_CHECK
25454 #undef JSON_HEDLEY_UNAVAILABLE
25455 #undef JSON_HEDLEY_UNLIKELY
25456 #undef JSON_HEDLEY_UNPREDICTABLE
25457 #undef JSON_HEDLEY_UNREACHABLE
25458 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25459 #undef JSON_HEDLEY_VERSION
25460 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25461 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25462 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25463 #undef JSON_HEDLEY_VERSION_ENCODE
25464 #undef JSON_HEDLEY_WARNING
25465 #undef
25466 #undef _MSG
25467 #undef JSON_HEDLEY_FALL_THROUGH
25468 
25469 
25470 
25471 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const
Definition: json.hpp:19542
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:16560
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:22017
nlohmann::json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
nlohmann::json_sax::number_integer
virtual bool number_integer(number_integer_t val)=0
an integer number was read
nlohmann::byte_container_with_subtype::operator==
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4470
nlohmann::basic_json::initializer_list_t
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:16745
nlohmann::basic_json::get_to
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:19553
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:17877
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:24695
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:17209
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:16735
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:16801
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:18293
nlohmann::basic_json::to_cbor
static std::vector< uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:23584
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21934
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:18648
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:23101
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype) noexcept
sets the binary subtype
Definition: json.hpp:4499
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:18247
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:21669
nlohmann::basic_json::get
BasicJsonType get() const
get special-case overload
Definition: json.hpp:19382
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:17348
nlohmann::basic_json::m_value
json_value m_value
the value of the current element
Definition: json.hpp:23480
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:21177
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:22964
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:24634
nlohmann::ordered_map::at
T & at(const Key &key)
Definition: json.hpp:16465
nlohmann::ordered_map::Container
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:16427
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:19052
nlohmann::basic_json::from_msgpack
static basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:24136
nlohmann::basic_json::cbor_tag_handler_t
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:16743
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:16764
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:19118
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5216
nlohmann::basic_json::get
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:19638
nlohmann::basic_json::accept
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:23261
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:16790
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:11816
nlohmann::json_sax::start_object
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
nlohmann::json_pointer::to_string
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:11610
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:22643
nlohmann::basic_json::dump
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:18782
nlohmann::ordered_map
Definition: json.hpp:16424
nlohmann::basic_json::to_bson
static std::vector< uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:23860
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:20438
nlohmann::basic_json::operator=
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:18685
nlohmann::ordered_map::mapped_type
T mapped_type
Definition: json.hpp:16426
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:18915
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:82
nlohmann::basic_json::get_to
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:19529
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:18866
nlohmann::basic_json::to_ubjson
static std::vector< uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:23782
nlohmann::basic_json::get_ptr
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19590
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:4547
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:18429
nlohmann::json_sax::parse_error
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
nlohmann::basic_json::parse
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:23169
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:11565
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:21746
nlohmann::ordered_map::operator[]
T & operator[](const Key &key)
Definition: json.hpp:16455
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:16793
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:16820
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:20999
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4476
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:22751
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11863
nlohmann::basic_json::value
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:20312
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:21598
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:17987
nlohmann::anonymous_namespace{json.hpp}::from_json
constexpr const auto & from_json
Definition: json.hpp:3808
nlohmann::basic_json::count
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:20896
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21771
nlohmann::ordered_map::operator[]
const T & operator[](const Key &key) const
Definition: json.hpp:16460
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:18937
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:19024
nlohmann::basic_json::const_pointer
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:16803
nlohmann::json_pointer::operator==
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:12499
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:16762
nlohmann::ordered_map::ordered_map
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:16439
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:16678
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:21243
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:18718
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:4464
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:4378
nlohmann::to_string
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25205
nlohmann::adl_serializer::from_json
static auto from_json(BasicJsonType &&j, ValueType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:4389
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:16795
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:18559
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:23010
nlohmann::json_sax::string
virtual bool string(string_t &val)=0
a string was read
nlohmann::json_sax::number_integer_t
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5212
nlohmann::basic_json::from_ubjson
static basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:24252
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:22055
nlohmann::ordered_map::count
size_type count(const Key &key) const
Definition: json.hpp:16524
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:22918
nlohmann::basic_json::exception
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:16760
nlohmann::basic_json::object_t
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.hpp:17012
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:11708
nlohmann::ordered_map::erase
size_type erase(const Key &key)
Definition: json.hpp:16491
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5214
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:21214
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:16739
nlohmann::ordered_map::key_type
Key key_type
Definition: json.hpp:16425
nlohmann::basic_json::from_cbor
static basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:23993
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:24597
nlohmann::basic_json::to_msgpack
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:23679
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:23445
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:17111
nlohmann::basic_json::binary
static basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18190
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:23077
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:5213
nlohmann::json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:21039
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:16747
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:16922
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:20845
nlohmann::json_sax::~json_sax
virtual ~json_sax()=default
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:20482
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:4454
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:16788
nlohmann::ordered_map::find
const_iterator find(const Key &key) const
Definition: json.hpp:16548
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:16852
nlohmann::basic_json::basic_json
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:18364
nlohmann::basic_json::get
constexpr auto get() const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:19650
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:17812
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:16808
nlohmann::json_pointer::push_back
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:11838
nlohmann::ordered_map::erase
iterator erase(iterator pos)
Definition: json.hpp:16510
nlohmann::json_sax::key
virtual bool key(string_t &val)=0
an object key was read
nlohmann::json_sax::number_float
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
nlohmann::json_pointer::operator/=
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:11688
nlohmann::ordered_map::ordered_map
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:16435
nlohmann::basic_json::basic_json
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:18110
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:17137
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:18532
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:17419
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:19167
nlohmann::basic_json::get
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:19432
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:18237
nlohmann::basic_json::basic_json
basic_json(CompatibleType &&val) noexcept(noexcept(JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:17950
nlohmann::json_sax::end_array
virtual bool end_array()=0
the end of an array was read
nlohmann::json_pointer::operator/=
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:11642
nlohmann::json_pointer::push_back
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:11844
nlohmann::ordered_map::insert
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:16565
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:21070
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:20021
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:16768
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:5215
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:16676
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:18996
nlohmann::json_sax::end_object
virtual bool end_object()=0
the end of an object was read
nlohmann::basic_json::binary
static basic_json binary(const typename binary_t::container_type &init, std::uint8_t subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:18227
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:19769
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:19074
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:25166
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:4571
nlohmann::basic_json::iterator_wrapper
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:21307
nlohmann::ordered_map::find
iterator find(const Key &key)
Definition: json.hpp:16536
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:11749
nlohmann::json_pointer::operator!=
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:12516
nlohmann::json_sax::number_unsigned
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
nlohmann::json_sax::binary
virtual bool binary(binary_t &val)=0
a binary string was read
nlohmann::ordered_map::ordered_map
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:16437
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:20549
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:4526
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:21140
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:18337
nlohmann::anonymous_namespace{json.hpp}::to_json
constexpr const auto & to_json
Definition: json.hpp:4368
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4446
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:4450
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:16737
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:17058
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:18835
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11592
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:19684
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:16806
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:17853
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:11792
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:21110
nlohmann::basic_json::get_ptr
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:19603
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:19697
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:17280
nlohmann::basic_json::get
ValueType get() const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:19483
nlohmann::json_pointer::operator/=
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:11666
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:18893
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:11767
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:22290
nlohmann::basic_json::sax_parse
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:23324
nlohmann::json_pointer::operator/
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:11729
nlohmann::basic_json::diff
static basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:24991
nlohmann::basic_json::swap
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:22392
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21886
nlohmann::ordered_map::emplace
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:16442
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:18967
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:2940
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:21389
nlohmann::json_sax
SAX interface.
Definition: json.hpp:5211
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype(const container_type &b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
Definition: json.hpp:4458
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:19758
nlohmann::adl_serializer::to_json
static auto to_json(BasicJsonType &j, ValueType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< ValueType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< ValueType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:4406
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:19816
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4441
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:22804
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:19140
nlohmann::ordered_map::at
const T & at(const Key &key) const
Definition: json.hpp:16478
nlohmann::basic_json::from_cbor
static basic_json from_cbor(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:24025
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:21454
nlohmann::basic_json::reverse_iterator
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:16810
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:19096
nlohmann::basic_json::emplace
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:21987
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:16766
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:21527
nlohmann::basic_json::from_bson
static basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:24365
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20929
nlohmann::basic_json::get
basic_json get() const
get special-case overload
Definition: json.hpp:19359
nlohmann::basic_json::const_reverse_iterator
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:16812
nlohmann::basic_json::other_error
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:16770
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:16798
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4444