JSON for Modern C++  3.7.3
json.hpp
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.7.3
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 7
35 #define NLOHMANN_JSON_VERSION_PATCH 3
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
40 #include <functional> // hash, less
41 #include <initializer_list> // initializer_list
42 #include <iosfwd> // istream, ostream
43 #include <iterator> // random_access_iterator_tag
44 #include <memory> // unique_ptr
45 #include <numeric> // accumulate
46 #include <string> // string, stoi, to_string
47 #include <utility> // declval, forward, move, pair, swap
48 #include <vector> // vector
49 
50 // #include <nlohmann/adl_serializer.hpp>
51 
52 
53 #include <utility>
54 
55 // #include <nlohmann/detail/conversions/from_json.hpp>
56 
57 
58 #include <algorithm> // transform
59 #include <array> // array
60 #include <forward_list> // forward_list
61 #include <iterator> // inserter, front_inserter, end
62 #include <map> // map
63 #include <string> // string
64 #include <tuple> // tuple, make_tuple
65 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
66 #include <unordered_map> // unordered_map
67 #include <utility> // pair, declval
68 #include <valarray> // valarray
69 
70 // #include <nlohmann/detail/boolean_operators.hpp>
71 
72 
73 // Header <ciso646> is removed in C++20.
74 // See <https://github.com/nlohmann/json/issues/2089> for more information.
75 
76 #if __cplusplus <= 201703L
77  #include <ciso646> // and, not, or
78 #endif
79 
80 // #include <nlohmann/detail/exceptions.hpp>
81 
82 
83 #include <exception> // exception
84 #include <stdexcept> // runtime_error
85 #include <string> // to_string
86 
87 // #include <nlohmann/detail/input/position_t.hpp>
88 
89 
90 #include <cstddef> // size_t
91 
92 namespace nlohmann
93 {
94 namespace detail
95 {
97 struct position_t
98 {
100  std::size_t chars_read_total = 0;
102  std::size_t chars_read_current_line = 0;
104  std::size_t lines_read = 0;
105 
107  constexpr operator size_t() const
108  {
109  return chars_read_total;
110  }
111 };
112 
113 } // namespace detail
114 } // namespace nlohmann
115 
116 // #include <nlohmann/detail/macro_scope.hpp>
117 
118 
119 #include <utility> // pair
120 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
121 /* Hedley - https://nemequ.github.io/hedley
122  * Created by Evan Nemerson <evan@nemerson.com>
123  *
124  * To the extent possible under law, the author(s) have dedicated all
125  * copyright and related and neighboring rights to this software to
126  * the public domain worldwide. This software is distributed without
127  * any warranty.
128  *
129  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
130  * SPDX-License-Identifier: CC0-1.0
131  */
132 
133 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
134 #if defined(JSON_HEDLEY_VERSION)
135  #undef JSON_HEDLEY_VERSION
136 #endif
137 #define JSON_HEDLEY_VERSION 13
138 
139 #if defined(JSON_HEDLEY_STRINGIFY_EX)
140  #undef JSON_HEDLEY_STRINGIFY_EX
141 #endif
142 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
143 
144 #if defined(JSON_HEDLEY_STRINGIFY)
145  #undef JSON_HEDLEY_STRINGIFY
146 #endif
147 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
148 
149 #if defined(JSON_HEDLEY_CONCAT_EX)
150  #undef JSON_HEDLEY_CONCAT_EX
151 #endif
152 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
153 
154 #if defined(JSON_HEDLEY_CONCAT)
155  #undef JSON_HEDLEY_CONCAT
156 #endif
157 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
158 
159 #if defined(JSON_HEDLEY_CONCAT3_EX)
160  #undef JSON_HEDLEY_CONCAT3_EX
161 #endif
162 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
163 
164 #if defined(JSON_HEDLEY_CONCAT3)
165  #undef JSON_HEDLEY_CONCAT3
166 #endif
167 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
168 
169 #if defined(JSON_HEDLEY_VERSION_ENCODE)
170  #undef JSON_HEDLEY_VERSION_ENCODE
171 #endif
172 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
173 
174 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
175  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
176 #endif
177 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
178 
179 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
180  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
181 #endif
182 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
183 
184 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
185  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
186 #endif
187 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
188 
189 #if defined(JSON_HEDLEY_GNUC_VERSION)
190  #undef JSON_HEDLEY_GNUC_VERSION
191 #endif
192 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
193  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
194 #elif defined(__GNUC__)
195  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
196 #endif
197 
198 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
199  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
200 #endif
201 #if defined(JSON_HEDLEY_GNUC_VERSION)
202  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
203 #else
204  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
205 #endif
206 
207 #if defined(JSON_HEDLEY_MSVC_VERSION)
208  #undef JSON_HEDLEY_MSVC_VERSION
209 #endif
210 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
211  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
212 #elif defined(_MSC_FULL_VER)
213  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
214 #elif defined(_MSC_VER)
215  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
216 #endif
217 
218 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
219  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
220 #endif
221 #if !defined(_MSC_VER)
222  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
223 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
224  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
225 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
226  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
227 #else
228  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
229 #endif
230 
231 #if defined(JSON_HEDLEY_INTEL_VERSION)
232  #undef JSON_HEDLEY_INTEL_VERSION
233 #endif
234 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
235  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
236 #elif defined(__INTEL_COMPILER)
237  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
238 #endif
239 
240 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
241  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
242 #endif
243 #if defined(JSON_HEDLEY_INTEL_VERSION)
244  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
245 #else
246  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
247 #endif
248 
249 #if defined(JSON_HEDLEY_PGI_VERSION)
250  #undef JSON_HEDLEY_PGI_VERSION
251 #endif
252 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
253  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
254 #endif
255 
256 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
257  #undef JSON_HEDLEY_PGI_VERSION_CHECK
258 #endif
259 #if defined(JSON_HEDLEY_PGI_VERSION)
260  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
261 #else
262  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
263 #endif
264 
265 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
266  #undef JSON_HEDLEY_SUNPRO_VERSION
267 #endif
268 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
269  #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)
270 #elif defined(__SUNPRO_C)
271  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
272 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
273  #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)
274 #elif defined(__SUNPRO_CC)
275  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
276 #endif
277 
278 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
279  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
280 #endif
281 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
282  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
283 #else
284  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
285 #endif
286 
287 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
288  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
289 #endif
290 #if defined(__EMSCRIPTEN__)
291  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
292 #endif
293 
294 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
295  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
296 #endif
297 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
298  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
299 #else
300  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
301 #endif
302 
303 #if defined(JSON_HEDLEY_ARM_VERSION)
304  #undef JSON_HEDLEY_ARM_VERSION
305 #endif
306 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
307  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
308 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
309  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
310 #endif
311 
312 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
313  #undef JSON_HEDLEY_ARM_VERSION_CHECK
314 #endif
315 #if defined(JSON_HEDLEY_ARM_VERSION)
316  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
317 #else
318  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
319 #endif
320 
321 #if defined(JSON_HEDLEY_IBM_VERSION)
322  #undef JSON_HEDLEY_IBM_VERSION
323 #endif
324 #if defined(__ibmxl__)
325  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
326 #elif defined(__xlC__) && defined(__xlC_ver__)
327  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
328 #elif defined(__xlC__)
329  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
330 #endif
331 
332 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
333  #undef JSON_HEDLEY_IBM_VERSION_CHECK
334 #endif
335 #if defined(JSON_HEDLEY_IBM_VERSION)
336  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
337 #else
338  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
339 #endif
340 
341 #if defined(JSON_HEDLEY_TI_VERSION)
342  #undef JSON_HEDLEY_TI_VERSION
343 #endif
344 #if \
345  defined(__TI_COMPILER_VERSION__) && \
346  ( \
347  defined(__TMS470__) || defined(__TI_ARM__) || \
348  defined(__MSP430__) || \
349  defined(__TMS320C2000__) \
350  )
351 #if (__TI_COMPILER_VERSION__ >= 16000000)
352  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
353 #endif
354 #endif
355 
356 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
357  #undef JSON_HEDLEY_TI_VERSION_CHECK
358 #endif
359 #if defined(JSON_HEDLEY_TI_VERSION)
360  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
361 #else
362  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
363 #endif
364 
365 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
366  #undef JSON_HEDLEY_TI_CL2000_VERSION
367 #endif
368 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
369  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
370 #endif
371 
372 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
373  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
374 #endif
375 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
376  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
377 #else
378  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
379 #endif
380 
381 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
382  #undef JSON_HEDLEY_TI_CL430_VERSION
383 #endif
384 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
385  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
386 #endif
387 
388 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
389  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
390 #endif
391 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
392  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
393 #else
394  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
395 #endif
396 
397 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
398  #undef JSON_HEDLEY_TI_ARMCL_VERSION
399 #endif
400 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
401  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
402 #endif
403 
404 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
405  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
406 #endif
407 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
408  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
409 #else
410  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
411 #endif
412 
413 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
414  #undef JSON_HEDLEY_TI_CL6X_VERSION
415 #endif
416 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
417  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
418 #endif
419 
420 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
421  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
422 #endif
423 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
424  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
425 #else
426  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
427 #endif
428 
429 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
430  #undef JSON_HEDLEY_TI_CL7X_VERSION
431 #endif
432 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
433  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
434 #endif
435 
436 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
437  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
438 #endif
439 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
440  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
441 #else
442  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
443 #endif
444 
445 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
446  #undef JSON_HEDLEY_TI_CLPRU_VERSION
447 #endif
448 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
449  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
450 #endif
451 
452 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
453  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
454 #endif
455 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
456  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
457 #else
458  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
459 #endif
460 
461 #if defined(JSON_HEDLEY_CRAY_VERSION)
462  #undef JSON_HEDLEY_CRAY_VERSION
463 #endif
464 #if defined(_CRAYC)
465  #if defined(_RELEASE_PATCHLEVEL)
466  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
467  #else
468  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
469  #endif
470 #endif
471 
472 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
473  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
474 #endif
475 #if defined(JSON_HEDLEY_CRAY_VERSION)
476  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
477 #else
478  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
479 #endif
480 
481 #if defined(JSON_HEDLEY_IAR_VERSION)
482  #undef JSON_HEDLEY_IAR_VERSION
483 #endif
484 #if defined(__IAR_SYSTEMS_ICC__)
485  #if __VER__ > 1000
486  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
487  #else
488  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
489  #endif
490 #endif
491 
492 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
493  #undef JSON_HEDLEY_IAR_VERSION_CHECK
494 #endif
495 #if defined(JSON_HEDLEY_IAR_VERSION)
496  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
497 #else
498  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
499 #endif
500 
501 #if defined(JSON_HEDLEY_TINYC_VERSION)
502  #undef JSON_HEDLEY_TINYC_VERSION
503 #endif
504 #if defined(__TINYC__)
505  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
506 #endif
507 
508 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
509  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
510 #endif
511 #if defined(JSON_HEDLEY_TINYC_VERSION)
512  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
513 #else
514  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
515 #endif
516 
517 #if defined(JSON_HEDLEY_DMC_VERSION)
518  #undef JSON_HEDLEY_DMC_VERSION
519 #endif
520 #if defined(__DMC__)
521  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
522 #endif
523 
524 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
525  #undef JSON_HEDLEY_DMC_VERSION_CHECK
526 #endif
527 #if defined(JSON_HEDLEY_DMC_VERSION)
528  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
529 #else
530  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
531 #endif
532 
533 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
534  #undef JSON_HEDLEY_COMPCERT_VERSION
535 #endif
536 #if defined(__COMPCERT_VERSION__)
537  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
538 #endif
539 
540 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
541  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
542 #endif
543 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
544  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
545 #else
546  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
547 #endif
548 
549 #if defined(JSON_HEDLEY_PELLES_VERSION)
550  #undef JSON_HEDLEY_PELLES_VERSION
551 #endif
552 #if defined(__POCC__)
553  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
554 #endif
555 
556 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
557  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
558 #endif
559 #if defined(JSON_HEDLEY_PELLES_VERSION)
560  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
561 #else
562  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
563 #endif
564 
565 #if defined(JSON_HEDLEY_GCC_VERSION)
566  #undef JSON_HEDLEY_GCC_VERSION
567 #endif
568 #if \
569  defined(JSON_HEDLEY_GNUC_VERSION) && \
570  !defined(__clang__) && \
571  !defined(JSON_HEDLEY_INTEL_VERSION) && \
572  !defined(JSON_HEDLEY_PGI_VERSION) && \
573  !defined(JSON_HEDLEY_ARM_VERSION) && \
574  !defined(JSON_HEDLEY_TI_VERSION) && \
575  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
576  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
577  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
578  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
579  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
580  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
581  !defined(__COMPCERT__)
582  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
583 #endif
584 
585 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
586  #undef JSON_HEDLEY_GCC_VERSION_CHECK
587 #endif
588 #if defined(JSON_HEDLEY_GCC_VERSION)
589  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
590 #else
591  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
592 #endif
593 
594 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
595  #undef JSON_HEDLEY_HAS_ATTRIBUTE
596 #endif
597 #if defined(__has_attribute)
598  #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
599 #else
600  #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
601 #endif
602 
603 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
604  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
605 #endif
606 #if defined(__has_attribute)
607  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
608 #else
609  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
610 #endif
611 
612 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
613  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
614 #endif
615 #if defined(__has_attribute)
616  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
617 #else
618  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
619 #endif
620 
621 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
622  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
623 #endif
624 #if \
625  defined(__has_cpp_attribute) && \
626  defined(__cplusplus) && \
627  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
628  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
629 #else
630  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
631 #endif
632 
633 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
634  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
635 #endif
636 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
637  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
638 #elif \
639  !defined(JSON_HEDLEY_PGI_VERSION) && \
640  !defined(JSON_HEDLEY_IAR_VERSION) && \
641  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
642  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
643  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
644 #else
645  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
646 #endif
647 
648 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
649  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
650 #endif
651 #if defined(__has_cpp_attribute) && defined(__cplusplus)
652  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
653 #else
654  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
655 #endif
656 
657 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
658  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
659 #endif
660 #if defined(__has_cpp_attribute) && defined(__cplusplus)
661  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
662 #else
663  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
664 #endif
665 
666 #if defined(JSON_HEDLEY_HAS_BUILTIN)
667  #undef JSON_HEDLEY_HAS_BUILTIN
668 #endif
669 #if defined(__has_builtin)
670  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
671 #else
672  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
673 #endif
674 
675 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
676  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
677 #endif
678 #if defined(__has_builtin)
679  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
680 #else
681  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
682 #endif
683 
684 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
685  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
686 #endif
687 #if defined(__has_builtin)
688  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
689 #else
690  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
691 #endif
692 
693 #if defined(JSON_HEDLEY_HAS_FEATURE)
694  #undef JSON_HEDLEY_HAS_FEATURE
695 #endif
696 #if defined(__has_feature)
697  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
698 #else
699  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
700 #endif
701 
702 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
703  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
704 #endif
705 #if defined(__has_feature)
706  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
707 #else
708  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
709 #endif
710 
711 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
712  #undef JSON_HEDLEY_GCC_HAS_FEATURE
713 #endif
714 #if defined(__has_feature)
715  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
716 #else
717  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
718 #endif
719 
720 #if defined(JSON_HEDLEY_HAS_EXTENSION)
721  #undef JSON_HEDLEY_HAS_EXTENSION
722 #endif
723 #if defined(__has_extension)
724  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
725 #else
726  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
727 #endif
728 
729 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
730  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
731 #endif
732 #if defined(__has_extension)
733  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
734 #else
735  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
736 #endif
737 
738 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
739  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
740 #endif
741 #if defined(__has_extension)
742  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
743 #else
744  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
745 #endif
746 
747 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
748  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
749 #endif
750 #if defined(__has_declspec_attribute)
751  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
752 #else
753  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
754 #endif
755 
756 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
757  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
758 #endif
759 #if defined(__has_declspec_attribute)
760  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
761 #else
762  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
763 #endif
764 
765 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
766  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
767 #endif
768 #if defined(__has_declspec_attribute)
769  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
770 #else
771  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
772 #endif
773 
774 #if defined(JSON_HEDLEY_HAS_WARNING)
775  #undef JSON_HEDLEY_HAS_WARNING
776 #endif
777 #if defined(__has_warning)
778  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
779 #else
780  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
781 #endif
782 
783 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
784  #undef JSON_HEDLEY_GNUC_HAS_WARNING
785 #endif
786 #if defined(__has_warning)
787  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
788 #else
789  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
790 #endif
791 
792 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
793  #undef JSON_HEDLEY_GCC_HAS_WARNING
794 #endif
795 #if defined(__has_warning)
796  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
797 #else
798  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
799 #endif
800 
801 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
802  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
803 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
804  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
805 #endif
806 #if defined(__cplusplus)
807 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
808 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
809 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
810  JSON_HEDLEY_DIAGNOSTIC_PUSH \
811  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
812  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
813  xpr \
814  JSON_HEDLEY_DIAGNOSTIC_POP
815 # else
816 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
817  JSON_HEDLEY_DIAGNOSTIC_PUSH \
818  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
819  xpr \
820  JSON_HEDLEY_DIAGNOSTIC_POP
821 # endif
822 # endif
823 #endif
824 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
825  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
826 #endif
827 
828 #if defined(JSON_HEDLEY_CONST_CAST)
829  #undef JSON_HEDLEY_CONST_CAST
830 #endif
831 #if defined(__cplusplus)
832 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
833 #elif \
834  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
835  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
836  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
837 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
838  JSON_HEDLEY_DIAGNOSTIC_PUSH \
839  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
840  ((T) (expr)); \
841  JSON_HEDLEY_DIAGNOSTIC_POP \
842  }))
843 #else
844 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
845 #endif
846 
847 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
848  #undef JSON_HEDLEY_REINTERPRET_CAST
849 #endif
850 #if defined(__cplusplus)
851  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
852 #else
853  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
854 #endif
855 
856 #if defined(JSON_HEDLEY_STATIC_CAST)
857  #undef JSON_HEDLEY_STATIC_CAST
858 #endif
859 #if defined(__cplusplus)
860  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
861 #else
862  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
863 #endif
864 
865 #if defined(JSON_HEDLEY_CPP_CAST)
866  #undef JSON_HEDLEY_CPP_CAST
867 #endif
868 #if defined(__cplusplus)
869 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
870 # define JSON_HEDLEY_CPP_CAST(T, expr) \
871  JSON_HEDLEY_DIAGNOSTIC_PUSH \
872  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
873  ((T) (expr)) \
874  JSON_HEDLEY_DIAGNOSTIC_POP
875 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
876 # define JSON_HEDLEY_CPP_CAST(T, expr) \
877  JSON_HEDLEY_DIAGNOSTIC_PUSH \
878  _Pragma("diag_suppress=Pe137") \
879  JSON_HEDLEY_DIAGNOSTIC_POP \
880 # else
881 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
882 # endif
883 #else
884 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
885 #endif
886 
887 #if \
888  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
889  defined(__clang__) || \
890  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
891  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
892  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
893  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
894  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
895  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
896  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
897  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
898  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
899  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
900  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
901  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
902  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
903  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
904  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
905  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
906  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
907 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
908  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
909 #else
910  #define JSON_HEDLEY_PRAGMA(value)
911 #endif
912 
913 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
914  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
915 #endif
916 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
917  #undef JSON_HEDLEY_DIAGNOSTIC_POP
918 #endif
919 #if defined(__clang__)
920  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
921  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
922 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
923  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
924  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
925 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
926  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
927  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
928 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
929  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
930  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
931 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
932  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
933  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
934 #elif \
935  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
936  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
937  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
938  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
939  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
940  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
941  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
942  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
943 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
944  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
945  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
946 #else
947  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
948  #define JSON_HEDLEY_DIAGNOSTIC_POP
949 #endif
950 
951 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
952  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
953 #endif
954 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
955  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
956 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
957  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
958 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
959  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
960 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
961  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
962 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
963  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
964 #elif \
965  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
966  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
967  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
968  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
969  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
970  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
971  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
972  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
973  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
974  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
975  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
976  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
977 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
978  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
979 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
980  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
981 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
982  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
983 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
984  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
985 #else
986  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
987 #endif
988 
989 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
990  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
991 #endif
992 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
993  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
994 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
995  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
996 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
997  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
998 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
999  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1000 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1001  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1002 #elif \
1003  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1004  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1005  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1006  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1007  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1008 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1009  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1010 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1011  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1012 #else
1013  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1014 #endif
1015 
1016 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1017  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1018 #endif
1019 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1020  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1021 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1022  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1023 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1024  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1025 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1026  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1027 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1028  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1029 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1030  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1031 #elif \
1032  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1033  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1034  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1035  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1036 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1037  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1038 #else
1039  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1040 #endif
1041 
1042 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1043  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1044 #endif
1045 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1046  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1047 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1048  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1049 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1050  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1051 #else
1052  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1053 #endif
1054 
1055 #if defined(JSON_HEDLEY_DEPRECATED)
1056  #undef JSON_HEDLEY_DEPRECATED
1057 #endif
1058 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1059  #undef JSON_HEDLEY_DEPRECATED_FOR
1060 #endif
1061 #if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
1062  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1063  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1064 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1065  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1066  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1067 #elif \
1068  JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1069  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1070  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1071  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1072  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1073  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1074  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1075  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1076  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1077  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1078  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1079  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1080  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1081 #elif \
1082  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1083  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1084  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1085  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1086  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1087  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1088  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1089  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1090  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1091  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1092  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1093  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1094  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1095  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1096  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1097  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1098 #elif \
1099  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1100  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
1101  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1102  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1103 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1104  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1105  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1106 #else
1107  #define JSON_HEDLEY_DEPRECATED(since)
1108  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1109 #endif
1110 
1111 #if defined(JSON_HEDLEY_UNAVAILABLE)
1112  #undef JSON_HEDLEY_UNAVAILABLE
1113 #endif
1114 #if \
1115  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1116  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1117  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1118  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1119 #else
1120  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1121 #endif
1122 
1123 #if defined()
1124  #undef
1125 #endif
1126 #if defined(_MSG)
1127  #undef _MSG
1128 #endif
1129 #if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1130  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1131  #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1132 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1133  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1134  #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1135 #elif \
1136  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1137  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1138  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1139  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1140  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1141  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1142  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1143  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1144  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1145  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1146  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1147  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1148  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1149  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1150  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1151  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1152  #define __attribute__((__warn_unused_result__))
1153  #define _MSG(msg) __attribute__((__warn_unused_result__))
1154 #elif defined(_Check_return_) /* SAL */
1155  #define _Check_return_
1156  #define _MSG(msg) _Check_return_
1157 #else
1158  #define
1159  #define _MSG(msg)
1160 #endif
1161 
1162 #if defined(JSON_HEDLEY_SENTINEL)
1163  #undef JSON_HEDLEY_SENTINEL
1164 #endif
1165 #if \
1166  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1167  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1168  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1169  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1170  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1171 #else
1172  #define JSON_HEDLEY_SENTINEL(position)
1173 #endif
1174 
1175 #if defined(JSON_HEDLEY_NO_RETURN)
1176  #undef JSON_HEDLEY_NO_RETURN
1177 #endif
1178 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1179  #define JSON_HEDLEY_NO_RETURN __noreturn
1180 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1181  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1182 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1183  #define JSON_HEDLEY_NO_RETURN _Noreturn
1184 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1185  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1186 #elif \
1187  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1188  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1189  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1190  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1191  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1192  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1193  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1194  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1195  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1196  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1197  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1198  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1199  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1200  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1201  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1202  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1203  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1204 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1205  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1206 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1207  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1208 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1209  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1210 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1211  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1212 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1213  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1214 #else
1215  #define JSON_HEDLEY_NO_RETURN
1216 #endif
1217 
1218 #if defined(JSON_HEDLEY_NO_ESCAPE)
1219  #undef JSON_HEDLEY_NO_ESCAPE
1220 #endif
1221 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1222  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1223 #else
1224  #define JSON_HEDLEY_NO_ESCAPE
1225 #endif
1226 
1227 #if defined(JSON_HEDLEY_UNREACHABLE)
1228  #undef JSON_HEDLEY_UNREACHABLE
1229 #endif
1230 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1231  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1232 #endif
1233 #if defined(JSON_HEDLEY_ASSUME)
1234  #undef JSON_HEDLEY_ASSUME
1235 #endif
1236 #if \
1237  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1239  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1240 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1241  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1242 #elif \
1243  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1244  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1245  #if defined(__cplusplus)
1246  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1247  #else
1248  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1249  #endif
1250 #endif
1251 #if \
1252  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1253  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1254  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1255  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1256  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1257  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1258 #elif defined(JSON_HEDLEY_ASSUME)
1259  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1260 #endif
1261 #if !defined(JSON_HEDLEY_ASSUME)
1262  #if defined(JSON_HEDLEY_UNREACHABLE)
1263  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1264  #else
1265  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1266  #endif
1267 #endif
1268 #if defined(JSON_HEDLEY_UNREACHABLE)
1269  #if \
1270  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1271  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1272  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1273  #else
1274  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1275  #endif
1276 #else
1277  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1278 #endif
1279 #if !defined(JSON_HEDLEY_UNREACHABLE)
1280  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1281 #endif
1282 
1283 JSON_HEDLEY_DIAGNOSTIC_PUSH
1284 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1285  #pragma clang diagnostic ignored "-Wpedantic"
1286 #endif
1287 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1288  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1289 #endif
1290 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1291  #if defined(__clang__)
1292  #pragma clang diagnostic ignored "-Wvariadic-macros"
1293  #elif defined(JSON_HEDLEY_GCC_VERSION)
1294  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1295  #endif
1296 #endif
1297 #if defined(JSON_HEDLEY_NON_NULL)
1298  #undef JSON_HEDLEY_NON_NULL
1299 #endif
1300 #if \
1301  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1302  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1303  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1304  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1305  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1306 #else
1307  #define JSON_HEDLEY_NON_NULL(...)
1308 #endif
1309 JSON_HEDLEY_DIAGNOSTIC_POP
1310 
1311 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1312  #undef JSON_HEDLEY_PRINTF_FORMAT
1313 #endif
1314 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1315  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1316 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1317  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1318 #elif \
1319  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1320  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1321  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1322  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1323  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1324  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1325  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1326  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1327  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1328  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1329  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1330  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1331  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1332  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1333  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1334  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1335  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1336 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1337  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1338 #else
1339  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1340 #endif
1341 
1342 #if defined(JSON_HEDLEY_CONSTEXPR)
1343  #undef JSON_HEDLEY_CONSTEXPR
1344 #endif
1345 #if defined(__cplusplus)
1346  #if __cplusplus >= 201103L
1347  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1348  #endif
1349 #endif
1350 #if !defined(JSON_HEDLEY_CONSTEXPR)
1351  #define JSON_HEDLEY_CONSTEXPR
1352 #endif
1353 
1354 #if defined(JSON_HEDLEY_PREDICT)
1355  #undef JSON_HEDLEY_PREDICT
1356 #endif
1357 #if defined(JSON_HEDLEY_LIKELY)
1358  #undef JSON_HEDLEY_LIKELY
1359 #endif
1360 #if defined(JSON_HEDLEY_UNLIKELY)
1361  #undef JSON_HEDLEY_UNLIKELY
1362 #endif
1363 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1364  #undef JSON_HEDLEY_UNPREDICTABLE
1365 #endif
1366 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1367  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1368 #endif
1369 #if \
1370  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1371  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1372 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1373 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1374 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1375 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1376 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1377 #elif \
1378  JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1379  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1380  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1381  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1382  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1383  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1384  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1385  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1386  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1387  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1388  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1389  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1390  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1391  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1392  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1393 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1394  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1395 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1396  (__extension__ ({ \
1397  double hedley_probability_ = (probability); \
1398  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1399  }))
1400 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1401  (__extension__ ({ \
1402  double hedley_probability_ = (probability); \
1403  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1404  }))
1405 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1406 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1407 #else
1408 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1409 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1410 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1411 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1412 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1413 #endif
1414 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1415  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1416 #endif
1417 
1418 #if defined(JSON_HEDLEY_MALLOC)
1419  #undef JSON_HEDLEY_MALLOC
1420 #endif
1421 #if \
1422  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1423  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1424  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1425  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1426  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1427  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1428  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1429  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1430  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1431  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1432  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1433  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1434  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1435  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1436  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1437  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1438  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1439  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1440 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1441  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1442 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1443  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1444 #else
1445  #define JSON_HEDLEY_MALLOC
1446 #endif
1447 
1448 #if defined(JSON_HEDLEY_PURE)
1449  #undef JSON_HEDLEY_PURE
1450 #endif
1451 #if \
1452  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1453  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1454  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1456  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1457  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1458  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1459  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1460  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1461  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1462  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1463  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1464  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1465  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1466  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1467  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1468  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1469  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1470 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1471 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1472 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1473 #elif defined(__cplusplus) && \
1474  ( \
1475  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1476  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1477  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1478  )
1479 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1480 #else
1481 # define JSON_HEDLEY_PURE
1482 #endif
1483 
1484 #if defined(JSON_HEDLEY_CONST)
1485  #undef JSON_HEDLEY_CONST
1486 #endif
1487 #if \
1488  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1489  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1490  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1491  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1492  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1493  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1494  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1495  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1496  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1497  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1498  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1499  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1500  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1501  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1502  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1503  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1504  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1505  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1506  #define JSON_HEDLEY_CONST __attribute__((__const__))
1507 #elif \
1508  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1509  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1510 #else
1511  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1512 #endif
1513 
1514 #if defined(JSON_HEDLEY_RESTRICT)
1515  #undef JSON_HEDLEY_RESTRICT
1516 #endif
1517 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1518  #define JSON_HEDLEY_RESTRICT restrict
1519 #elif \
1520  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1521  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1522  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1523  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1524  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1525  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1526  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1527  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1528  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1529  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1530  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1531  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1532  defined(__clang__)
1533  #define JSON_HEDLEY_RESTRICT __restrict
1534 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1535  #define JSON_HEDLEY_RESTRICT _Restrict
1536 #else
1537  #define JSON_HEDLEY_RESTRICT
1538 #endif
1539 
1540 #if defined(JSON_HEDLEY_INLINE)
1541  #undef JSON_HEDLEY_INLINE
1542 #endif
1543 #if \
1544  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1545  (defined(__cplusplus) && (__cplusplus >= 199711L))
1546  #define JSON_HEDLEY_INLINE inline
1547 #elif \
1548  defined(JSON_HEDLEY_GCC_VERSION) || \
1549  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1550  #define JSON_HEDLEY_INLINE __inline__
1551 #elif \
1552  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1553  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1554  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1555  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1556  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1557  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1558  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1559  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1560  #define JSON_HEDLEY_INLINE __inline
1561 #else
1562  #define JSON_HEDLEY_INLINE
1563 #endif
1564 
1565 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1566  #undef JSON_HEDLEY_ALWAYS_INLINE
1567 #endif
1568 #if \
1569  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1570  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1571  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1572  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1573  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1574  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1575  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1576  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1577  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1578  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1579  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1580  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1581  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1582  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1583  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1584  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1585  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1586 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1587 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1588 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1589 #elif defined(__cplusplus) && \
1590  ( \
1591  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1592  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1593  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1594  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1595  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1596  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1597  )
1598 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1599 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1600 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1601 #else
1602 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1603 #endif
1604 
1605 #if defined(JSON_HEDLEY_NEVER_INLINE)
1606  #undef JSON_HEDLEY_NEVER_INLINE
1607 #endif
1608 #if \
1609  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1610  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1611  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1626  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1627 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1628  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1629 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1630  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1631 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1632  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1633 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1634  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1635 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1636  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1637 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1638  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1639 #else
1640  #define JSON_HEDLEY_NEVER_INLINE
1641 #endif
1642 
1643 #if defined(JSON_HEDLEY_PRIVATE)
1644  #undef JSON_HEDLEY_PRIVATE
1645 #endif
1646 #if defined(JSON_HEDLEY_PUBLIC)
1647  #undef JSON_HEDLEY_PUBLIC
1648 #endif
1649 #if defined(JSON_HEDLEY_IMPORT)
1650  #undef JSON_HEDLEY_IMPORT
1651 #endif
1652 #if defined(_WIN32) || defined(__CYGWIN__)
1653 # define JSON_HEDLEY_PRIVATE
1654 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1655 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1656 #else
1657 # if \
1658  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1659  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1660  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1661  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1662  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1663  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1664  ( \
1665  defined(__TI_EABI__) && \
1666  ( \
1667  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1668  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1669  ) \
1670  )
1671 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1672 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1673 # else
1674 # define JSON_HEDLEY_PRIVATE
1675 # define JSON_HEDLEY_PUBLIC
1676 # endif
1677 # define JSON_HEDLEY_IMPORT extern
1678 #endif
1679 
1680 #if defined(JSON_HEDLEY_NO_THROW)
1681  #undef JSON_HEDLEY_NO_THROW
1682 #endif
1683 #if \
1684  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1685  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1686  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1687  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1688 #elif \
1689  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1690  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1691  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1692 #else
1693  #define JSON_HEDLEY_NO_THROW
1694 #endif
1695 
1696 #if defined(JSON_HEDLEY_FALL_THROUGH)
1697  #undef JSON_HEDLEY_FALL_THROUGH
1698 #endif
1699 #if \
1700  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1701  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1702  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1703 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1704  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1705 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1706  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1707 #elif defined(__fallthrough) /* SAL */
1708  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1709 #else
1710  #define JSON_HEDLEY_FALL_THROUGH
1711 #endif
1712 
1713 #if defined()
1714  #undef
1715 #endif
1716 #if \
1717  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1718  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1719  #define __attribute__((__returns_nonnull__))
1720 #elif defined(_Ret_notnull_) /* SAL */
1721  #define _Ret_notnull_
1722 #else
1723  #define
1724 #endif
1725 
1726 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1727  #undef JSON_HEDLEY_ARRAY_PARAM
1728 #endif
1729 #if \
1730  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1731  !defined(__STDC_NO_VLA__) && \
1732  !defined(__cplusplus) && \
1733  !defined(JSON_HEDLEY_PGI_VERSION) && \
1734  !defined(JSON_HEDLEY_TINYC_VERSION)
1735  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1736 #else
1737  #define JSON_HEDLEY_ARRAY_PARAM(name)
1738 #endif
1739 
1740 #if defined(JSON_HEDLEY_IS_CONSTANT)
1741  #undef JSON_HEDLEY_IS_CONSTANT
1742 #endif
1743 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1744  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1745 #endif
1746 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1747  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1748 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1749  #undef JSON_HEDLEY_IS_CONSTEXPR_
1750 #endif
1751 #if \
1752  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1753  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1754  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1755  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1756  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1757  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1758  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1759  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1760  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1761  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1762 #endif
1763 #if !defined(__cplusplus)
1764 # if \
1765  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1766  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1767  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1768  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1769  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1770  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1771  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1772 #if defined(__INTPTR_TYPE__)
1773  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1774 #else
1775  #include <stdint.h>
1776  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1777 #endif
1778 # elif \
1779  ( \
1780  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1781  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1782  !defined(JSON_HEDLEY_PGI_VERSION) && \
1783  !defined(JSON_HEDLEY_IAR_VERSION)) || \
1784  JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1785  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1786  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1787  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1788  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1789 #if defined(__INTPTR_TYPE__)
1790  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1791 #else
1792  #include <stdint.h>
1793  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1794 #endif
1795 # elif \
1796  defined(JSON_HEDLEY_GCC_VERSION) || \
1797  defined(JSON_HEDLEY_INTEL_VERSION) || \
1798  defined(JSON_HEDLEY_TINYC_VERSION) || \
1799  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1800  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1801  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1802  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1803  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1804  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1805  defined(__clang__)
1806 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1807  sizeof(void) != \
1808  sizeof(*( \
1809  1 ? \
1810  ((void*) ((expr) * 0L) ) : \
1811 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1812  ) \
1813  ) \
1814  )
1815 # endif
1816 #endif
1817 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1818  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1819  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1820  #endif
1821  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1822 #else
1823  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1824  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1825  #endif
1826  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1827 #endif
1828 
1829 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1830  #undef JSON_HEDLEY_BEGIN_C_DECLS
1831 #endif
1832 #if defined(JSON_HEDLEY_END_C_DECLS)
1833  #undef JSON_HEDLEY_END_C_DECLS
1834 #endif
1835 #if defined(JSON_HEDLEY_C_DECL)
1836  #undef JSON_HEDLEY_C_DECL
1837 #endif
1838 #if defined(__cplusplus)
1839  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1840  #define JSON_HEDLEY_END_C_DECLS }
1841  #define JSON_HEDLEY_C_DECL extern "C"
1842 #else
1843  #define JSON_HEDLEY_BEGIN_C_DECLS
1844  #define JSON_HEDLEY_END_C_DECLS
1845  #define JSON_HEDLEY_C_DECL
1846 #endif
1847 
1848 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1849  #undef JSON_HEDLEY_STATIC_ASSERT
1850 #endif
1851 #if \
1852  !defined(__cplusplus) && ( \
1853  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1854  JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1855  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1856  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1857  defined(_Static_assert) \
1858  )
1859 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1860 #elif \
1861  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1862  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
1863 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1864 #else
1865 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1866 #endif
1867 
1868 #if defined(JSON_HEDLEY_NULL)
1869  #undef JSON_HEDLEY_NULL
1870 #endif
1871 #if defined(__cplusplus)
1872  #if __cplusplus >= 201103L
1873  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1874  #elif defined(NULL)
1875  #define JSON_HEDLEY_NULL NULL
1876  #else
1877  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1878  #endif
1879 #elif defined(NULL)
1880  #define JSON_HEDLEY_NULL NULL
1881 #else
1882  #define JSON_HEDLEY_NULL ((void*) 0)
1883 #endif
1884 
1885 #if defined(JSON_HEDLEY_MESSAGE)
1886  #undef JSON_HEDLEY_MESSAGE
1887 #endif
1888 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1889 # define JSON_HEDLEY_MESSAGE(msg) \
1890  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1891  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1892  JSON_HEDLEY_PRAGMA(message msg) \
1893  JSON_HEDLEY_DIAGNOSTIC_POP
1894 #elif \
1895  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1896  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1897 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1898 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1899 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1900 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1901 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1902 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1903 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1904 #else
1905 # define JSON_HEDLEY_MESSAGE(msg)
1906 #endif
1907 
1908 #if defined(JSON_HEDLEY_WARNING)
1909  #undef JSON_HEDLEY_WARNING
1910 #endif
1911 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1912 # define JSON_HEDLEY_WARNING(msg) \
1913  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1914  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1915  JSON_HEDLEY_PRAGMA(clang warning msg) \
1916  JSON_HEDLEY_DIAGNOSTIC_POP
1917 #elif \
1918  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1919  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1920  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1921 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1922 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1923 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1924 #else
1925 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1926 #endif
1927 
1928 #if defined(JSON_HEDLEY_REQUIRE)
1929  #undef JSON_HEDLEY_REQUIRE
1930 #endif
1931 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1932  #undef JSON_HEDLEY_REQUIRE_MSG
1933 #endif
1934 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1935 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1936 # define JSON_HEDLEY_REQUIRE(expr) \
1937  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1938  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1939  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1940  JSON_HEDLEY_DIAGNOSTIC_POP
1941 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1942  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1943  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1944  __attribute__((diagnose_if(!(expr), msg, "error"))) \
1945  JSON_HEDLEY_DIAGNOSTIC_POP
1946 # else
1947 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1948 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1949 # endif
1950 #else
1951 # define JSON_HEDLEY_REQUIRE(expr)
1952 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1953 #endif
1954 
1955 #if defined(JSON_HEDLEY_FLAGS)
1956  #undef JSON_HEDLEY_FLAGS
1957 #endif
1958 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1959  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1960 #endif
1961 
1962 #if defined(JSON_HEDLEY_FLAGS_CAST)
1963  #undef JSON_HEDLEY_FLAGS_CAST
1964 #endif
1965 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1966 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1967  JSON_HEDLEY_DIAGNOSTIC_PUSH \
1968  _Pragma("warning(disable:188)") \
1969  ((T) (expr)); \
1970  JSON_HEDLEY_DIAGNOSTIC_POP \
1971  }))
1972 #else
1973 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1974 #endif
1975 
1976 #if defined(JSON_HEDLEY_EMPTY_BASES)
1977  #undef JSON_HEDLEY_EMPTY_BASES
1978 #endif
1979 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1980  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1981 #else
1982  #define JSON_HEDLEY_EMPTY_BASES
1983 #endif
1984 
1985 /* Remaining macros are deprecated. */
1986 
1987 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1988  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1989 #endif
1990 #if defined(__clang__)
1991  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1992 #else
1993  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1994 #endif
1995 
1996 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1997  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1998 #endif
1999 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2000 
2001 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2002  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2003 #endif
2004 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2005 
2006 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2007  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2008 #endif
2009 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2010 
2011 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2012  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2013 #endif
2014 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2015 
2016 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2017  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2018 #endif
2019 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2020 
2021 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2022  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2023 #endif
2024 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2025 
2026 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2027  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2028 #endif
2029 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2030 
2031 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2032 
2033 
2034 // This file contains all internal macro definitions
2035 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2036 
2037 // exclude unsupported compilers
2038 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2039  #if defined(__clang__)
2040  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2041  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2042  #endif
2043  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2044  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2045  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2046  #endif
2047  #endif
2048 #endif
2049 
2050 // C++ language standard detection
2051 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2052  #define JSON_HAS_CPP_17
2053  #define JSON_HAS_CPP_14
2054 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2055  #define JSON_HAS_CPP_14
2056 #endif
2057 
2058 // disable float-equal warnings on GCC/clang
2059 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2060  #pragma GCC diagnostic push
2061  #pragma GCC diagnostic ignored "-Wfloat-equal"
2062 #endif
2063 
2064 // disable documentation warnings on clang
2065 #if defined(__clang__)
2066  #pragma GCC diagnostic push
2067  #pragma GCC diagnostic ignored "-Wdocumentation"
2068 #endif
2069 
2070 // allow to disable exceptions
2071 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2072  #define JSON_THROW(exception) throw exception
2073  #define JSON_TRY try
2074  #define JSON_CATCH(exception) catch(exception)
2075  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2076 #else
2077  #include <cstdlib>
2078  #define JSON_THROW(exception) std::abort()
2079  #define JSON_TRY if(true)
2080  #define JSON_CATCH(exception) if(false)
2081  #define JSON_INTERNAL_CATCH(exception) if(false)
2082 #endif
2083 
2084 // override exception macros
2085 #if defined(JSON_THROW_USER)
2086  #undef JSON_THROW
2087  #define JSON_THROW JSON_THROW_USER
2088 #endif
2089 #if defined(JSON_TRY_USER)
2090  #undef JSON_TRY
2091  #define JSON_TRY JSON_TRY_USER
2092 #endif
2093 #if defined(JSON_CATCH_USER)
2094  #undef JSON_CATCH
2095  #define JSON_CATCH JSON_CATCH_USER
2096  #undef JSON_INTERNAL_CATCH
2097  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2098 #endif
2099 #if defined(JSON_INTERNAL_CATCH_USER)
2100  #undef JSON_INTERNAL_CATCH
2101  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2102 #endif
2103 
2109 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2110  template<typename BasicJsonType> \
2111  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2112  { \
2113  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2114  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2115  auto it = std::find_if(std::begin(m), std::end(m), \
2116  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2117  { \
2118  return ej_pair.first == e; \
2119  }); \
2120  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2121  } \
2122  template<typename BasicJsonType> \
2123  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2124  { \
2125  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2126  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2127  auto it = std::find_if(std::begin(m), std::end(m), \
2128  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2129  { \
2130  return ej_pair.second == j; \
2131  }); \
2132  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2133  }
2134 
2135 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2136 // may be removed in the future once the class is split.
2137 
2138 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2139  template<template<typename, typename, typename...> class ObjectType, \
2140  template<typename, typename...> class ArrayType, \
2141  class StringType, class BooleanType, class NumberIntegerType, \
2142  class NumberUnsignedType, class NumberFloatType, \
2143  template<typename> class AllocatorType, \
2144  template<typename, typename = void> class JSONSerializer, \
2145  class BinaryType>
2146 
2147 #define NLOHMANN_BASIC_JSON_TPL \
2148  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2149  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2150  AllocatorType, JSONSerializer, BinaryType>
2151 
2152 
2153 namespace nlohmann
2154 {
2155 namespace detail
2156 {
2158 // exceptions //
2160 
2189 class exception : public std::exception
2190 {
2191  public:
2193 
2194  const char* what() const noexcept override
2195  {
2196  return m.what();
2197  }
2198 
2200  const int id;
2201 
2202  protected:
2203  JSON_HEDLEY_NON_NULL(3)
2204  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2205 
2206  static std::string name(const std::string& ename, int id_)
2207  {
2208  return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2209  }
2210 
2211  private:
2213  std::runtime_error m;
2214 };
2215 
2260 class parse_error : public exception
2261 {
2262  public:
2272  static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2273  {
2274  std::string w = exception::name("parse_error", id_) + "parse error" +
2275  position_string(pos) + ": " + what_arg;
2276  return parse_error(id_, pos.chars_read_total, w.c_str());
2277  }
2278 
2279  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2280  {
2281  std::string w = exception::name("parse_error", id_) + "parse error" +
2282  (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2283  ": " + what_arg;
2284  return parse_error(id_, byte_, w.c_str());
2285  }
2286 
2296  const std::size_t byte;
2297 
2298  private:
2299  parse_error(int id_, std::size_t byte_, const char* what_arg)
2300  : exception(id_, what_arg), byte(byte_) {}
2301 
2302  static std::string position_string(const position_t& pos)
2303  {
2304  return " at line " + std::to_string(pos.lines_read + 1) +
2305  ", column " + std::to_string(pos.chars_read_current_line);
2306  }
2307 };
2308 
2346 class invalid_iterator : public exception
2347 {
2348  public:
2349  static invalid_iterator create(int id_, const std::string& what_arg)
2350  {
2351  std::string w = exception::name("invalid_iterator", id_) + what_arg;
2352  return invalid_iterator(id_, w.c_str());
2353  }
2354 
2355  private:
2356  JSON_HEDLEY_NON_NULL(3)
2357  invalid_iterator(int id_, const char* what_arg)
2358  : exception(id_, what_arg) {}
2359 };
2360 
2400 class type_error : public exception
2401 {
2402  public:
2403  static type_error create(int id_, const std::string& what_arg)
2404  {
2405  std::string w = exception::name("type_error", id_) + what_arg;
2406  return type_error(id_, w.c_str());
2407  }
2408 
2409  private:
2410  JSON_HEDLEY_NON_NULL(3)
2411  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2412 };
2413 
2447 class out_of_range : public exception
2448 {
2449  public:
2450  static out_of_range create(int id_, const std::string& what_arg)
2451  {
2452  std::string w = exception::name("out_of_range", id_) + what_arg;
2453  return out_of_range(id_, w.c_str());
2454  }
2455 
2456  private:
2457  JSON_HEDLEY_NON_NULL(3)
2458  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2459 };
2460 
2485 class other_error : public exception
2486 {
2487  public:
2488  static other_error create(int id_, const std::string& what_arg)
2489  {
2490  std::string w = exception::name("other_error", id_) + what_arg;
2491  return other_error(id_, w.c_str());
2492  }
2493 
2494  private:
2495  JSON_HEDLEY_NON_NULL(3)
2496  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2497 };
2498 } // namespace detail
2499 } // namespace nlohmann
2500 
2501 // #include <nlohmann/detail/macro_scope.hpp>
2502 
2503 // #include <nlohmann/detail/meta/cpp_future.hpp>
2504 
2505 
2506 #include <cstddef> // size_t
2507 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2508 
2509 // #include <nlohmann/detail/boolean_operators.hpp>
2510 
2511 
2512 namespace nlohmann
2513 {
2514 namespace detail
2515 {
2516 // alias templates to reduce boilerplate
2517 template<bool B, typename T = void>
2518 using enable_if_t = typename std::enable_if<B, T>::type;
2519 
2520 template<typename T>
2521 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2522 
2523 // implementation of C++14 index_sequence and affiliates
2524 // source: https://stackoverflow.com/a/32223343
2525 template<std::size_t... Ints>
2526 struct index_sequence
2527 {
2528  using type = index_sequence;
2529  using value_type = std::size_t;
2530  static constexpr std::size_t size() noexcept
2531  {
2532  return sizeof...(Ints);
2533  }
2534 };
2535 
2536 template<class Sequence1, class Sequence2>
2537 struct merge_and_renumber;
2538 
2539 template<std::size_t... I1, std::size_t... I2>
2540 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2541  : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2542 
2543 template<std::size_t N>
2544 struct make_index_sequence
2545  : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2546  typename make_index_sequence < N - N / 2 >::type > {};
2547 
2548 template<> struct make_index_sequence<0> : index_sequence<> {};
2549 template<> struct make_index_sequence<1> : index_sequence<0> {};
2550 
2551 template<typename... Ts>
2552 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2553 
2554 // dispatch utility (taken from ranges-v3)
2555 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2556 template<> struct priority_tag<0> {};
2557 
2558 // taken from ranges-v3
2559 template<typename T>
2560 struct static_const
2561 {
2562  static constexpr T value{};
2563 };
2564 
2565 template<typename T>
2566 constexpr T static_const<T>::value;
2567 } // namespace detail
2568 } // namespace nlohmann
2569 
2570 // #include <nlohmann/detail/meta/type_traits.hpp>
2571 
2572 
2573 #include <limits> // numeric_limits
2574 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2575 #include <utility> // declval
2576 
2577 // #include <nlohmann/detail/boolean_operators.hpp>
2578 
2579 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2580 
2581 
2582 #include <iterator> // random_access_iterator_tag
2583 
2584 // #include <nlohmann/detail/meta/void_t.hpp>
2585 
2586 
2587 namespace nlohmann
2588 {
2589 namespace detail
2590 {
2591 template <typename ...Ts> struct make_void
2592 {
2593  using type = void;
2594 };
2595 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
2596 } // namespace detail
2597 } // namespace nlohmann
2598 
2599 // #include <nlohmann/detail/meta/cpp_future.hpp>
2600 
2601 
2602 namespace nlohmann
2603 {
2604 namespace detail
2605 {
2606 template <typename It, typename = void>
2607 struct iterator_types {};
2608 
2609 template <typename It>
2610 struct iterator_types <
2611  It,
2612  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2613  typename It::reference, typename It::iterator_category >>
2614 {
2615  using difference_type = typename It::difference_type;
2616  using value_type = typename It::value_type;
2617  using pointer = typename It::pointer;
2618  using reference = typename It::reference;
2619  using iterator_category = typename It::iterator_category;
2620 };
2621 
2622 // This is required as some compilers implement std::iterator_traits in a way that
2623 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2624 template <typename T, typename = void>
2625 struct iterator_traits
2626 {
2627 };
2628 
2629 template <typename T>
2630 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2631  : iterator_types<T>
2632 {
2633 };
2634 
2635 template <typename T>
2636 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2637 {
2638  using iterator_category = std::random_access_iterator_tag;
2639  using value_type = T;
2640  using difference_type = ptrdiff_t;
2641  using pointer = T*;
2642  using reference = T&;
2643 };
2644 } // namespace detail
2645 } // namespace nlohmann
2646 
2647 // #include <nlohmann/detail/macro_scope.hpp>
2648 
2649 // #include <nlohmann/detail/meta/cpp_future.hpp>
2650 
2651 // #include <nlohmann/detail/meta/detected.hpp>
2652 
2653 
2654 #include <type_traits>
2655 
2656 // #include <nlohmann/detail/meta/void_t.hpp>
2657 
2658 
2659 // https://en.cppreference.com/w/cpp/experimental/is_detected
2660 namespace nlohmann
2661 {
2662 namespace detail
2663 {
2664 struct nonesuch
2665 {
2666  nonesuch() = delete;
2667  ~nonesuch() = delete;
2668  nonesuch(nonesuch const&) = delete;
2669  nonesuch(nonesuch const&&) = delete;
2670  void operator=(nonesuch const&) = delete;
2671  void operator=(nonesuch&&) = delete;
2672 };
2673 
2674 template <class Default,
2675  class AlwaysVoid,
2676  template <class...> class Op,
2677  class... Args>
2678 struct detector
2679 {
2680  using value_t = std::false_type;
2681  using type = Default;
2682 };
2683 
2684 template <class Default, template <class...> class Op, class... Args>
2685 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2686 {
2687  using value_t = std::true_type;
2688  using type = Op<Args...>;
2689 };
2690 
2691 template <template <class...> class Op, class... Args>
2692 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2693 
2694 template <template <class...> class Op, class... Args>
2695 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2696 
2697 template <class Default, template <class...> class Op, class... Args>
2698 using detected_or = detector<Default, void, Op, Args...>;
2699 
2700 template <class Default, template <class...> class Op, class... Args>
2701 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2702 
2703 template <class Expected, template <class...> class Op, class... Args>
2704 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2705 
2706 template <class To, template <class...> class Op, class... Args>
2707 using is_detected_convertible =
2708  std::is_convertible<detected_t<Op, Args...>, To>;
2709 } // namespace detail
2710 } // namespace nlohmann
2711 
2712 // #include <nlohmann/json_fwd.hpp>
2713 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2714 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2715 
2716 #include <cstdint> // int64_t, uint64_t
2717 #include <map> // map
2718 #include <memory> // allocator
2719 #include <string> // string
2720 #include <vector> // vector
2721 
2727 namespace nlohmann
2728 {
2736 template<typename T = void, typename SFINAE = void>
2737 struct adl_serializer;
2738 
2739 template<template<typename U, typename V, typename... Args> class ObjectType =
2740  std::map,
2741  template<typename U, typename... Args> class ArrayType = std::vector,
2742  class StringType = std::string, class BooleanType = bool,
2743  class NumberIntegerType = std::int64_t,
2744  class NumberUnsignedType = std::uint64_t,
2745  class NumberFloatType = double,
2746  template<typename U> class AllocatorType = std::allocator,
2747  template<typename T, typename SFINAE = void> class JSONSerializer =
2748  adl_serializer,
2749  class BinaryType = std::vector<std::uint8_t>>
2750 class basic_json;
2751 
2763 template<typename BasicJsonType>
2764 class json_pointer;
2765 
2775 } // namespace nlohmann
2776 
2777 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2778 
2779 
2780 namespace nlohmann
2781 {
2790 namespace detail
2791 {
2793 // helpers //
2795 
2796 // Note to maintainers:
2797 //
2798 // Every trait in this file expects a non CV-qualified type.
2799 // The only exceptions are in the 'aliases for detected' section
2800 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2801 //
2802 // In this case, T has to be properly CV-qualified to constraint the function arguments
2803 // (e.g. to_json(BasicJsonType&, const T&))
2804 
2805 template<typename> struct is_basic_json : std::false_type {};
2806 
2807 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2808 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2809 
2811 // json_ref helpers //
2813 
2814 template <typename>
2815 class json_ref;
2816 
2817 template<typename>
2818 struct is_json_ref : std::false_type {};
2819 
2820 template <typename T>
2821 struct is_json_ref<json_ref<T>> : std::true_type {};
2822 
2824 // aliases for detected //
2826 
2827 template <typename T>
2828 using mapped_type_t = typename T::mapped_type;
2829 
2830 template <typename T>
2831 using key_type_t = typename T::key_type;
2832 
2833 template <typename T>
2834 using value_type_t = typename T::value_type;
2835 
2836 template <typename T>
2837 using difference_type_t = typename T::difference_type;
2838 
2839 template <typename T>
2840 using pointer_t = typename T::pointer;
2841 
2842 template <typename T>
2843 using reference_t = typename T::reference;
2844 
2845 template <typename T>
2846 using iterator_category_t = typename T::iterator_category;
2847 
2848 template <typename T>
2849 using iterator_t = typename T::iterator;
2850 
2851 template <typename T, typename... Args>
2852 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
2853 
2854 template <typename T, typename... Args>
2855 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
2856 
2857 template <typename T, typename U>
2858 using get_template_function = decltype(std::declval<T>().template get<U>());
2859 
2860 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
2861 template <typename BasicJsonType, typename T, typename = void>
2862 struct has_from_json : std::false_type {};
2863 
2864 template <typename BasicJsonType, typename T>
2865 struct has_from_json<BasicJsonType, T,
2866  enable_if_t<not is_basic_json<T>::value>>
2867 {
2868  using serializer = typename BasicJsonType::template json_serializer<T, void>;
2869 
2870  static constexpr bool value =
2871  is_detected_exact<void, from_json_function, serializer,
2872  const BasicJsonType&, T&>::value;
2873 };
2874 
2875 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
2876 // this overload is used for non-default-constructible user-defined-types
2877 template <typename BasicJsonType, typename T, typename = void>
2878 struct has_non_default_from_json : std::false_type {};
2879 
2880 template<typename BasicJsonType, typename T>
2881 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2882 {
2883  using serializer = typename BasicJsonType::template json_serializer<T, void>;
2884 
2885  static constexpr bool value =
2886  is_detected_exact<T, from_json_function, serializer,
2887  const BasicJsonType&>::value;
2888 };
2889 
2890 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
2891 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
2892 template <typename BasicJsonType, typename T, typename = void>
2893 struct has_to_json : std::false_type {};
2894 
2895 template <typename BasicJsonType, typename T>
2896 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
2897 {
2898  using serializer = typename BasicJsonType::template json_serializer<T, void>;
2899 
2900  static constexpr bool value =
2901  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
2902  T>::value;
2903 };
2904 
2905 
2907 // is_ functions //
2909 
2910 template <typename T, typename = void>
2911 struct is_iterator_traits : std::false_type {};
2912 
2913 template <typename T>
2914 struct is_iterator_traits<iterator_traits<T>>
2915 {
2916  private:
2917  using traits = iterator_traits<T>;
2918 
2919  public:
2920  static constexpr auto value =
2921  is_detected<value_type_t, traits>::value &&
2922  is_detected<difference_type_t, traits>::value &&
2923  is_detected<pointer_t, traits>::value &&
2924  is_detected<iterator_category_t, traits>::value &&
2925  is_detected<reference_t, traits>::value;
2926 };
2927 
2928 // source: https://stackoverflow.com/a/37193089/4116453
2929 
2930 template <typename T, typename = void>
2931 struct is_complete_type : std::false_type {};
2932 
2933 template <typename T>
2934 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
2935 
2936 template <typename BasicJsonType, typename CompatibleObjectType,
2937  typename = void>
2938 struct is_compatible_object_type_impl : std::false_type {};
2939 
2940 template <typename BasicJsonType, typename CompatibleObjectType>
2941 struct is_compatible_object_type_impl <
2942  BasicJsonType, CompatibleObjectType,
2943  enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
2944  is_detected<key_type_t, CompatibleObjectType>::value >>
2945 {
2946 
2947  using object_t = typename BasicJsonType::object_t;
2948 
2949  // macOS's is_constructible does not play well with nonesuch...
2950  static constexpr bool value =
2951  std::is_constructible<typename object_t::key_type,
2952  typename CompatibleObjectType::key_type>::value and
2953  std::is_constructible<typename object_t::mapped_type,
2954  typename CompatibleObjectType::mapped_type>::value;
2955 };
2956 
2957 template <typename BasicJsonType, typename CompatibleObjectType>
2958 struct is_compatible_object_type
2959  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
2960 
2961 template <typename BasicJsonType, typename ConstructibleObjectType,
2962  typename = void>
2963 struct is_constructible_object_type_impl : std::false_type {};
2964 
2965 template <typename BasicJsonType, typename ConstructibleObjectType>
2966 struct is_constructible_object_type_impl <
2967  BasicJsonType, ConstructibleObjectType,
2968  enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
2969  is_detected<key_type_t, ConstructibleObjectType>::value >>
2970 {
2971  using object_t = typename BasicJsonType::object_t;
2972 
2973  static constexpr bool value =
2974  (std::is_default_constructible<ConstructibleObjectType>::value and
2975  (std::is_move_assignable<ConstructibleObjectType>::value or
2976  std::is_copy_assignable<ConstructibleObjectType>::value) and
2977  (std::is_constructible<typename ConstructibleObjectType::key_type,
2978  typename object_t::key_type>::value and
2979  std::is_same <
2980  typename object_t::mapped_type,
2981  typename ConstructibleObjectType::mapped_type >::value)) or
2982  (has_from_json<BasicJsonType,
2983  typename ConstructibleObjectType::mapped_type>::value or
2984  has_non_default_from_json <
2985  BasicJsonType,
2986  typename ConstructibleObjectType::mapped_type >::value);
2987 };
2988 
2989 template <typename BasicJsonType, typename ConstructibleObjectType>
2990 struct is_constructible_object_type
2991  : is_constructible_object_type_impl<BasicJsonType,
2992  ConstructibleObjectType> {};
2993 
2994 template <typename BasicJsonType, typename CompatibleStringType,
2995  typename = void>
2996 struct is_compatible_string_type_impl : std::false_type {};
2997 
2998 template <typename BasicJsonType, typename CompatibleStringType>
2999 struct is_compatible_string_type_impl <
3000  BasicJsonType, CompatibleStringType,
3001  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3002  value_type_t, CompatibleStringType>::value >>
3003 {
3004  static constexpr auto value =
3005  std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3006 };
3007 
3008 template <typename BasicJsonType, typename ConstructibleStringType>
3009 struct is_compatible_string_type
3010  : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3011 
3012 template <typename BasicJsonType, typename ConstructibleStringType,
3013  typename = void>
3014 struct is_constructible_string_type_impl : std::false_type {};
3015 
3016 template <typename BasicJsonType, typename ConstructibleStringType>
3017 struct is_constructible_string_type_impl <
3018  BasicJsonType, ConstructibleStringType,
3019  enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3020  value_type_t, ConstructibleStringType>::value >>
3021 {
3022  static constexpr auto value =
3023  std::is_constructible<ConstructibleStringType,
3024  typename BasicJsonType::string_t>::value;
3025 };
3026 
3027 template <typename BasicJsonType, typename ConstructibleStringType>
3028 struct is_constructible_string_type
3029  : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3030 
3031 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
3032 struct is_compatible_array_type_impl : std::false_type {};
3033 
3034 template <typename BasicJsonType, typename CompatibleArrayType>
3035 struct is_compatible_array_type_impl <
3036  BasicJsonType, CompatibleArrayType,
3037  enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
3038  is_detected<iterator_t, CompatibleArrayType>::value and
3039 // This is needed because json_reverse_iterator has a ::iterator type...
3040 // Therefore it is detected as a CompatibleArrayType.
3041 // The real fix would be to have an Iterable concept.
3042  not is_iterator_traits<
3043  iterator_traits<CompatibleArrayType>>::value >>
3044 {
3045  static constexpr bool value =
3046  std::is_constructible<BasicJsonType,
3047  typename CompatibleArrayType::value_type>::value;
3048 };
3049 
3050 template <typename BasicJsonType, typename CompatibleArrayType>
3051 struct is_compatible_array_type
3052  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3053 
3054 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3055 struct is_constructible_array_type_impl : std::false_type {};
3056 
3057 template <typename BasicJsonType, typename ConstructibleArrayType>
3058 struct is_constructible_array_type_impl <
3059  BasicJsonType, ConstructibleArrayType,
3060  enable_if_t<std::is_same<ConstructibleArrayType,
3061  typename BasicJsonType::value_type>::value >>
3062  : std::true_type {};
3063 
3064 template <typename BasicJsonType, typename ConstructibleArrayType>
3065 struct is_constructible_array_type_impl <
3066  BasicJsonType, ConstructibleArrayType,
3067  enable_if_t<not std::is_same<ConstructibleArrayType,
3068  typename BasicJsonType::value_type>::value and
3069  std::is_default_constructible<ConstructibleArrayType>::value and
3070 (std::is_move_assignable<ConstructibleArrayType>::value or
3071  std::is_copy_assignable<ConstructibleArrayType>::value) and
3072 is_detected<value_type_t, ConstructibleArrayType>::value and
3073 is_detected<iterator_t, ConstructibleArrayType>::value and
3074 is_complete_type<
3075 detected_t<value_type_t, ConstructibleArrayType>>::value >>
3076 {
3077  static constexpr bool value =
3078  // This is needed because json_reverse_iterator has a ::iterator type,
3079  // furthermore, std::back_insert_iterator (and other iterators) have a
3080  // base class `iterator`... Therefore it is detected as a
3081  // ConstructibleArrayType. The real fix would be to have an Iterable
3082  // concept.
3083  not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
3084 
3085  (std::is_same<typename ConstructibleArrayType::value_type,
3086  typename BasicJsonType::array_t::value_type>::value or
3087  has_from_json<BasicJsonType,
3088  typename ConstructibleArrayType::value_type>::value or
3089  has_non_default_from_json <
3090  BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3091 };
3092 
3093 template <typename BasicJsonType, typename ConstructibleArrayType>
3094 struct is_constructible_array_type
3095  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3096 
3097 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
3098  typename = void>
3099 struct is_compatible_integer_type_impl : std::false_type {};
3100 
3101 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
3102 struct is_compatible_integer_type_impl <
3103  RealIntegerType, CompatibleNumberIntegerType,
3104  enable_if_t<std::is_integral<RealIntegerType>::value and
3105  std::is_integral<CompatibleNumberIntegerType>::value and
3106  not std::is_same<bool, CompatibleNumberIntegerType>::value >>
3107 {
3108  // is there an assert somewhere on overflows?
3109  using RealLimits = std::numeric_limits<RealIntegerType>;
3110  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3111 
3112  static constexpr auto value =
3113  std::is_constructible<RealIntegerType,
3114  CompatibleNumberIntegerType>::value and
3115  CompatibleLimits::is_integer and
3116  RealLimits::is_signed == CompatibleLimits::is_signed;
3117 };
3118 
3119 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
3120 struct is_compatible_integer_type
3121  : is_compatible_integer_type_impl<RealIntegerType,
3122  CompatibleNumberIntegerType> {};
3123 
3124 template <typename BasicJsonType, typename CompatibleType, typename = void>
3125 struct is_compatible_type_impl: std::false_type {};
3126 
3127 template <typename BasicJsonType, typename CompatibleType>
3128 struct is_compatible_type_impl <
3129  BasicJsonType, CompatibleType,
3130  enable_if_t<is_complete_type<CompatibleType>::value >>
3131 {
3132  static constexpr bool value =
3133  has_to_json<BasicJsonType, CompatibleType>::value;
3134 };
3135 
3136 template <typename BasicJsonType, typename CompatibleType>
3137 struct is_compatible_type
3138  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3139 
3140 // https://en.cppreference.com/w/cpp/types/conjunction
3141 template<class...> struct conjunction : std::true_type { };
3142 template<class B1> struct conjunction<B1> : B1 { };
3143 template<class B1, class... Bn>
3144 struct conjunction<B1, Bn...>
3145 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3146 
3147 template <typename T1, typename T2>
3148 struct is_constructible_tuple : std::false_type {};
3149 
3150 template <typename T1, typename... Args>
3151 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3152 } // namespace detail
3153 } // namespace nlohmann
3154 
3155 // #include <nlohmann/detail/value_t.hpp>
3156 
3157 
3158 #include <array> // array
3159 #include <cstddef> // size_t
3160 #include <cstdint> // uint8_t
3161 #include <string> // string
3162 
3163 // #include <nlohmann/detail/boolean_operators.hpp>
3164 
3165 
3166 namespace nlohmann
3167 {
3168 namespace detail
3169 {
3171 // JSON type enumeration //
3173 
3198 enum class value_t : std::uint8_t
3199 {
3200  null,
3201  object,
3202  array,
3203  string,
3204  boolean,
3205  number_integer,
3206  number_unsigned,
3207  number_float,
3208  binary,
3209  discarded
3210 };
3211 
3225 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3226 {
3227  static constexpr std::array<std::uint8_t, 9> order = {{
3228  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3229  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3230  6 /* binary */
3231  }
3232  };
3233 
3234  const auto l_index = static_cast<std::size_t>(lhs);
3235  const auto r_index = static_cast<std::size_t>(rhs);
3236  return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
3237 }
3238 } // namespace detail
3239 } // namespace nlohmann
3240 
3241 
3242 namespace nlohmann
3243 {
3244 namespace detail
3245 {
3246 template<typename BasicJsonType>
3247 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3248 {
3249  if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
3250  {
3251  JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3252  }
3253  n = nullptr;
3254 }
3255 
3256 // overloads for basic_json template parameters
3257 template<typename BasicJsonType, typename ArithmeticType,
3258  enable_if_t<std::is_arithmetic<ArithmeticType>::value and
3259  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3260  int> = 0>
3261 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3262 {
3263  switch (static_cast<value_t>(j))
3264  {
3265  case value_t::number_unsigned:
3266  {
3267  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3268  break;
3269  }
3270  case value_t::number_integer:
3271  {
3272  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3273  break;
3274  }
3275  case value_t::number_float:
3276  {
3277  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3278  break;
3279  }
3280 
3281  default:
3282  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3283  }
3284 }
3285 
3286 template<typename BasicJsonType>
3287 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3288 {
3289  if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
3290  {
3291  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3292  }
3293  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3294 }
3295 
3296 template<typename BasicJsonType>
3297 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3298 {
3299  if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
3300  {
3301  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3302  }
3303  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3304 }
3305 
3306 template <
3307  typename BasicJsonType, typename ConstructibleStringType,
3308  enable_if_t <
3309  is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
3310  not std::is_same<typename BasicJsonType::string_t,
3311  ConstructibleStringType>::value,
3312  int > = 0 >
3313 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3314 {
3315  if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
3316  {
3317  JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3318  }
3319 
3320  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3321 }
3322 
3323 template<typename BasicJsonType>
3324 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3325 {
3326  get_arithmetic_value(j, val);
3327 }
3328 
3329 template<typename BasicJsonType>
3330 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3331 {
3332  get_arithmetic_value(j, val);
3333 }
3334 
3335 template<typename BasicJsonType>
3336 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3337 {
3338  get_arithmetic_value(j, val);
3339 }
3340 
3341 template<typename BasicJsonType, typename EnumType,
3342  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3343 void from_json(const BasicJsonType& j, EnumType& e)
3344 {
3345  typename std::underlying_type<EnumType>::type val;
3346  get_arithmetic_value(j, val);
3347  e = static_cast<EnumType>(val);
3348 }
3349 
3350 // forward_list doesn't have an insert method
3351 template<typename BasicJsonType, typename T, typename Allocator,
3352  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
3353 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3354 {
3355  if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3356  {
3357  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3358  }
3359  l.clear();
3360  std::transform(j.rbegin(), j.rend(),
3361  std::front_inserter(l), [](const BasicJsonType & i)
3362  {
3363  return i.template get<T>();
3364  });
3365 }
3366 
3367 // valarray doesn't have an insert method
3368 template<typename BasicJsonType, typename T,
3369  enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
3370 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3371 {
3372  if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3373  {
3374  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3375  }
3376  l.resize(j.size());
3377  std::copy(j.begin(), j.end(), std::begin(l));
3378 }
3379 
3380 template <typename BasicJsonType, typename T, std::size_t N>
3381 auto from_json(const BasicJsonType& j, T (&arr)[N])
3382 -> decltype(j.template get<T>(), void())
3383 {
3384  for (std::size_t i = 0; i < N; ++i)
3385  {
3386  arr[i] = j.at(i).template get<T>();
3387  }
3388 }
3389 
3390 template<typename BasicJsonType>
3391 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3392 {
3393  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3394 }
3395 
3396 template <typename BasicJsonType, typename T, std::size_t N>
3397 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3398  priority_tag<2> /*unused*/)
3399 -> decltype(j.template get<T>(), void())
3400 {
3401  for (std::size_t i = 0; i < N; ++i)
3402  {
3403  arr[i] = j.at(i).template get<T>();
3404  }
3405 }
3406 
3407 template<typename BasicJsonType, typename ConstructibleArrayType>
3408 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3409 -> decltype(
3410  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3411  j.template get<typename ConstructibleArrayType::value_type>(),
3412  void())
3413 {
3414  using std::end;
3415 
3416  ConstructibleArrayType ret;
3417  ret.reserve(j.size());
3418  std::transform(j.begin(), j.end(),
3419  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3420  {
3421  // get<BasicJsonType>() returns *this, this won't call a from_json
3422  // method when value_type is BasicJsonType
3423  return i.template get<typename ConstructibleArrayType::value_type>();
3424  });
3425  arr = std::move(ret);
3426 }
3427 
3428 template <typename BasicJsonType, typename ConstructibleArrayType>
3429 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3430  priority_tag<0> /*unused*/)
3431 {
3432  using std::end;
3433 
3434  ConstructibleArrayType ret;
3435  std::transform(
3436  j.begin(), j.end(), std::inserter(ret, end(ret)),
3437  [](const BasicJsonType & i)
3438  {
3439  // get<BasicJsonType>() returns *this, this won't call a from_json
3440  // method when value_type is BasicJsonType
3441  return i.template get<typename ConstructibleArrayType::value_type>();
3442  });
3443  arr = std::move(ret);
3444 }
3445 
3446 template <typename BasicJsonType, typename ConstructibleArrayType,
3447  enable_if_t <
3448  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
3449  not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
3450  not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
3451  not std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value and
3452  not is_basic_json<ConstructibleArrayType>::value,
3453  int > = 0 >
3454 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3455 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3456 j.template get<typename ConstructibleArrayType::value_type>(),
3457 void())
3458 {
3459  if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3460  {
3461  JSON_THROW(type_error::create(302, "type must be array, but is " +
3462  std::string(j.type_name())));
3463  }
3464 
3465  from_json_array_impl(j, arr, priority_tag<3> {});
3466 }
3467 
3468 template <typename BasicJsonType>
3469 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3470 {
3471  if (JSON_HEDLEY_UNLIKELY(not j.is_binary()))
3472  {
3473  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3474  }
3475 
3476  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3477 }
3478 
3479 template<typename BasicJsonType, typename ConstructibleObjectType,
3480  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
3481 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3482 {
3483  if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
3484  {
3485  JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3486  }
3487 
3488  ConstructibleObjectType ret;
3489  auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3490  using value_type = typename ConstructibleObjectType::value_type;
3491  std::transform(
3492  inner_object->begin(), inner_object->end(),
3493  std::inserter(ret, ret.begin()),
3494  [](typename BasicJsonType::object_t::value_type const & p)
3495  {
3496  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3497  });
3498  obj = std::move(ret);
3499 }
3500 
3501 // overload for arithmetic types, not chosen for basic_json template arguments
3502 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3503 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3504 // an arithmetic type?
3505 template<typename BasicJsonType, typename ArithmeticType,
3506  enable_if_t <
3507  std::is_arithmetic<ArithmeticType>::value and
3508  not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
3509  not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
3510  not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
3511  not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3512  int> = 0>
3513 void from_json(const BasicJsonType& j, ArithmeticType& val)
3514 {
3515  switch (static_cast<value_t>(j))
3516  {
3517  case value_t::number_unsigned:
3518  {
3519  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3520  break;
3521  }
3522  case value_t::number_integer:
3523  {
3524  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3525  break;
3526  }
3527  case value_t::number_float:
3528  {
3529  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3530  break;
3531  }
3532  case value_t::boolean:
3533  {
3534  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3535  break;
3536  }
3537 
3538  default:
3539  JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3540  }
3541 }
3542 
3543 template<typename BasicJsonType, typename A1, typename A2>
3544 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3545 {
3546  p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3547 }
3548 
3549 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
3550 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3551 {
3552  t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3553 }
3554 
3555 template<typename BasicJsonType, typename... Args>
3556 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3557 {
3558  from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3559 }
3560 
3561 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3562  typename = enable_if_t<not std::is_constructible<
3563  typename BasicJsonType::string_t, Key>::value>>
3564 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3565 {
3566  if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3567  {
3568  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3569  }
3570  m.clear();
3571  for (const auto& p : j)
3572  {
3573  if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3574  {
3575  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3576  }
3577  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3578  }
3579 }
3580 
3581 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3582  typename = enable_if_t<not std::is_constructible<
3583  typename BasicJsonType::string_t, Key>::value>>
3584 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3585 {
3586  if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
3587  {
3588  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3589  }
3590  m.clear();
3591  for (const auto& p : j)
3592  {
3593  if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
3594  {
3595  JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3596  }
3597  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3598  }
3599 }
3600 
3601 struct from_json_fn
3602 {
3603  template<typename BasicJsonType, typename T>
3604  auto operator()(const BasicJsonType& j, T& val) const
3605  noexcept(noexcept(from_json(j, val)))
3606  -> decltype(from_json(j, val), void())
3607  {
3608  return from_json(j, val);
3609  }
3610 };
3611 } // namespace detail
3612 
3616 namespace
3617 {
3618 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3619 } // namespace
3620 } // namespace nlohmann
3621 
3622 // #include <nlohmann/detail/conversions/to_json.hpp>
3623 
3624 
3625 #include <algorithm> // copy
3626 #include <iterator> // begin, end
3627 #include <string> // string
3628 #include <tuple> // tuple, get
3629 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3630 #include <utility> // move, forward, declval, pair
3631 #include <valarray> // valarray
3632 #include <vector> // vector
3633 
3634 // #include <nlohmann/detail/boolean_operators.hpp>
3635 
3636 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3637 
3638 
3639 #include <cstddef> // size_t
3640 #include <iterator> // input_iterator_tag
3641 #include <string> // string, to_string
3642 #include <tuple> // tuple_size, get, tuple_element
3643 
3644 // #include <nlohmann/detail/meta/type_traits.hpp>
3645 
3646 // #include <nlohmann/detail/value_t.hpp>
3647 
3648 
3649 namespace nlohmann
3650 {
3651 namespace detail
3652 {
3653 template<typename string_type>
3654 void int_to_string( string_type& target, std::size_t value )
3655 {
3656  target = std::to_string(value);
3657 }
3658 template <typename IteratorType> class iteration_proxy_value
3659 {
3660  public:
3661  using difference_type = std::ptrdiff_t;
3662  using value_type = iteration_proxy_value;
3663  using pointer = value_type * ;
3664  using reference = value_type & ;
3665  using iterator_category = std::input_iterator_tag;
3666  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3667 
3668  private:
3670  IteratorType anchor;
3672  std::size_t array_index = 0;
3674  mutable std::size_t array_index_last = 0;
3676  mutable string_type array_index_str = "0";
3678  const string_type empty_str = "";
3679 
3680  public:
3681  explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3682 
3684  iteration_proxy_value& operator*()
3685  {
3686  return *this;
3687  }
3688 
3690  iteration_proxy_value& operator++()
3691  {
3692  ++anchor;
3693  ++array_index;
3694 
3695  return *this;
3696  }
3697 
3699  bool operator==(const iteration_proxy_value& o) const
3700  {
3701  return anchor == o.anchor;
3702  }
3703 
3705  bool operator!=(const iteration_proxy_value& o) const
3706  {
3707  return anchor != o.anchor;
3708  }
3709 
3711  const string_type& key() const
3712  {
3713  assert(anchor.m_object != nullptr);
3714 
3715  switch (anchor.m_object->type())
3716  {
3717  // use integer array index as key
3718  case value_t::array:
3719  {
3720  if (array_index != array_index_last)
3721  {
3722  int_to_string( array_index_str, array_index );
3723  array_index_last = array_index;
3724  }
3725  return array_index_str;
3726  }
3727 
3728  // use key from the object
3729  case value_t::object:
3730  return anchor.key();
3731 
3732  // use an empty key for all primitive types
3733  default:
3734  return empty_str;
3735  }
3736  }
3737 
3739  typename IteratorType::reference value() const
3740  {
3741  return anchor.value();
3742  }
3743 };
3744 
3746 template<typename IteratorType> class iteration_proxy
3747 {
3748  private:
3750  typename IteratorType::reference container;
3751 
3752  public:
3754  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3755  : container(cont) {}
3756 
3758  iteration_proxy_value<IteratorType> begin() noexcept
3759  {
3760  return iteration_proxy_value<IteratorType>(container.begin());
3761  }
3762 
3764  iteration_proxy_value<IteratorType> end() noexcept
3765  {
3766  return iteration_proxy_value<IteratorType>(container.end());
3767  }
3768 };
3769 // Structured Bindings Support
3770 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3771 // And see https://github.com/nlohmann/json/pull/1391
3772 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
3773 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3774 {
3775  return i.key();
3776 }
3777 // Structured Bindings Support
3778 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3779 // And see https://github.com/nlohmann/json/pull/1391
3780 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
3781 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3782 {
3783  return i.value();
3784 }
3785 } // namespace detail
3786 } // namespace nlohmann
3787 
3788 // The Addition to the STD Namespace is required to add
3789 // Structured Bindings Support to the iteration_proxy_value class
3790 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3791 // And see https://github.com/nlohmann/json/pull/1391
3792 namespace std
3793 {
3794 #if defined(__clang__)
3795  // Fix: https://github.com/nlohmann/json/issues/1401
3796  #pragma clang diagnostic push
3797  #pragma clang diagnostic ignored "-Wmismatched-tags"
3798 #endif
3799 template <typename IteratorType>
3800 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3801  : public std::integral_constant<std::size_t, 2> {};
3802 
3803 template <std::size_t N, typename IteratorType>
3804 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3805 {
3806  public:
3807  using type = decltype(
3808  get<N>(std::declval <
3809  ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3810 };
3811 #if defined(__clang__)
3812  #pragma clang diagnostic pop
3813 #endif
3814 } // namespace std
3815 
3816 // #include <nlohmann/detail/meta/cpp_future.hpp>
3817 
3818 // #include <nlohmann/detail/meta/type_traits.hpp>
3819 
3820 // #include <nlohmann/detail/value_t.hpp>
3821 
3822 
3823 namespace nlohmann
3824 {
3825 namespace detail
3826 {
3828 // constructors //
3830 
3831 template<value_t> struct external_constructor;
3832 
3833 template<>
3834 struct external_constructor<value_t::boolean>
3835 {
3836  template<typename BasicJsonType>
3837  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
3838  {
3839  j.m_type = value_t::boolean;
3840  j.m_value = b;
3841  j.assert_invariant();
3842  }
3843 };
3844 
3845 template<>
3846 struct external_constructor<value_t::string>
3847 {
3848  template<typename BasicJsonType>
3849  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
3850  {
3851  j.m_type = value_t::string;
3852  j.m_value = s;
3853  j.assert_invariant();
3854  }
3855 
3856  template<typename BasicJsonType>
3857  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
3858  {
3859  j.m_type = value_t::string;
3860  j.m_value = std::move(s);
3861  j.assert_invariant();
3862  }
3863 
3864  template<typename BasicJsonType, typename CompatibleStringType,
3865  enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
3866  int> = 0>
3867  static void construct(BasicJsonType& j, const CompatibleStringType& str)
3868  {
3869  j.m_type = value_t::string;
3870  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
3871  j.assert_invariant();
3872  }
3873 };
3874 
3875 template<>
3876 struct external_constructor<value_t::binary>
3877 {
3878  template<typename BasicJsonType>
3879  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
3880  {
3881  j.m_type = value_t::binary;
3882  typename BasicJsonType::binary_t value{b};
3883  j.m_value = value;
3884  j.assert_invariant();
3885  }
3886 
3887  template<typename BasicJsonType>
3888  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
3889  {
3890  j.m_type = value_t::binary;
3891  typename BasicJsonType::binary_t value{std::move(b)};
3892  j.m_value = value;
3893  j.assert_invariant();
3894  }
3895 };
3896 
3897 template<>
3898 struct external_constructor<value_t::number_float>
3899 {
3900  template<typename BasicJsonType>
3901  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
3902  {
3903  j.m_type = value_t::number_float;
3904  j.m_value = val;
3905  j.assert_invariant();
3906  }
3907 };
3908 
3909 template<>
3910 struct external_constructor<value_t::number_unsigned>
3911 {
3912  template<typename BasicJsonType>
3913  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
3914  {
3915  j.m_type = value_t::number_unsigned;
3916  j.m_value = val;
3917  j.assert_invariant();
3918  }
3919 };
3920 
3921 template<>
3922 struct external_constructor<value_t::number_integer>
3923 {
3924  template<typename BasicJsonType>
3925  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
3926  {
3927  j.m_type = value_t::number_integer;
3928  j.m_value = val;
3929  j.assert_invariant();
3930  }
3931 };
3932 
3933 template<>
3934 struct external_constructor<value_t::array>
3935 {
3936  template<typename BasicJsonType>
3937  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
3938  {
3939  j.m_type = value_t::array;
3940  j.m_value = arr;
3941  j.assert_invariant();
3942  }
3943 
3944  template<typename BasicJsonType>
3945  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
3946  {
3947  j.m_type = value_t::array;
3948  j.m_value = std::move(arr);
3949  j.assert_invariant();
3950  }
3951 
3952  template<typename BasicJsonType, typename CompatibleArrayType,
3953  enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
3954  int> = 0>
3955  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
3956  {
3957  using std::begin;
3958  using std::end;
3959  j.m_type = value_t::array;
3960  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
3961  j.assert_invariant();
3962  }
3963 
3964  template<typename BasicJsonType>
3965  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
3966  {
3967  j.m_type = value_t::array;
3968  j.m_value = value_t::array;
3969  j.m_value.array->reserve(arr.size());
3970  for (const bool x : arr)
3971  {
3972  j.m_value.array->push_back(x);
3973  }
3974  j.assert_invariant();
3975  }
3976 
3977  template<typename BasicJsonType, typename T,
3978  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
3979  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
3980  {
3981  j.m_type = value_t::array;
3982  j.m_value = value_t::array;
3983  j.m_value.array->resize(arr.size());
3984  if (arr.size() > 0)
3985  {
3986  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
3987  }
3988  j.assert_invariant();
3989  }
3990 };
3991 
3992 template<>
3993 struct external_constructor<value_t::object>
3994 {
3995  template<typename BasicJsonType>
3996  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
3997  {
3998  j.m_type = value_t::object;
3999  j.m_value = obj;
4000  j.assert_invariant();
4001  }
4002 
4003  template<typename BasicJsonType>
4004  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4005  {
4006  j.m_type = value_t::object;
4007  j.m_value = std::move(obj);
4008  j.assert_invariant();
4009  }
4010 
4011  template<typename BasicJsonType, typename CompatibleObjectType,
4012  enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
4013  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4014  {
4015  using std::begin;
4016  using std::end;
4017 
4018  j.m_type = value_t::object;
4019  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4020  j.assert_invariant();
4021  }
4022 };
4023 
4025 // to_json //
4027 
4028 template<typename BasicJsonType, typename T,
4029  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4030 void to_json(BasicJsonType& j, T b) noexcept
4031 {
4032  external_constructor<value_t::boolean>::construct(j, b);
4033 }
4034 
4035 template<typename BasicJsonType, typename CompatibleString,
4036  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4037 void to_json(BasicJsonType& j, const CompatibleString& s)
4038 {
4039  external_constructor<value_t::string>::construct(j, s);
4040 }
4041 
4042 template<typename BasicJsonType>
4043 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4044 {
4045  external_constructor<value_t::string>::construct(j, std::move(s));
4046 }
4047 
4048 template<typename BasicJsonType, typename FloatType,
4049  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4050 void to_json(BasicJsonType& j, FloatType val) noexcept
4051 {
4052  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4053 }
4054 
4055 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4056  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4057 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4058 {
4059  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4060 }
4061 
4062 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4063  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4064 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4065 {
4066  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4067 }
4068 
4069 template<typename BasicJsonType, typename EnumType,
4070  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4071 void to_json(BasicJsonType& j, EnumType e) noexcept
4072 {
4073  using underlying_type = typename std::underlying_type<EnumType>::type;
4074  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4075 }
4076 
4077 template<typename BasicJsonType>
4078 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4079 {
4080  external_constructor<value_t::array>::construct(j, e);
4081 }
4082 
4083 template <typename BasicJsonType, typename CompatibleArrayType,
4084  enable_if_t<is_compatible_array_type<BasicJsonType,
4085  CompatibleArrayType>::value and
4086  not is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value and
4087  not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
4088  not std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value and
4089  not is_basic_json<CompatibleArrayType>::value,
4090  int> = 0>
4091 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4092 {
4093  external_constructor<value_t::array>::construct(j, arr);
4094 }
4095 
4096 template <typename BasicJsonType>
4097 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4098 {
4099  external_constructor<value_t::binary>::construct(j, bin);
4100 }
4101 
4102 template<typename BasicJsonType, typename T,
4103  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4104 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4105 {
4106  external_constructor<value_t::array>::construct(j, std::move(arr));
4107 }
4108 
4109 template<typename BasicJsonType>
4110 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4111 {
4112  external_constructor<value_t::array>::construct(j, std::move(arr));
4113 }
4114 
4115 template<typename BasicJsonType, typename CompatibleObjectType,
4116  enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
4117 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4118 {
4119  external_constructor<value_t::object>::construct(j, obj);
4120 }
4121 
4122 template<typename BasicJsonType>
4123 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4124 {
4125  external_constructor<value_t::object>::construct(j, std::move(obj));
4126 }
4127 
4128 template <
4129  typename BasicJsonType, typename T, std::size_t N,
4130  enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
4131  const T(&)[N]>::value,
4132  int> = 0 >
4133 void to_json(BasicJsonType& j, const T(&arr)[N])
4134 {
4135  external_constructor<value_t::array>::construct(j, arr);
4136 }
4137 
4138 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4139 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4140 {
4141  j = { p.first, p.second };
4142 }
4143 
4144 // for https://github.com/nlohmann/json/pull/1134
4145 template < typename BasicJsonType, typename T,
4146  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4147 void to_json(BasicJsonType& j, const T& b)
4148 {
4149  j = { {b.key(), b.value()} };
4150 }
4151 
4152 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4153 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4154 {
4155  j = { std::get<Idx>(t)... };
4156 }
4157 
4158 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4159 void to_json(BasicJsonType& j, const T& t)
4160 {
4161  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4162 }
4163 
4164 struct to_json_fn
4165 {
4166  template<typename BasicJsonType, typename T>
4167  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4168  -> decltype(to_json(j, std::forward<T>(val)), void())
4169  {
4170  return to_json(j, std::forward<T>(val));
4171  }
4172 };
4173 } // namespace detail
4174 
4176 namespace
4177 {
4178 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4179 } // namespace
4180 } // namespace nlohmann
4181 
4182 
4183 namespace nlohmann
4184 {
4185 
4186 template<typename, typename>
4188 {
4198  template<typename BasicJsonType, typename ValueType>
4199  static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4200  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4201  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4202  {
4203  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4204  }
4205 
4215  template <typename BasicJsonType, typename ValueType>
4216  static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4217  noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4218  -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4219  {
4220  ::nlohmann::to_json(j, std::forward<ValueType>(val));
4221  }
4222 };
4223 
4224 } // namespace nlohmann
4225 
4226 // #include <nlohmann/byte_container_with_subtype.hpp>
4227 
4228 
4229 #include <cstdint> // uint8_t
4230 #include <tuple> // tie
4231 #include <utility> // move
4232 
4233 namespace nlohmann
4234 {
4235 
4249 template<typename BinaryType>
4250 class byte_container_with_subtype : public BinaryType
4251 {
4252  public:
4254  using container_type = BinaryType;
4255 
4257  : container_type()
4258  {}
4259 
4261  : container_type(b)
4262  {}
4263 
4264  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4265  : container_type(std::move(b))
4266  {}
4267 
4268  byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4269  : container_type(b)
4270  , m_subtype(subtype)
4271  , m_has_subtype(true)
4272  {}
4273 
4274  byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4275  : container_type(std::move(b))
4276  , m_subtype(subtype)
4277  , m_has_subtype(true)
4278  {}
4279 
4281  {
4282  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4283  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4284  }
4285 
4287  {
4288  return !(rhs == *this);
4289  }
4290 
4309  void set_subtype(std::uint8_t subtype) noexcept
4310  {
4311  m_subtype = subtype;
4312  m_has_subtype = true;
4313  }
4314 
4336  constexpr std::uint8_t subtype() const noexcept
4337  {
4338  return m_subtype;
4339  }
4340 
4357  constexpr bool has_subtype() const noexcept
4358  {
4359  return m_has_subtype;
4360  }
4361 
4381  void clear_subtype() noexcept
4382  {
4383  m_subtype = 0;
4384  m_has_subtype = false;
4385  }
4386 
4387  private:
4388  std::uint8_t m_subtype = 0;
4389  bool m_has_subtype = false;
4390 };
4391 
4392 } // namespace nlohmann
4393 
4394 // #include <nlohmann/detail/boolean_operators.hpp>
4395 
4396 // #include <nlohmann/detail/conversions/from_json.hpp>
4397 
4398 // #include <nlohmann/detail/conversions/to_json.hpp>
4399 
4400 // #include <nlohmann/detail/exceptions.hpp>
4401 
4402 // #include <nlohmann/detail/input/binary_reader.hpp>
4403 
4404 
4405 #include <algorithm> // generate_n
4406 #include <array> // array
4407 #include <cassert> // assert
4408 #include <cmath> // ldexp
4409 #include <cstddef> // size_t
4410 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4411 #include <cstdio> // snprintf
4412 #include <cstring> // memcpy
4413 #include <iterator> // back_inserter
4414 #include <limits> // numeric_limits
4415 #include <string> // char_traits, string
4416 #include <utility> // make_pair, move
4417 
4418 // #include <nlohmann/detail/exceptions.hpp>
4419 
4420 // #include <nlohmann/detail/input/input_adapters.hpp>
4421 
4422 
4423 #include <array> // array
4424 #include <cassert> // assert
4425 #include <cstddef> // size_t
4426 #include <cstdio> //FILE *
4427 #include <cstring> // strlen
4428 #include <istream> // istream
4429 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4430 #include <memory> // shared_ptr, make_shared, addressof
4431 #include <numeric> // accumulate
4432 #include <string> // string, char_traits
4433 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4434 #include <utility> // pair, declval
4435 
4436 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4437 
4438 // #include <nlohmann/detail/macro_scope.hpp>
4439 
4440 
4441 namespace nlohmann
4442 {
4443 namespace detail
4444 {
4446 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4447 
4449 // input adapters //
4451 
4456 class file_input_adapter
4457 {
4458  public:
4459  JSON_HEDLEY_NON_NULL(2)
4460  explicit file_input_adapter(std::FILE* f) noexcept
4461  : m_file(f)
4462  {}
4463 
4464  // make class move-only
4465  file_input_adapter(const file_input_adapter&) = delete;
4466  file_input_adapter(file_input_adapter&&) = default;
4467  file_input_adapter& operator=(const file_input_adapter&) = delete;
4468  file_input_adapter& operator=(file_input_adapter&&) = delete;
4469 
4470  std::char_traits<char>::int_type get_character() noexcept
4471  {
4472  return std::fgetc(m_file);
4473  }
4474 
4475  private:
4477  std::FILE* m_file;
4478 };
4479 
4480 
4490 class input_stream_adapter
4491 {
4492  public:
4493  ~input_stream_adapter()
4494  {
4495  // clear stream flags; we use underlying streambuf I/O, do not
4496  // maintain ifstream flags, except eof
4497  if (is)
4498  {
4499  is->clear(is->rdstate() & std::ios::eofbit);
4500  }
4501  }
4502 
4503  explicit input_stream_adapter(std::istream& i)
4504  : is(&i), sb(i.rdbuf())
4505  {}
4506 
4507  // delete because of pointer members
4508  input_stream_adapter(const input_stream_adapter&) = delete;
4509  input_stream_adapter& operator=(input_stream_adapter&) = delete;
4510  input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4511 
4512  input_stream_adapter(input_stream_adapter&& rhs) : is(rhs.is), sb(rhs.sb)
4513  {
4514  rhs.is = nullptr;
4515  rhs.sb = nullptr;
4516  }
4517 
4518  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4519  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4520  // end up as the same value, eg. 0xFFFFFFFF.
4521  std::char_traits<char>::int_type get_character()
4522  {
4523  auto res = sb->sbumpc();
4524  // set eof manually, as we don't use the istream interface.
4525  if (res == EOF)
4526  {
4527  is->clear(is->rdstate() | std::ios::eofbit);
4528  }
4529  return res;
4530  }
4531 
4532  private:
4534  std::istream* is = nullptr;
4535  std::streambuf* sb = nullptr;
4536 };
4537 
4539 class input_buffer_adapter
4540 {
4541  public:
4542  input_buffer_adapter(const char* b, const std::size_t l) noexcept
4543  : cursor(b), limit(b == nullptr ? nullptr : (b + l))
4544  {}
4545 
4546  // delete because of pointer members
4547  input_buffer_adapter(const input_buffer_adapter&) = delete;
4548  input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
4549  input_buffer_adapter(input_buffer_adapter&&) = default;
4550  input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
4551 
4552  std::char_traits<char>::int_type get_character() noexcept
4553  {
4554  if (JSON_HEDLEY_LIKELY(cursor < limit))
4555  {
4556  assert(cursor != nullptr and limit != nullptr);
4557  return std::char_traits<char>::to_int_type(*(cursor++));
4558  }
4559 
4560  return std::char_traits<char>::eof();
4561  }
4562 
4563  private:
4565  const char* cursor;
4567  const char* const limit;
4568 };
4569 
4570 template<typename WideStringType, size_t T>
4571 struct wide_string_input_helper
4572 {
4573  // UTF-32
4574  static void fill_buffer(const WideStringType& str,
4575  size_t& current_wchar,
4576  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4577  size_t& utf8_bytes_index,
4578  size_t& utf8_bytes_filled)
4579  {
4580  utf8_bytes_index = 0;
4581 
4582  if (current_wchar == str.size())
4583  {
4584  utf8_bytes[0] = std::char_traits<char>::eof();
4585  utf8_bytes_filled = 1;
4586  }
4587  else
4588  {
4589  // get the current character
4590  const auto wc = static_cast<unsigned int>(str[current_wchar++]);
4591 
4592  // UTF-32 to UTF-8 encoding
4593  if (wc < 0x80)
4594  {
4595  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4596  utf8_bytes_filled = 1;
4597  }
4598  else if (wc <= 0x7FF)
4599  {
4600  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
4601  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4602  utf8_bytes_filled = 2;
4603  }
4604  else if (wc <= 0xFFFF)
4605  {
4606  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
4607  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4608  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4609  utf8_bytes_filled = 3;
4610  }
4611  else if (wc <= 0x10FFFF)
4612  {
4613  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
4614  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
4615  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4616  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4617  utf8_bytes_filled = 4;
4618  }
4619  else
4620  {
4621  // unknown character
4622  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4623  utf8_bytes_filled = 1;
4624  }
4625  }
4626  }
4627 };
4628 
4629 template<typename WideStringType>
4630 struct wide_string_input_helper<WideStringType, 2>
4631 {
4632  // UTF-16
4633  static void fill_buffer(const WideStringType& str,
4634  size_t& current_wchar,
4635  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4636  size_t& utf8_bytes_index,
4637  size_t& utf8_bytes_filled)
4638  {
4639  utf8_bytes_index = 0;
4640 
4641  if (current_wchar == str.size())
4642  {
4643  utf8_bytes[0] = std::char_traits<char>::eof();
4644  utf8_bytes_filled = 1;
4645  }
4646  else
4647  {
4648  // get the current character
4649  const auto wc = static_cast<unsigned int>(str[current_wchar++]);
4650 
4651  // UTF-16 to UTF-8 encoding
4652  if (wc < 0x80)
4653  {
4654  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4655  utf8_bytes_filled = 1;
4656  }
4657  else if (wc <= 0x7FF)
4658  {
4659  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
4660  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4661  utf8_bytes_filled = 2;
4662  }
4663  else if (0xD800 > wc or wc >= 0xE000)
4664  {
4665  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
4666  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
4667  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
4668  utf8_bytes_filled = 3;
4669  }
4670  else
4671  {
4672  if (current_wchar < str.size())
4673  {
4674  const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
4675  const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4676  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4677  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4678  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4679  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4680  utf8_bytes_filled = 4;
4681  }
4682  else
4683  {
4684  // unknown character
4685  ++current_wchar;
4686  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4687  utf8_bytes_filled = 1;
4688  }
4689  }
4690  }
4691  }
4692 };
4693 
4694 template<typename WideStringType>
4695 class wide_string_input_adapter
4696 {
4697  public:
4698  explicit wide_string_input_adapter(const WideStringType& w) noexcept
4699  : str(w)
4700  {}
4701 
4702  std::char_traits<char>::int_type get_character() noexcept
4703  {
4704  // check if buffer needs to be filled
4705  if (utf8_bytes_index == utf8_bytes_filled)
4706  {
4707  fill_buffer<sizeof(typename WideStringType::value_type)>();
4708 
4709  assert(utf8_bytes_filled > 0);
4710  assert(utf8_bytes_index == 0);
4711  }
4712 
4713  // use buffer
4714  assert(utf8_bytes_filled > 0);
4715  assert(utf8_bytes_index < utf8_bytes_filled);
4716  return utf8_bytes[utf8_bytes_index++];
4717  }
4718 
4719  private:
4720  template<size_t T>
4721  void fill_buffer()
4722  {
4723  wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
4724  }
4725 
4727  const WideStringType& str;
4728 
4730  std::size_t current_wchar = 0;
4731 
4733  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
4734 
4736  std::size_t utf8_bytes_index = 0;
4738  std::size_t utf8_bytes_filled = 0;
4739 };
4740 
4741 inline file_input_adapter input_adapter(std::FILE* file)
4742 {
4743  return file_input_adapter(file);
4744 }
4745 
4746 inline input_stream_adapter input_adapter(std::istream& stream)
4747 {
4748  return input_stream_adapter(stream);
4749 }
4750 
4751 inline input_stream_adapter input_adapter(std::istream&& stream)
4752 {
4753  return input_stream_adapter(stream);
4754 }
4755 
4756 template<typename CharT,
4757  typename std::enable_if<
4758  std::is_pointer<CharT>::value and
4759  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4760  sizeof(typename std::remove_pointer<CharT>::type) == 1,
4761  int>::type = 0>
4762 input_buffer_adapter input_adapter(CharT b, std::size_t l)
4763 {
4764  return input_buffer_adapter(reinterpret_cast<const char*>(b), l);
4765 }
4766 
4767 template<typename CharT,
4768  typename std::enable_if<
4769  std::is_pointer<CharT>::value and
4770  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4771  sizeof(typename std::remove_pointer<CharT>::type) == 1,
4772  int>::type = 0>
4773 input_buffer_adapter input_adapter(CharT b)
4774 {
4775  return input_adapter(reinterpret_cast<const char*>(b),
4776  std::strlen(reinterpret_cast<const char*>(b)));
4777 }
4778 
4779 template<class IteratorType,
4780  typename std::enable_if<
4781  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4782  int>::type = 0>
4783 input_buffer_adapter input_adapter(IteratorType first, IteratorType last)
4784 {
4785 #ifndef NDEBUG
4786  // assertion to check that the iterator range is indeed contiguous,
4787  // see https://stackoverflow.com/a/35008842/266378 for more discussion
4788  const auto is_contiguous = std::accumulate(
4789  first, last, std::pair<bool, int>(true, 0),
4790  [&first](std::pair<bool, int> res, decltype(*first) val)
4791  {
4792  res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
4793  return res;
4794  }).first;
4795  assert(is_contiguous);
4796 #endif
4797 
4798  // assertion to check that each element is 1 byte long
4799  static_assert(
4800  sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
4801  "each element in the iterator range must have the size of 1 byte");
4802 
4803  const auto len = static_cast<size_t>(std::distance(first, last));
4804  if (JSON_HEDLEY_LIKELY(len > 0))
4805  {
4806  // there is at least one element: use the address of first
4807  return input_buffer_adapter(reinterpret_cast<const char*>(&(*first)), len);
4808  }
4809  else
4810  {
4811  // the address of first cannot be used: use nullptr
4812  return input_buffer_adapter(nullptr, len);
4813  }
4814 }
4815 
4816 inline wide_string_input_adapter<std::wstring> input_adapter(const std::wstring& ws)
4817 {
4818  return wide_string_input_adapter<std::wstring>(ws);
4819 }
4820 
4821 
4822 inline wide_string_input_adapter<std::u16string> input_adapter(const std::u16string& ws)
4823 {
4824  return wide_string_input_adapter<std::u16string>(ws);
4825 }
4826 
4827 inline wide_string_input_adapter<std::u32string> input_adapter(const std::u32string& ws)
4828 {
4829  return wide_string_input_adapter<std::u32string>(ws);
4830 }
4831 
4832 template<class ContiguousContainer, typename
4833  std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4834  std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4835  int>::type = 0>
4836 input_buffer_adapter input_adapter(const ContiguousContainer& c)
4837 {
4838  return input_adapter(std::begin(c), std::end(c));
4839 }
4840 
4841 
4842 template<class T, std::size_t N>
4843 input_buffer_adapter input_adapter(T (&array)[N])
4844 {
4845  return input_adapter(std::begin(array), std::end(array));
4846 }
4847 
4848 // This class only handles inputs of input_buffer_adapter type.
4849 // It's required so that expressions like {ptr, len} can be implicitely casted
4850 // to the correct adapter.
4851 class span_input_adapter
4852 {
4853  public:
4854  template<typename CharT,
4855  typename std::enable_if<
4856  std::is_pointer<CharT>::value and
4857  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4858  sizeof(typename std::remove_pointer<CharT>::type) == 1,
4859  int>::type = 0>
4860  span_input_adapter(CharT b, std::size_t l)
4861  : ia(reinterpret_cast<const char*>(b), l) {}
4862 
4863  template<typename CharT,
4864  typename std::enable_if<
4865  std::is_pointer<CharT>::value and
4866  std::is_integral<typename std::remove_pointer<CharT>::type>::value and
4867  sizeof(typename std::remove_pointer<CharT>::type) == 1,
4868  int>::type = 0>
4869  span_input_adapter(CharT b)
4870  : span_input_adapter(reinterpret_cast<const char*>(b),
4871  std::strlen(reinterpret_cast<const char*>(b))) {}
4872 
4873  template<class IteratorType,
4874  typename std::enable_if<
4875  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
4876  int>::type = 0>
4877  span_input_adapter(IteratorType first, IteratorType last)
4878  : ia(input_adapter(first, last)) {}
4879 
4880  template<class T, std::size_t N>
4881  span_input_adapter(T (&array)[N])
4882  : span_input_adapter(std::begin(array), std::end(array)) {}
4883 
4885  template<class ContiguousContainer, typename
4886  std::enable_if<not std::is_pointer<ContiguousContainer>::value and
4887  std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
4888  int>::type = 0>
4889  span_input_adapter(const ContiguousContainer& c)
4890  : span_input_adapter(std::begin(c), std::end(c)) {}
4891 
4892  input_buffer_adapter&& get()
4893  {
4894  return std::move(ia);
4895  }
4896 
4897  private:
4898  input_buffer_adapter ia;
4899 };
4900 } // namespace detail
4901 } // namespace nlohmann
4902 
4903 // #include <nlohmann/detail/input/json_sax.hpp>
4904 
4905 
4906 #include <cassert> // assert
4907 #include <cstddef>
4908 #include <string> // string
4909 #include <utility> // move
4910 #include <vector> // vector
4911 
4912 // #include <nlohmann/detail/exceptions.hpp>
4913 
4914 // #include <nlohmann/detail/macro_scope.hpp>
4915 
4916 
4917 namespace nlohmann
4918 {
4919 
4928 template<typename BasicJsonType>
4929 struct json_sax
4930 {
4931  using number_integer_t = typename BasicJsonType::number_integer_t;
4932  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4933  using number_float_t = typename BasicJsonType::number_float_t;
4934  using string_t = typename BasicJsonType::string_t;
4935  using binary_t = typename BasicJsonType::binary_t;
4936 
4941  virtual bool null() = 0;
4942 
4948  virtual bool boolean(bool val) = 0;
4949 
4955  virtual bool number_integer(number_integer_t val) = 0;
4956 
4962  virtual bool number_unsigned(number_unsigned_t val) = 0;
4963 
4970  virtual bool number_float(number_float_t val, const string_t& s) = 0;
4971 
4978  virtual bool string(string_t& val) = 0;
4979 
4986  virtual bool binary(binary_t& val) = 0;
4987 
4994  virtual bool start_object(std::size_t elements) = 0;
4995 
5002  virtual bool key(string_t& val) = 0;
5003 
5008  virtual bool end_object() = 0;
5009 
5016  virtual bool start_array(std::size_t elements) = 0;
5017 
5022  virtual bool end_array() = 0;
5023 
5031  virtual bool parse_error(std::size_t position,
5032  const std::string& last_token,
5033  const detail::exception& ex) = 0;
5034 
5035  virtual ~json_sax() = default;
5036 };
5037 
5038 
5039 namespace detail
5040 {
5054 template<typename BasicJsonType>
5055 class json_sax_dom_parser
5056 {
5057  public:
5058  using number_integer_t = typename BasicJsonType::number_integer_t;
5059  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5060  using number_float_t = typename BasicJsonType::number_float_t;
5061  using string_t = typename BasicJsonType::string_t;
5062  using binary_t = typename BasicJsonType::binary_t;
5063 
5069  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5070  : root(r), allow_exceptions(allow_exceptions_)
5071  {}
5072 
5073  // make class move-only
5074  json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5075  json_sax_dom_parser(json_sax_dom_parser&&) = default;
5076  json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5077  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5078  ~json_sax_dom_parser() = default;
5079 
5080  bool null()
5081  {
5082  handle_value(nullptr);
5083  return true;
5084  }
5085 
5086  bool boolean(bool val)
5087  {
5088  handle_value(val);
5089  return true;
5090  }
5091 
5092  bool number_integer(number_integer_t val)
5093  {
5094  handle_value(val);
5095  return true;
5096  }
5097 
5098  bool number_unsigned(number_unsigned_t val)
5099  {
5100  handle_value(val);
5101  return true;
5102  }
5103 
5104  bool number_float(number_float_t val, const string_t& /*unused*/)
5105  {
5106  handle_value(val);
5107  return true;
5108  }
5109 
5110  bool string(string_t& val)
5111  {
5112  handle_value(val);
5113  return true;
5114  }
5115 
5116  bool binary(binary_t& val)
5117  {
5118  handle_value(std::move(val));
5119  return true;
5120  }
5121 
5122  bool start_object(std::size_t len)
5123  {
5124  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5125 
5126  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5127  {
5128  JSON_THROW(out_of_range::create(408,
5129  "excessive object size: " + std::to_string(len)));
5130  }
5131 
5132  return true;
5133  }
5134 
5135  bool key(string_t& val)
5136  {
5137  // add null at given key and store the reference for later
5138  object_element = &(ref_stack.back()->m_value.object->operator[](val));
5139  return true;
5140  }
5141 
5142  bool end_object()
5143  {
5144  ref_stack.pop_back();
5145  return true;
5146  }
5147 
5148  bool start_array(std::size_t len)
5149  {
5150  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5151 
5152  if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5153  {
5154  JSON_THROW(out_of_range::create(408,
5155  "excessive array size: " + std::to_string(len)));
5156  }
5157 
5158  return true;
5159  }
5160 
5161  bool end_array()
5162  {
5163  ref_stack.pop_back();
5164  return true;
5165  }
5166 
5167  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5168  const detail::exception& ex)
5169  {
5170  errored = true;
5171  if (allow_exceptions)
5172  {
5173  // determine the proper exception type from the id
5174  switch ((ex.id / 100) % 100)
5175  {
5176  case 1:
5177  JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
5178  case 4:
5179  JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
5180  // LCOV_EXCL_START
5181  case 2:
5182  JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
5183  case 3:
5184  JSON_THROW(*static_cast<const detail::type_error*>(&ex));
5185  case 5:
5186  JSON_THROW(*static_cast<const detail::other_error*>(&ex));
5187  default:
5188  assert(false);
5189  // LCOV_EXCL_STOP
5190  }
5191  }
5192  return false;
5193  }
5194 
5195  constexpr bool is_errored() const
5196  {
5197  return errored;
5198  }
5199 
5200  private:
5207  template<typename Value>
5208 
5209  BasicJsonType* handle_value(Value&& v)
5210  {
5211  if (ref_stack.empty())
5212  {
5213  root = BasicJsonType(std::forward<Value>(v));
5214  return &root;
5215  }
5216 
5217  assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5218 
5219  if (ref_stack.back()->is_array())
5220  {
5221  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5222  return &(ref_stack.back()->m_value.array->back());
5223  }
5224 
5225  assert(ref_stack.back()->is_object());
5226  assert(object_element);
5227  *object_element = BasicJsonType(std::forward<Value>(v));
5228  return object_element;
5229  }
5230 
5232  BasicJsonType& root;
5234  std::vector<BasicJsonType*> ref_stack {};
5236  BasicJsonType* object_element = nullptr;
5238  bool errored = false;
5240  const bool allow_exceptions = true;
5241 };
5242 
5243 template<typename BasicJsonType>
5244 class json_sax_dom_callback_parser
5245 {
5246  public:
5247  using number_integer_t = typename BasicJsonType::number_integer_t;
5248  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5249  using number_float_t = typename BasicJsonType::number_float_t;
5250  using string_t = typename BasicJsonType::string_t;
5251  using binary_t = typename BasicJsonType::binary_t;
5252  using parser_callback_t = typename BasicJsonType::parser_callback_t;
5253  using parse_event_t = typename BasicJsonType::parse_event_t;
5254 
5255  json_sax_dom_callback_parser(BasicJsonType& r,
5256  const parser_callback_t cb,
5257  const bool allow_exceptions_ = true)
5258  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5259  {
5260  keep_stack.push_back(true);
5261  }
5262 
5263  // make class move-only
5264  json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5265  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5266  json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5267  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5268  ~json_sax_dom_callback_parser() = default;
5269 
5270  bool null()
5271  {
5272  handle_value(nullptr);
5273  return true;
5274  }
5275 
5276  bool boolean(bool val)
5277  {
5278  handle_value(val);
5279  return true;
5280  }
5281 
5282  bool number_integer(number_integer_t val)
5283  {
5284  handle_value(val);
5285  return true;
5286  }
5287 
5288  bool number_unsigned(number_unsigned_t val)
5289  {
5290  handle_value(val);
5291  return true;
5292  }
5293 
5294  bool number_float(number_float_t val, const string_t& /*unused*/)
5295  {
5296  handle_value(val);
5297  return true;
5298  }
5299 
5300  bool string(string_t& val)
5301  {
5302  handle_value(val);
5303  return true;
5304  }
5305 
5306  bool binary(binary_t& val)
5307  {
5308  handle_value(std::move(val));
5309  return true;
5310  }
5311 
5312  bool start_object(std::size_t len)
5313  {
5314  // check callback for object start
5315  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5316  keep_stack.push_back(keep);
5317 
5318  auto val = handle_value(BasicJsonType::value_t::object, true);
5319  ref_stack.push_back(val.second);
5320 
5321  // check object limit
5322  if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5323  {
5324  JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5325  }
5326 
5327  return true;
5328  }
5329 
5330  bool key(string_t& val)
5331  {
5332  BasicJsonType k = BasicJsonType(val);
5333 
5334  // check callback for key
5335  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5336  key_keep_stack.push_back(keep);
5337 
5338  // add discarded value at given key and store the reference for later
5339  if (keep and ref_stack.back())
5340  {
5341  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5342  }
5343 
5344  return true;
5345  }
5346 
5347  bool end_object()
5348  {
5349  if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5350  {
5351  // discard object
5352  *ref_stack.back() = discarded;
5353  }
5354 
5355  assert(not ref_stack.empty());
5356  assert(not keep_stack.empty());
5357  ref_stack.pop_back();
5358  keep_stack.pop_back();
5359 
5360  if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
5361  {
5362  // remove discarded value
5363  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5364  {
5365  if (it->is_discarded())
5366  {
5367  ref_stack.back()->erase(it);
5368  break;
5369  }
5370  }
5371  }
5372 
5373  return true;
5374  }
5375 
5376  bool start_array(std::size_t len)
5377  {
5378  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5379  keep_stack.push_back(keep);
5380 
5381  auto val = handle_value(BasicJsonType::value_t::array, true);
5382  ref_stack.push_back(val.second);
5383 
5384  // check array limit
5385  if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
5386  {
5387  JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5388  }
5389 
5390  return true;
5391  }
5392 
5393  bool end_array()
5394  {
5395  bool keep = true;
5396 
5397  if (ref_stack.back())
5398  {
5399  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5400  if (not keep)
5401  {
5402  // discard array
5403  *ref_stack.back() = discarded;
5404  }
5405  }
5406 
5407  assert(not ref_stack.empty());
5408  assert(not keep_stack.empty());
5409  ref_stack.pop_back();
5410  keep_stack.pop_back();
5411 
5412  // remove discarded value
5413  if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
5414  {
5415  ref_stack.back()->m_value.array->pop_back();
5416  }
5417 
5418  return true;
5419  }
5420 
5421  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5422  const detail::exception& ex)
5423  {
5424  errored = true;
5425  if (allow_exceptions)
5426  {
5427  // determine the proper exception type from the id
5428  switch ((ex.id / 100) % 100)
5429  {
5430  case 1:
5431  JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
5432  case 4:
5433  JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
5434  // LCOV_EXCL_START
5435  case 2:
5436  JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
5437  case 3:
5438  JSON_THROW(*static_cast<const detail::type_error*>(&ex));
5439  case 5:
5440  JSON_THROW(*static_cast<const detail::other_error*>(&ex));
5441  default:
5442  assert(false);
5443  // LCOV_EXCL_STOP
5444  }
5445  }
5446  return false;
5447  }
5448 
5449  constexpr bool is_errored() const
5450  {
5451  return errored;
5452  }
5453 
5454  private:
5470  template<typename Value>
5471  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5472  {
5473  assert(not keep_stack.empty());
5474 
5475  // do not handle this value if we know it would be added to a discarded
5476  // container
5477  if (not keep_stack.back())
5478  {
5479  return {false, nullptr};
5480  }
5481 
5482  // create value
5483  auto value = BasicJsonType(std::forward<Value>(v));
5484 
5485  // check callback
5486  const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5487 
5488  // do not handle this value if we just learnt it shall be discarded
5489  if (not keep)
5490  {
5491  return {false, nullptr};
5492  }
5493 
5494  if (ref_stack.empty())
5495  {
5496  root = std::move(value);
5497  return {true, &root};
5498  }
5499 
5500  // skip this value if we already decided to skip the parent
5501  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5502  if (not ref_stack.back())
5503  {
5504  return {false, nullptr};
5505  }
5506 
5507  // we now only expect arrays and objects
5508  assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
5509 
5510  // array
5511  if (ref_stack.back()->is_array())
5512  {
5513  ref_stack.back()->m_value.array->push_back(std::move(value));
5514  return {true, &(ref_stack.back()->m_value.array->back())};
5515  }
5516 
5517  // object
5518  assert(ref_stack.back()->is_object());
5519  // check if we should store an element for the current key
5520  assert(not key_keep_stack.empty());
5521  const bool store_element = key_keep_stack.back();
5522  key_keep_stack.pop_back();
5523 
5524  if (not store_element)
5525  {
5526  return {false, nullptr};
5527  }
5528 
5529  assert(object_element);
5530  *object_element = std::move(value);
5531  return {true, object_element};
5532  }
5533 
5535  BasicJsonType& root;
5537  std::vector<BasicJsonType*> ref_stack {};
5539  std::vector<bool> keep_stack {};
5541  std::vector<bool> key_keep_stack {};
5543  BasicJsonType* object_element = nullptr;
5545  bool errored = false;
5547  const parser_callback_t callback = nullptr;
5549  const bool allow_exceptions = true;
5551  BasicJsonType discarded = BasicJsonType::value_t::discarded;
5552 };
5553 
5554 template<typename BasicJsonType>
5555 class json_sax_acceptor
5556 {
5557  public:
5558  using number_integer_t = typename BasicJsonType::number_integer_t;
5559  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5560  using number_float_t = typename BasicJsonType::number_float_t;
5561  using string_t = typename BasicJsonType::string_t;
5562  using binary_t = typename BasicJsonType::binary_t;
5563 
5564  bool null()
5565  {
5566  return true;
5567  }
5568 
5569  bool boolean(bool /*unused*/)
5570  {
5571  return true;
5572  }
5573 
5574  bool number_integer(number_integer_t /*unused*/)
5575  {
5576  return true;
5577  }
5578 
5579  bool number_unsigned(number_unsigned_t /*unused*/)
5580  {
5581  return true;
5582  }
5583 
5584  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5585  {
5586  return true;
5587  }
5588 
5589  bool string(string_t& /*unused*/)
5590  {
5591  return true;
5592  }
5593 
5594  bool binary(binary_t& /*unused*/)
5595  {
5596  return true;
5597  }
5598 
5599  bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5600  {
5601  return true;
5602  }
5603 
5604  bool key(string_t& /*unused*/)
5605  {
5606  return true;
5607  }
5608 
5609  bool end_object()
5610  {
5611  return true;
5612  }
5613 
5614  bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5615  {
5616  return true;
5617  }
5618 
5619  bool end_array()
5620  {
5621  return true;
5622  }
5623 
5624  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5625  {
5626  return false;
5627  }
5628 };
5629 } // namespace detail
5630 
5631 } // namespace nlohmann
5632 
5633 // #include <nlohmann/detail/macro_scope.hpp>
5634 
5635 // #include <nlohmann/detail/meta/is_sax.hpp>
5636 
5637 
5638 #include <cstdint> // size_t
5639 #include <utility> // declval
5640 #include <string> // string
5641 
5642 // #include <nlohmann/detail/meta/detected.hpp>
5643 
5644 // #include <nlohmann/detail/meta/type_traits.hpp>
5645 
5646 
5647 namespace nlohmann
5648 {
5649 namespace detail
5650 {
5651 template <typename T>
5652 using null_function_t = decltype(std::declval<T&>().null());
5653 
5654 template <typename T>
5655 using boolean_function_t =
5656  decltype(std::declval<T&>().boolean(std::declval<bool>()));
5657 
5658 template <typename T, typename Integer>
5659 using number_integer_function_t =
5660  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
5661 
5662 template <typename T, typename Unsigned>
5663 using number_unsigned_function_t =
5664  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
5665 
5666 template <typename T, typename Float, typename String>
5667 using number_float_function_t = decltype(std::declval<T&>().number_float(
5668  std::declval<Float>(), std::declval<const String&>()));
5669 
5670 template <typename T, typename String>
5671 using string_function_t =
5672  decltype(std::declval<T&>().string(std::declval<String&>()));
5673 
5674 template <typename T>
5675 using start_object_function_t =
5676  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
5677 
5678 template <typename T, typename String>
5679 using key_function_t =
5680  decltype(std::declval<T&>().key(std::declval<String&>()));
5681 
5682 template <typename T>
5683 using end_object_function_t = decltype(std::declval<T&>().end_object());
5684 
5685 template <typename T>
5686 using start_array_function_t =
5687  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
5688 
5689 template <typename T>
5690 using end_array_function_t = decltype(std::declval<T&>().end_array());
5691 
5692 template <typename T, typename Exception>
5693 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
5694  std::declval<std::size_t>(), std::declval<const std::string&>(),
5695  std::declval<const Exception&>()));
5696 
5697 template <typename SAX, typename BasicJsonType>
5698 struct is_sax
5699 {
5700  private:
5701  static_assert(is_basic_json<BasicJsonType>::value,
5702  "BasicJsonType must be of type basic_json<...>");
5703 
5704  using number_integer_t = typename BasicJsonType::number_integer_t;
5705  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5706  using number_float_t = typename BasicJsonType::number_float_t;
5707  using string_t = typename BasicJsonType::string_t;
5708  using exception_t = typename BasicJsonType::exception;
5709 
5710  public:
5711  static constexpr bool value =
5712  is_detected_exact<bool, null_function_t, SAX>::value &&
5713  is_detected_exact<bool, boolean_function_t, SAX>::value &&
5714  is_detected_exact<bool, number_integer_function_t, SAX,
5715  number_integer_t>::value &&
5716  is_detected_exact<bool, number_unsigned_function_t, SAX,
5717  number_unsigned_t>::value &&
5718  is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
5719  string_t>::value &&
5720  is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
5721  is_detected_exact<bool, start_object_function_t, SAX>::value &&
5722  is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
5723  is_detected_exact<bool, end_object_function_t, SAX>::value &&
5724  is_detected_exact<bool, start_array_function_t, SAX>::value &&
5725  is_detected_exact<bool, end_array_function_t, SAX>::value &&
5726  is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
5727 };
5728 
5729 template <typename SAX, typename BasicJsonType>
5730 struct is_sax_static_asserts
5731 {
5732  private:
5733  static_assert(is_basic_json<BasicJsonType>::value,
5734  "BasicJsonType must be of type basic_json<...>");
5735 
5736  using number_integer_t = typename BasicJsonType::number_integer_t;
5737  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5738  using number_float_t = typename BasicJsonType::number_float_t;
5739  using string_t = typename BasicJsonType::string_t;
5740  using exception_t = typename BasicJsonType::exception;
5741 
5742  public:
5743  static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
5744  "Missing/invalid function: bool null()");
5745  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5746  "Missing/invalid function: bool boolean(bool)");
5747  static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
5748  "Missing/invalid function: bool boolean(bool)");
5749  static_assert(
5750  is_detected_exact<bool, number_integer_function_t, SAX,
5751  number_integer_t>::value,
5752  "Missing/invalid function: bool number_integer(number_integer_t)");
5753  static_assert(
5754  is_detected_exact<bool, number_unsigned_function_t, SAX,
5755  number_unsigned_t>::value,
5756  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
5757  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
5758  number_float_t, string_t>::value,
5759  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
5760  static_assert(
5761  is_detected_exact<bool, string_function_t, SAX, string_t>::value,
5762  "Missing/invalid function: bool string(string_t&)");
5763  static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
5764  "Missing/invalid function: bool start_object(std::size_t)");
5765  static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
5766  "Missing/invalid function: bool key(string_t&)");
5767  static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
5768  "Missing/invalid function: bool end_object()");
5769  static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
5770  "Missing/invalid function: bool start_array(std::size_t)");
5771  static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
5772  "Missing/invalid function: bool end_array()");
5773  static_assert(
5774  is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
5775  "Missing/invalid function: bool parse_error(std::size_t, const "
5776  "std::string&, const exception&)");
5777 };
5778 } // namespace detail
5779 } // namespace nlohmann
5780 
5781 // #include <nlohmann/detail/value_t.hpp>
5782 
5783 
5784 namespace nlohmann
5785 {
5786 namespace detail
5787 {
5788 
5796 static inline bool little_endianess(int num = 1) noexcept
5797 {
5798  return *reinterpret_cast<char*>(&num) == 1;
5799 }
5800 
5801 
5803 // binary reader //
5805 
5809 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
5810 class binary_reader
5811 {
5812  using number_integer_t = typename BasicJsonType::number_integer_t;
5813  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5814  using number_float_t = typename BasicJsonType::number_float_t;
5815  using string_t = typename BasicJsonType::string_t;
5816  using binary_t = typename BasicJsonType::binary_t;
5817  using json_sax_t = SAX;
5818 
5819  public:
5825  explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
5826  {
5827  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
5828  }
5829 
5830  // make class move-only
5831  binary_reader(const binary_reader&) = delete;
5832  binary_reader(binary_reader&&) = default;
5833  binary_reader& operator=(const binary_reader&) = delete;
5834  binary_reader& operator=(binary_reader&&) = default;
5835  ~binary_reader() = default;
5836 
5844  JSON_HEDLEY_NON_NULL(3)
5845  bool sax_parse(const input_format_t format,
5846  json_sax_t* sax_,
5847  const bool strict = true)
5848  {
5849  sax = sax_;
5850  bool result = false;
5851 
5852  switch (format)
5853  {
5854  case input_format_t::bson:
5855  result = parse_bson_internal();
5856  break;
5857 
5858  case input_format_t::cbor:
5859  result = parse_cbor_internal();
5860  break;
5861 
5862  case input_format_t::msgpack:
5863  result = parse_msgpack_internal();
5864  break;
5865 
5866  case input_format_t::ubjson:
5867  result = parse_ubjson_internal();
5868  break;
5869 
5870  default: // LCOV_EXCL_LINE
5871  assert(false); // LCOV_EXCL_LINE
5872  }
5873 
5874  // strict mode: next byte must be EOF
5875  if (result and strict)
5876  {
5877  if (format == input_format_t::ubjson)
5878  {
5879  get_ignore_noop();
5880  }
5881  else
5882  {
5883  get();
5884  }
5885 
5886  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char>::eof()))
5887  {
5888  return sax->parse_error(chars_read, get_token_string(),
5889  parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
5890  }
5891  }
5892 
5893  return result;
5894  }
5895 
5896  private:
5898  // BSON //
5900 
5905  bool parse_bson_internal()
5906  {
5907  std::int32_t document_size;
5908  get_number<std::int32_t, true>(input_format_t::bson, document_size);
5909 
5910  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
5911  {
5912  return false;
5913  }
5914 
5915  if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
5916  {
5917  return false;
5918  }
5919 
5920  return sax->end_object();
5921  }
5922 
5930  bool get_bson_cstr(string_t& result)
5931  {
5932  auto out = std::back_inserter(result);
5933  while (true)
5934  {
5935  get();
5936  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
5937  {
5938  return false;
5939  }
5940  if (current == 0x00)
5941  {
5942  return true;
5943  }
5944  *out++ = static_cast<char>(current);
5945  }
5946 
5947  return true;
5948  }
5949 
5961  template<typename NumberType>
5962  bool get_bson_string(const NumberType len, string_t& result)
5963  {
5964  if (JSON_HEDLEY_UNLIKELY(len < 1))
5965  {
5966  auto last_token = get_token_string();
5967  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")));
5968  }
5969 
5970  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
5971  }
5972 
5982  template<typename NumberType>
5983  bool get_bson_binary(const NumberType len, binary_t& result)
5984  {
5985  if (JSON_HEDLEY_UNLIKELY(len < 0))
5986  {
5987  auto last_token = get_token_string();
5988  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")));
5989  }
5990 
5991  // All BSON binary values have a subtype
5992  std::uint8_t subtype;
5993  get_number<std::uint8_t>(input_format_t::bson, subtype);
5994  result.set_subtype(subtype);
5995 
5996  return get_binary(input_format_t::bson, len, result);
5997  }
5998 
6009  bool parse_bson_element_internal(const int element_type,
6010  const std::size_t element_type_parse_position)
6011  {
6012  switch (element_type)
6013  {
6014  case 0x01: // double
6015  {
6016  double number;
6017  return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
6018  }
6019 
6020  case 0x02: // string
6021  {
6022  std::int32_t len;
6023  string_t value;
6024  return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
6025  }
6026 
6027  case 0x03: // object
6028  {
6029  return parse_bson_internal();
6030  }
6031 
6032  case 0x04: // array
6033  {
6034  return parse_bson_array();
6035  }
6036 
6037  case 0x05: // binary
6038  {
6039  std::int32_t len;
6040  binary_t value;
6041  return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_binary(len, value) and sax->binary(value);
6042  }
6043 
6044  case 0x08: // boolean
6045  {
6046  return sax->boolean(get() != 0);
6047  }
6048 
6049  case 0x0A: // null
6050  {
6051  return sax->null();
6052  }
6053 
6054  case 0x10: // int32
6055  {
6056  std::int32_t value;
6057  return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6058  }
6059 
6060  case 0x12: // int64
6061  {
6062  std::int64_t value;
6063  return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
6064  }
6065 
6066  default: // anything else not supported (yet)
6067  {
6068  std::array<char, 3> cr{{}};
6069  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
6070  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())));
6071  }
6072  }
6073  }
6074 
6087  bool parse_bson_element_list(const bool is_array)
6088  {
6089  string_t key;
6090 
6091  while (int element_type = get())
6092  {
6093  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
6094  {
6095  return false;
6096  }
6097 
6098  const std::size_t element_type_parse_position = chars_read;
6099  if (JSON_HEDLEY_UNLIKELY(not get_bson_cstr(key)))
6100  {
6101  return false;
6102  }
6103 
6104  if (not is_array and not sax->key(key))
6105  {
6106  return false;
6107  }
6108 
6109  if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
6110  {
6111  return false;
6112  }
6113 
6114  // get_bson_cstr only appends
6115  key.clear();
6116  }
6117 
6118  return true;
6119  }
6120 
6125  bool parse_bson_array()
6126  {
6127  std::int32_t document_size;
6128  get_number<std::int32_t, true>(input_format_t::bson, document_size);
6129 
6130  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
6131  {
6132  return false;
6133  }
6134 
6135  if (JSON_HEDLEY_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
6136  {
6137  return false;
6138  }
6139 
6140  return sax->end_array();
6141  }
6142 
6144  // CBOR //
6146 
6154  bool parse_cbor_internal(const bool get_char = true)
6155  {
6156  switch (get_char ? get() : current)
6157  {
6158  // EOF
6159  case std::char_traits<char>::eof():
6160  return unexpect_eof(input_format_t::cbor, "value");
6161 
6162  // Integer 0x00..0x17 (0..23)
6163  case 0x00:
6164  case 0x01:
6165  case 0x02:
6166  case 0x03:
6167  case 0x04:
6168  case 0x05:
6169  case 0x06:
6170  case 0x07:
6171  case 0x08:
6172  case 0x09:
6173  case 0x0A:
6174  case 0x0B:
6175  case 0x0C:
6176  case 0x0D:
6177  case 0x0E:
6178  case 0x0F:
6179  case 0x10:
6180  case 0x11:
6181  case 0x12:
6182  case 0x13:
6183  case 0x14:
6184  case 0x15:
6185  case 0x16:
6186  case 0x17:
6187  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6188 
6189  case 0x18: // Unsigned integer (one-byte uint8_t follows)
6190  {
6191  std::uint8_t number;
6192  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6193  }
6194 
6195  case 0x19: // Unsigned integer (two-byte uint16_t follows)
6196  {
6197  std::uint16_t number;
6198  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6199  }
6200 
6201  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
6202  {
6203  std::uint32_t number;
6204  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6205  }
6206 
6207  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
6208  {
6209  std::uint64_t number;
6210  return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
6211  }
6212 
6213  // Negative integer -1-0x00..-1-0x17 (-1..-24)
6214  case 0x20:
6215  case 0x21:
6216  case 0x22:
6217  case 0x23:
6218  case 0x24:
6219  case 0x25:
6220  case 0x26:
6221  case 0x27:
6222  case 0x28:
6223  case 0x29:
6224  case 0x2A:
6225  case 0x2B:
6226  case 0x2C:
6227  case 0x2D:
6228  case 0x2E:
6229  case 0x2F:
6230  case 0x30:
6231  case 0x31:
6232  case 0x32:
6233  case 0x33:
6234  case 0x34:
6235  case 0x35:
6236  case 0x36:
6237  case 0x37:
6238  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
6239 
6240  case 0x38: // Negative integer (one-byte uint8_t follows)
6241  {
6242  std::uint8_t number;
6243  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6244  }
6245 
6246  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
6247  {
6248  std::uint16_t number;
6249  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6250  }
6251 
6252  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
6253  {
6254  std::uint32_t number;
6255  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
6256  }
6257 
6258  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
6259  {
6260  std::uint64_t number;
6261  return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
6262  - static_cast<number_integer_t>(number));
6263  }
6264 
6265  // Binary data (0x00..0x17 bytes follow)
6266  case 0x40:
6267  case 0x41:
6268  case 0x42:
6269  case 0x43:
6270  case 0x44:
6271  case 0x45:
6272  case 0x46:
6273  case 0x47:
6274  case 0x48:
6275  case 0x49:
6276  case 0x4A:
6277  case 0x4B:
6278  case 0x4C:
6279  case 0x4D:
6280  case 0x4E:
6281  case 0x4F:
6282  case 0x50:
6283  case 0x51:
6284  case 0x52:
6285  case 0x53:
6286  case 0x54:
6287  case 0x55:
6288  case 0x56:
6289  case 0x57:
6290  case 0x58: // Binary data (one-byte uint8_t for n follows)
6291  case 0x59: // Binary data (two-byte uint16_t for n follow)
6292  case 0x5A: // Binary data (four-byte uint32_t for n follow)
6293  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
6294  case 0x5F: // Binary data (indefinite length)
6295  {
6296  binary_t b;
6297  return get_cbor_binary(b) and sax->binary(b);
6298  }
6299 
6300  // UTF-8 string (0x00..0x17 bytes follow)
6301  case 0x60:
6302  case 0x61:
6303  case 0x62:
6304  case 0x63:
6305  case 0x64:
6306  case 0x65:
6307  case 0x66:
6308  case 0x67:
6309  case 0x68:
6310  case 0x69:
6311  case 0x6A:
6312  case 0x6B:
6313  case 0x6C:
6314  case 0x6D:
6315  case 0x6E:
6316  case 0x6F:
6317  case 0x70:
6318  case 0x71:
6319  case 0x72:
6320  case 0x73:
6321  case 0x74:
6322  case 0x75:
6323  case 0x76:
6324  case 0x77:
6325  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6326  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6327  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6328  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6329  case 0x7F: // UTF-8 string (indefinite length)
6330  {
6331  string_t s;
6332  return get_cbor_string(s) and sax->string(s);
6333  }
6334 
6335  // array (0x00..0x17 data items follow)
6336  case 0x80:
6337  case 0x81:
6338  case 0x82:
6339  case 0x83:
6340  case 0x84:
6341  case 0x85:
6342  case 0x86:
6343  case 0x87:
6344  case 0x88:
6345  case 0x89:
6346  case 0x8A:
6347  case 0x8B:
6348  case 0x8C:
6349  case 0x8D:
6350  case 0x8E:
6351  case 0x8F:
6352  case 0x90:
6353  case 0x91:
6354  case 0x92:
6355  case 0x93:
6356  case 0x94:
6357  case 0x95:
6358  case 0x96:
6359  case 0x97:
6360  return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
6361 
6362  case 0x98: // array (one-byte uint8_t for n follows)
6363  {
6364  std::uint8_t len;
6365  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6366  }
6367 
6368  case 0x99: // array (two-byte uint16_t for n follow)
6369  {
6370  std::uint16_t len;
6371  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6372  }
6373 
6374  case 0x9A: // array (four-byte uint32_t for n follow)
6375  {
6376  std::uint32_t len;
6377  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6378  }
6379 
6380  case 0x9B: // array (eight-byte uint64_t for n follow)
6381  {
6382  std::uint64_t len;
6383  return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
6384  }
6385 
6386  case 0x9F: // array (indefinite length)
6387  return get_cbor_array(std::size_t(-1));
6388 
6389  // map (0x00..0x17 pairs of data items follow)
6390  case 0xA0:
6391  case 0xA1:
6392  case 0xA2:
6393  case 0xA3:
6394  case 0xA4:
6395  case 0xA5:
6396  case 0xA6:
6397  case 0xA7:
6398  case 0xA8:
6399  case 0xA9:
6400  case 0xAA:
6401  case 0xAB:
6402  case 0xAC:
6403  case 0xAD:
6404  case 0xAE:
6405  case 0xAF:
6406  case 0xB0:
6407  case 0xB1:
6408  case 0xB2:
6409  case 0xB3:
6410  case 0xB4:
6411  case 0xB5:
6412  case 0xB6:
6413  case 0xB7:
6414  return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
6415 
6416  case 0xB8: // map (one-byte uint8_t for n follows)
6417  {
6418  std::uint8_t len;
6419  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6420  }
6421 
6422  case 0xB9: // map (two-byte uint16_t for n follow)
6423  {
6424  std::uint16_t len;
6425  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6426  }
6427 
6428  case 0xBA: // map (four-byte uint32_t for n follow)
6429  {
6430  std::uint32_t len;
6431  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6432  }
6433 
6434  case 0xBB: // map (eight-byte uint64_t for n follow)
6435  {
6436  std::uint64_t len;
6437  return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
6438  }
6439 
6440  case 0xBF: // map (indefinite length)
6441  return get_cbor_object(std::size_t(-1));
6442 
6443  case 0xF4: // false
6444  return sax->boolean(false);
6445 
6446  case 0xF5: // true
6447  return sax->boolean(true);
6448 
6449  case 0xF6: // null
6450  return sax->null();
6451 
6452  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
6453  {
6454  const int byte1_raw = get();
6455  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6456  {
6457  return false;
6458  }
6459  const int byte2_raw = get();
6460  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
6461  {
6462  return false;
6463  }
6464 
6465  const auto byte1 = static_cast<unsigned char>(byte1_raw);
6466  const auto byte2 = static_cast<unsigned char>(byte2_raw);
6467 
6468  // code from RFC 7049, Appendix D, Figure 3:
6469  // As half-precision floating-point numbers were only added
6470  // to IEEE 754 in 2008, today's programming platforms often
6471  // still only have limited support for them. It is very
6472  // easy to include at least decoding support for them even
6473  // without such support. An example of a small decoder for
6474  // half-precision floating-point numbers in the C language
6475  // is shown in Fig. 3.
6476  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
6477  const double val = [&half]
6478  {
6479  const int exp = (half >> 10u) & 0x1Fu;
6480  const unsigned int mant = half & 0x3FFu;
6481  assert(0 <= exp and exp <= 32);
6482  assert(mant <= 1024);
6483  switch (exp)
6484  {
6485  case 0:
6486  return std::ldexp(mant, -24);
6487  case 31:
6488  return (mant == 0)
6489  ? std::numeric_limits<double>::infinity()
6490  : std::numeric_limits<double>::quiet_NaN();
6491  default:
6492  return std::ldexp(mant + 1024, exp - 25);
6493  }
6494  }();
6495  return sax->number_float((half & 0x8000u) != 0
6496  ? static_cast<number_float_t>(-val)
6497  : static_cast<number_float_t>(val), "");
6498  }
6499 
6500  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
6501  {
6502  float number;
6503  return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
6504  }
6505 
6506  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
6507  {
6508  double number;
6509  return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
6510  }
6511 
6512  default: // anything else (0xFF is handled inside the other types)
6513  {
6514  auto last_token = get_token_string();
6515  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")));
6516  }
6517  }
6518  }
6519 
6531  bool get_cbor_string(string_t& result)
6532  {
6533  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
6534  {
6535  return false;
6536  }
6537 
6538  switch (current)
6539  {
6540  // UTF-8 string (0x00..0x17 bytes follow)
6541  case 0x60:
6542  case 0x61:
6543  case 0x62:
6544  case 0x63:
6545  case 0x64:
6546  case 0x65:
6547  case 0x66:
6548  case 0x67:
6549  case 0x68:
6550  case 0x69:
6551  case 0x6A:
6552  case 0x6B:
6553  case 0x6C:
6554  case 0x6D:
6555  case 0x6E:
6556  case 0x6F:
6557  case 0x70:
6558  case 0x71:
6559  case 0x72:
6560  case 0x73:
6561  case 0x74:
6562  case 0x75:
6563  case 0x76:
6564  case 0x77:
6565  {
6566  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
6567  }
6568 
6569  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
6570  {
6571  std::uint8_t len;
6572  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6573  }
6574 
6575  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
6576  {
6577  std::uint16_t len;
6578  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6579  }
6580 
6581  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
6582  {
6583  std::uint32_t len;
6584  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6585  }
6586 
6587  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
6588  {
6589  std::uint64_t len;
6590  return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
6591  }
6592 
6593  case 0x7F: // UTF-8 string (indefinite length)
6594  {
6595  while (get() != 0xFF)
6596  {
6597  string_t chunk;
6598  if (not get_cbor_string(chunk))
6599  {
6600  return false;
6601  }
6602  result.append(chunk);
6603  }
6604  return true;
6605  }
6606 
6607  default:
6608  {
6609  auto last_token = get_token_string();
6610  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")));
6611  }
6612  }
6613  }
6614 
6626  bool get_cbor_binary(binary_t& result)
6627  {
6628  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::cbor, "binary")))
6629  {
6630  return false;
6631  }
6632 
6633  switch (current)
6634  {
6635  // Binary data (0x00..0x17 bytes follow)
6636  case 0x40:
6637  case 0x41:
6638  case 0x42:
6639  case 0x43:
6640  case 0x44:
6641  case 0x45:
6642  case 0x46:
6643  case 0x47:
6644  case 0x48:
6645  case 0x49:
6646  case 0x4A:
6647  case 0x4B:
6648  case 0x4C:
6649  case 0x4D:
6650  case 0x4E:
6651  case 0x4F:
6652  case 0x50:
6653  case 0x51:
6654  case 0x52:
6655  case 0x53:
6656  case 0x54:
6657  case 0x55:
6658  case 0x56:
6659  case 0x57:
6660  {
6661  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
6662  }
6663 
6664  case 0x58: // Binary data (one-byte uint8_t for n follows)
6665  {
6666  std::uint8_t len;
6667  return get_number(input_format_t::cbor, len) and
6668  get_binary(input_format_t::cbor, len, result);
6669  }
6670 
6671  case 0x59: // Binary data (two-byte uint16_t for n follow)
6672  {
6673  std::uint16_t len;
6674  return get_number(input_format_t::cbor, len) and
6675  get_binary(input_format_t::cbor, len, result);
6676  }
6677 
6678  case 0x5A: // Binary data (four-byte uint32_t for n follow)
6679  {
6680  std::uint32_t len;
6681  return get_number(input_format_t::cbor, len) and
6682  get_binary(input_format_t::cbor, len, result);
6683  }
6684 
6685  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
6686  {
6687  std::uint64_t len;
6688  return get_number(input_format_t::cbor, len) and
6689  get_binary(input_format_t::cbor, len, result);
6690  }
6691 
6692  case 0x5F: // Binary data (indefinite length)
6693  {
6694  while (get() != 0xFF)
6695  {
6696  binary_t chunk;
6697  if (not get_cbor_binary(chunk))
6698  {
6699  return false;
6700  }
6701  result.insert(result.end(), chunk.begin(), chunk.end());
6702  }
6703  return true;
6704  }
6705 
6706  default:
6707  {
6708  auto last_token = get_token_string();
6709  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")));
6710  }
6711  }
6712  }
6713 
6719  bool get_cbor_array(const std::size_t len)
6720  {
6721  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
6722  {
6723  return false;
6724  }
6725 
6726  if (len != std::size_t(-1))
6727  {
6728  for (std::size_t i = 0; i < len; ++i)
6729  {
6730  if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6731  {
6732  return false;
6733  }
6734  }
6735  }
6736  else
6737  {
6738  while (get() != 0xFF)
6739  {
6740  if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal(false)))
6741  {
6742  return false;
6743  }
6744  }
6745  }
6746 
6747  return sax->end_array();
6748  }
6749 
6755  bool get_cbor_object(const std::size_t len)
6756  {
6757  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
6758  {
6759  return false;
6760  }
6761 
6762  string_t key;
6763  if (len != std::size_t(-1))
6764  {
6765  for (std::size_t i = 0; i < len; ++i)
6766  {
6767  get();
6768  if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6769  {
6770  return false;
6771  }
6772 
6773  if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6774  {
6775  return false;
6776  }
6777  key.clear();
6778  }
6779  }
6780  else
6781  {
6782  while (get() != 0xFF)
6783  {
6784  if (JSON_HEDLEY_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
6785  {
6786  return false;
6787  }
6788 
6789  if (JSON_HEDLEY_UNLIKELY(not parse_cbor_internal()))
6790  {
6791  return false;
6792  }
6793  key.clear();
6794  }
6795  }
6796 
6797  return sax->end_object();
6798  }
6799 
6801  // MsgPack //
6803 
6807  bool parse_msgpack_internal()
6808  {
6809  switch (get())
6810  {
6811  // EOF
6812  case std::char_traits<char>::eof():
6813  return unexpect_eof(input_format_t::msgpack, "value");
6814 
6815  // positive fixint
6816  case 0x00:
6817  case 0x01:
6818  case 0x02:
6819  case 0x03:
6820  case 0x04:
6821  case 0x05:
6822  case 0x06:
6823  case 0x07:
6824  case 0x08:
6825  case 0x09:
6826  case 0x0A:
6827  case 0x0B:
6828  case 0x0C:
6829  case 0x0D:
6830  case 0x0E:
6831  case 0x0F:
6832  case 0x10:
6833  case 0x11:
6834  case 0x12:
6835  case 0x13:
6836  case 0x14:
6837  case 0x15:
6838  case 0x16:
6839  case 0x17:
6840  case 0x18:
6841  case 0x19:
6842  case 0x1A:
6843  case 0x1B:
6844  case 0x1C:
6845  case 0x1D:
6846  case 0x1E:
6847  case 0x1F:
6848  case 0x20:
6849  case 0x21:
6850  case 0x22:
6851  case 0x23:
6852  case 0x24:
6853  case 0x25:
6854  case 0x26:
6855  case 0x27:
6856  case 0x28:
6857  case 0x29:
6858  case 0x2A:
6859  case 0x2B:
6860  case 0x2C:
6861  case 0x2D:
6862  case 0x2E:
6863  case 0x2F:
6864  case 0x30:
6865  case 0x31:
6866  case 0x32:
6867  case 0x33:
6868  case 0x34:
6869  case 0x35:
6870  case 0x36:
6871  case 0x37:
6872  case 0x38:
6873  case 0x39:
6874  case 0x3A:
6875  case 0x3B:
6876  case 0x3C:
6877  case 0x3D:
6878  case 0x3E:
6879  case 0x3F:
6880  case 0x40:
6881  case 0x41:
6882  case 0x42:
6883  case 0x43:
6884  case 0x44:
6885  case 0x45:
6886  case 0x46:
6887  case 0x47:
6888  case 0x48:
6889  case 0x49:
6890  case 0x4A:
6891  case 0x4B:
6892  case 0x4C:
6893  case 0x4D:
6894  case 0x4E:
6895  case 0x4F:
6896  case 0x50:
6897  case 0x51:
6898  case 0x52:
6899  case 0x53:
6900  case 0x54:
6901  case 0x55:
6902  case 0x56:
6903  case 0x57:
6904  case 0x58:
6905  case 0x59:
6906  case 0x5A:
6907  case 0x5B:
6908  case 0x5C:
6909  case 0x5D:
6910  case 0x5E:
6911  case 0x5F:
6912  case 0x60:
6913  case 0x61:
6914  case 0x62:
6915  case 0x63:
6916  case 0x64:
6917  case 0x65:
6918  case 0x66:
6919  case 0x67:
6920  case 0x68:
6921  case 0x69:
6922  case 0x6A:
6923  case 0x6B:
6924  case 0x6C:
6925  case 0x6D:
6926  case 0x6E:
6927  case 0x6F:
6928  case 0x70:
6929  case 0x71:
6930  case 0x72:
6931  case 0x73:
6932  case 0x74:
6933  case 0x75:
6934  case 0x76:
6935  case 0x77:
6936  case 0x78:
6937  case 0x79:
6938  case 0x7A:
6939  case 0x7B:
6940  case 0x7C:
6941  case 0x7D:
6942  case 0x7E:
6943  case 0x7F:
6944  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
6945 
6946  // fixmap
6947  case 0x80:
6948  case 0x81:
6949  case 0x82:
6950  case 0x83:
6951  case 0x84:
6952  case 0x85:
6953  case 0x86:
6954  case 0x87:
6955  case 0x88:
6956  case 0x89:
6957  case 0x8A:
6958  case 0x8B:
6959  case 0x8C:
6960  case 0x8D:
6961  case 0x8E:
6962  case 0x8F:
6963  return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6964 
6965  // fixarray
6966  case 0x90:
6967  case 0x91:
6968  case 0x92:
6969  case 0x93:
6970  case 0x94:
6971  case 0x95:
6972  case 0x96:
6973  case 0x97:
6974  case 0x98:
6975  case 0x99:
6976  case 0x9A:
6977  case 0x9B:
6978  case 0x9C:
6979  case 0x9D:
6980  case 0x9E:
6981  case 0x9F:
6982  return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
6983 
6984  // fixstr
6985  case 0xA0:
6986  case 0xA1:
6987  case 0xA2:
6988  case 0xA3:
6989  case 0xA4:
6990  case 0xA5:
6991  case 0xA6:
6992  case 0xA7:
6993  case 0xA8:
6994  case 0xA9:
6995  case 0xAA:
6996  case 0xAB:
6997  case 0xAC:
6998  case 0xAD:
6999  case 0xAE:
7000  case 0xAF:
7001  case 0xB0:
7002  case 0xB1:
7003  case 0xB2:
7004  case 0xB3:
7005  case 0xB4:
7006  case 0xB5:
7007  case 0xB6:
7008  case 0xB7:
7009  case 0xB8:
7010  case 0xB9:
7011  case 0xBA:
7012  case 0xBB:
7013  case 0xBC:
7014  case 0xBD:
7015  case 0xBE:
7016  case 0xBF:
7017  case 0xD9: // str 8
7018  case 0xDA: // str 16
7019  case 0xDB: // str 32
7020  {
7021  string_t s;
7022  return get_msgpack_string(s) and sax->string(s);
7023  }
7024 
7025  case 0xC0: // nil
7026  return sax->null();
7027 
7028  case 0xC2: // false
7029  return sax->boolean(false);
7030 
7031  case 0xC3: // true
7032  return sax->boolean(true);
7033 
7034  case 0xC4: // bin 8
7035  case 0xC5: // bin 16
7036  case 0xC6: // bin 32
7037  case 0xC7: // ext 8
7038  case 0xC8: // ext 16
7039  case 0xC9: // ext 32
7040  case 0xD4: // fixext 1
7041  case 0xD5: // fixext 2
7042  case 0xD6: // fixext 4
7043  case 0xD7: // fixext 8
7044  case 0xD8: // fixext 16
7045  {
7046  binary_t b;
7047  return get_msgpack_binary(b) and sax->binary(b);
7048  }
7049 
7050  case 0xCA: // float 32
7051  {
7052  float number;
7053  return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7054  }
7055 
7056  case 0xCB: // float 64
7057  {
7058  double number;
7059  return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
7060  }
7061 
7062  case 0xCC: // uint 8
7063  {
7064  std::uint8_t number;
7065  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7066  }
7067 
7068  case 0xCD: // uint 16
7069  {
7070  std::uint16_t number;
7071  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7072  }
7073 
7074  case 0xCE: // uint 32
7075  {
7076  std::uint32_t number;
7077  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7078  }
7079 
7080  case 0xCF: // uint 64
7081  {
7082  std::uint64_t number;
7083  return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
7084  }
7085 
7086  case 0xD0: // int 8
7087  {
7088  std::int8_t number;
7089  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7090  }
7091 
7092  case 0xD1: // int 16
7093  {
7094  std::int16_t number;
7095  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7096  }
7097 
7098  case 0xD2: // int 32
7099  {
7100  std::int32_t number;
7101  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7102  }
7103 
7104  case 0xD3: // int 64
7105  {
7106  std::int64_t number;
7107  return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
7108  }
7109 
7110  case 0xDC: // array 16
7111  {
7112  std::uint16_t len;
7113  return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7114  }
7115 
7116  case 0xDD: // array 32
7117  {
7118  std::uint32_t len;
7119  return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
7120  }
7121 
7122  case 0xDE: // map 16
7123  {
7124  std::uint16_t len;
7125  return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7126  }
7127 
7128  case 0xDF: // map 32
7129  {
7130  std::uint32_t len;
7131  return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
7132  }
7133 
7134  // negative fixint
7135  case 0xE0:
7136  case 0xE1:
7137  case 0xE2:
7138  case 0xE3:
7139  case 0xE4:
7140  case 0xE5:
7141  case 0xE6:
7142  case 0xE7:
7143  case 0xE8:
7144  case 0xE9:
7145  case 0xEA:
7146  case 0xEB:
7147  case 0xEC:
7148  case 0xED:
7149  case 0xEE:
7150  case 0xEF:
7151  case 0xF0:
7152  case 0xF1:
7153  case 0xF2:
7154  case 0xF3:
7155  case 0xF4:
7156  case 0xF5:
7157  case 0xF6:
7158  case 0xF7:
7159  case 0xF8:
7160  case 0xF9:
7161  case 0xFA:
7162  case 0xFB:
7163  case 0xFC:
7164  case 0xFD:
7165  case 0xFE:
7166  case 0xFF:
7167  return sax->number_integer(static_cast<std::int8_t>(current));
7168 
7169  default: // anything else
7170  {
7171  auto last_token = get_token_string();
7172  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")));
7173  }
7174  }
7175  }
7176 
7187  bool get_msgpack_string(string_t& result)
7188  {
7189  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
7190  {
7191  return false;
7192  }
7193 
7194  switch (current)
7195  {
7196  // fixstr
7197  case 0xA0:
7198  case 0xA1:
7199  case 0xA2:
7200  case 0xA3:
7201  case 0xA4:
7202  case 0xA5:
7203  case 0xA6:
7204  case 0xA7:
7205  case 0xA8:
7206  case 0xA9:
7207  case 0xAA:
7208  case 0xAB:
7209  case 0xAC:
7210  case 0xAD:
7211  case 0xAE:
7212  case 0xAF:
7213  case 0xB0:
7214  case 0xB1:
7215  case 0xB2:
7216  case 0xB3:
7217  case 0xB4:
7218  case 0xB5:
7219  case 0xB6:
7220  case 0xB7:
7221  case 0xB8:
7222  case 0xB9:
7223  case 0xBA:
7224  case 0xBB:
7225  case 0xBC:
7226  case 0xBD:
7227  case 0xBE:
7228  case 0xBF:
7229  {
7230  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
7231  }
7232 
7233  case 0xD9: // str 8
7234  {
7235  std::uint8_t len;
7236  return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7237  }
7238 
7239  case 0xDA: // str 16
7240  {
7241  std::uint16_t len;
7242  return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7243  }
7244 
7245  case 0xDB: // str 32
7246  {
7247  std::uint32_t len;
7248  return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
7249  }
7250 
7251  default:
7252  {
7253  auto last_token = get_token_string();
7254  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")));
7255  }
7256  }
7257  }
7258 
7269  bool get_msgpack_binary(binary_t& result)
7270  {
7271  // helper function to set the subtype
7272  auto assign_and_return_true = [&result](std::int8_t subtype)
7273  {
7274  result.set_subtype(static_cast<std::uint8_t>(subtype));
7275  return true;
7276  };
7277 
7278  switch (current)
7279  {
7280  case 0xC4: // bin 8
7281  {
7282  std::uint8_t len;
7283  return get_number(input_format_t::msgpack, len) and
7284  get_binary(input_format_t::msgpack, len, result);
7285  }
7286 
7287  case 0xC5: // bin 16
7288  {
7289  std::uint16_t len;
7290  return get_number(input_format_t::msgpack, len) and
7291  get_binary(input_format_t::msgpack, len, result);
7292  }
7293 
7294  case 0xC6: // bin 32
7295  {
7296  std::uint32_t len;
7297  return get_number(input_format_t::msgpack, len) and
7298  get_binary(input_format_t::msgpack, len, result);
7299  }
7300 
7301  case 0xC7: // ext 8
7302  {
7303  std::uint8_t len;
7304  std::int8_t subtype;
7305  return get_number(input_format_t::msgpack, len) and
7306  get_number(input_format_t::msgpack, subtype) and
7307  get_binary(input_format_t::msgpack, len, result) and
7308  assign_and_return_true(subtype);
7309  }
7310 
7311  case 0xC8: // ext 16
7312  {
7313  std::uint16_t len;
7314  std::int8_t subtype;
7315  return get_number(input_format_t::msgpack, len) and
7316  get_number(input_format_t::msgpack, subtype) and
7317  get_binary(input_format_t::msgpack, len, result) and
7318  assign_and_return_true(subtype);
7319  }
7320 
7321  case 0xC9: // ext 32
7322  {
7323  std::uint32_t len;
7324  std::int8_t subtype;
7325  return get_number(input_format_t::msgpack, len) and
7326  get_number(input_format_t::msgpack, subtype) and
7327  get_binary(input_format_t::msgpack, len, result) and
7328  assign_and_return_true(subtype);
7329  }
7330 
7331  case 0xD4: // fixext 1
7332  {
7333  std::int8_t subtype;
7334  return get_number(input_format_t::msgpack, subtype) and
7335  get_binary(input_format_t::msgpack, 1, result) and
7336  assign_and_return_true(subtype);
7337  }
7338 
7339  case 0xD5: // fixext 2
7340  {
7341  std::int8_t subtype;
7342  return get_number(input_format_t::msgpack, subtype) and
7343  get_binary(input_format_t::msgpack, 2, result) and
7344  assign_and_return_true(subtype);
7345  }
7346 
7347  case 0xD6: // fixext 4
7348  {
7349  std::int8_t subtype;
7350  return get_number(input_format_t::msgpack, subtype) and
7351  get_binary(input_format_t::msgpack, 4, result) and
7352  assign_and_return_true(subtype);
7353  }
7354 
7355  case 0xD7: // fixext 8
7356  {
7357  std::int8_t subtype;
7358  return get_number(input_format_t::msgpack, subtype) and
7359  get_binary(input_format_t::msgpack, 8, result) and
7360  assign_and_return_true(subtype);
7361  }
7362 
7363  case 0xD8: // fixext 16
7364  {
7365  std::int8_t subtype;
7366  return get_number(input_format_t::msgpack, subtype) and
7367  get_binary(input_format_t::msgpack, 16, result) and
7368  assign_and_return_true(subtype);
7369  }
7370 
7371  default: // LCOV_EXCL_LINE
7372  return false; // LCOV_EXCL_LINE
7373  }
7374  }
7375 
7380  bool get_msgpack_array(const std::size_t len)
7381  {
7382  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(len)))
7383  {
7384  return false;
7385  }
7386 
7387  for (std::size_t i = 0; i < len; ++i)
7388  {
7389  if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7390  {
7391  return false;
7392  }
7393  }
7394 
7395  return sax->end_array();
7396  }
7397 
7402  bool get_msgpack_object(const std::size_t len)
7403  {
7404  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(len)))
7405  {
7406  return false;
7407  }
7408 
7409  string_t key;
7410  for (std::size_t i = 0; i < len; ++i)
7411  {
7412  get();
7413  if (JSON_HEDLEY_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
7414  {
7415  return false;
7416  }
7417 
7418  if (JSON_HEDLEY_UNLIKELY(not parse_msgpack_internal()))
7419  {
7420  return false;
7421  }
7422  key.clear();
7423  }
7424 
7425  return sax->end_object();
7426  }
7427 
7429  // UBJSON //
7431 
7439  bool parse_ubjson_internal(const bool get_char = true)
7440  {
7441  return get_ubjson_value(get_char ? get_ignore_noop() : current);
7442  }
7443 
7458  bool get_ubjson_string(string_t& result, const bool get_char = true)
7459  {
7460  if (get_char)
7461  {
7462  get(); // TODO(niels): may we ignore N here?
7463  }
7464 
7465  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7466  {
7467  return false;
7468  }
7469 
7470  switch (current)
7471  {
7472  case 'U':
7473  {
7474  std::uint8_t len;
7475  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7476  }
7477 
7478  case 'i':
7479  {
7480  std::int8_t len;
7481  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7482  }
7483 
7484  case 'I':
7485  {
7486  std::int16_t len;
7487  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7488  }
7489 
7490  case 'l':
7491  {
7492  std::int32_t len;
7493  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7494  }
7495 
7496  case 'L':
7497  {
7498  std::int64_t len;
7499  return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
7500  }
7501 
7502  default:
7503  auto last_token = get_token_string();
7504  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")));
7505  }
7506  }
7507 
7512  bool get_ubjson_size_value(std::size_t& result)
7513  {
7514  switch (get_ignore_noop())
7515  {
7516  case 'U':
7517  {
7518  std::uint8_t number;
7519  if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7520  {
7521  return false;
7522  }
7523  result = static_cast<std::size_t>(number);
7524  return true;
7525  }
7526 
7527  case 'i':
7528  {
7529  std::int8_t number;
7530  if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7531  {
7532  return false;
7533  }
7534  result = static_cast<std::size_t>(number);
7535  return true;
7536  }
7537 
7538  case 'I':
7539  {
7540  std::int16_t number;
7541  if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7542  {
7543  return false;
7544  }
7545  result = static_cast<std::size_t>(number);
7546  return true;
7547  }
7548 
7549  case 'l':
7550  {
7551  std::int32_t number;
7552  if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7553  {
7554  return false;
7555  }
7556  result = static_cast<std::size_t>(number);
7557  return true;
7558  }
7559 
7560  case 'L':
7561  {
7562  std::int64_t number;
7563  if (JSON_HEDLEY_UNLIKELY(not get_number(input_format_t::ubjson, number)))
7564  {
7565  return false;
7566  }
7567  result = static_cast<std::size_t>(number);
7568  return true;
7569  }
7570 
7571  default:
7572  {
7573  auto last_token = get_token_string();
7574  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")));
7575  }
7576  }
7577  }
7578 
7589  bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
7590  {
7591  result.first = string_t::npos; // size
7592  result.second = 0; // type
7593 
7594  get_ignore_noop();
7595 
7596  if (current == '$')
7597  {
7598  result.second = get(); // must not ignore 'N', because 'N' maybe the type
7599  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
7600  {
7601  return false;
7602  }
7603 
7604  get_ignore_noop();
7605  if (JSON_HEDLEY_UNLIKELY(current != '#'))
7606  {
7607  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
7608  {
7609  return false;
7610  }
7611  auto last_token = get_token_string();
7612  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")));
7613  }
7614 
7615  return get_ubjson_size_value(result.first);
7616  }
7617 
7618  if (current == '#')
7619  {
7620  return get_ubjson_size_value(result.first);
7621  }
7622 
7623  return true;
7624  }
7625 
7630  bool get_ubjson_value(const int prefix)
7631  {
7632  switch (prefix)
7633  {
7634  case std::char_traits<char>::eof(): // EOF
7635  return unexpect_eof(input_format_t::ubjson, "value");
7636 
7637  case 'T': // true
7638  return sax->boolean(true);
7639  case 'F': // false
7640  return sax->boolean(false);
7641 
7642  case 'Z': // null
7643  return sax->null();
7644 
7645  case 'U':
7646  {
7647  std::uint8_t number;
7648  return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
7649  }
7650 
7651  case 'i':
7652  {
7653  std::int8_t number;
7654  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7655  }
7656 
7657  case 'I':
7658  {
7659  std::int16_t number;
7660  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7661  }
7662 
7663  case 'l':
7664  {
7665  std::int32_t number;
7666  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7667  }
7668 
7669  case 'L':
7670  {
7671  std::int64_t number;
7672  return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
7673  }
7674 
7675  case 'd':
7676  {
7677  float number;
7678  return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7679  }
7680 
7681  case 'D':
7682  {
7683  double number;
7684  return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
7685  }
7686 
7687  case 'C': // char
7688  {
7689  get();
7690  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
7691  {
7692  return false;
7693  }
7694  if (JSON_HEDLEY_UNLIKELY(current > 127))
7695  {
7696  auto last_token = get_token_string();
7697  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")));
7698  }
7699  string_t s(1, static_cast<char>(current));
7700  return sax->string(s);
7701  }
7702 
7703  case 'S': // string
7704  {
7705  string_t s;
7706  return get_ubjson_string(s) and sax->string(s);
7707  }
7708 
7709  case '[': // array
7710  return get_ubjson_array();
7711 
7712  case '{': // object
7713  return get_ubjson_object();
7714 
7715  default: // anything else
7716  {
7717  auto last_token = get_token_string();
7718  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")));
7719  }
7720  }
7721  }
7722 
7726  bool get_ubjson_array()
7727  {
7728  std::pair<std::size_t, int> size_and_type;
7729  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7730  {
7731  return false;
7732  }
7733 
7734  if (size_and_type.first != string_t::npos)
7735  {
7736  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(size_and_type.first)))
7737  {
7738  return false;
7739  }
7740 
7741  if (size_and_type.second != 0)
7742  {
7743  if (size_and_type.second != 'N')
7744  {
7745  for (std::size_t i = 0; i < size_and_type.first; ++i)
7746  {
7747  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7748  {
7749  return false;
7750  }
7751  }
7752  }
7753  }
7754  else
7755  {
7756  for (std::size_t i = 0; i < size_and_type.first; ++i)
7757  {
7758  if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7759  {
7760  return false;
7761  }
7762  }
7763  }
7764  }
7765  else
7766  {
7767  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
7768  {
7769  return false;
7770  }
7771 
7772  while (current != ']')
7773  {
7774  if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal(false)))
7775  {
7776  return false;
7777  }
7778  get_ignore_noop();
7779  }
7780  }
7781 
7782  return sax->end_array();
7783  }
7784 
7788  bool get_ubjson_object()
7789  {
7790  std::pair<std::size_t, int> size_and_type;
7791  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_size_type(size_and_type)))
7792  {
7793  return false;
7794  }
7795 
7796  string_t key;
7797  if (size_and_type.first != string_t::npos)
7798  {
7799  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(size_and_type.first)))
7800  {
7801  return false;
7802  }
7803 
7804  if (size_and_type.second != 0)
7805  {
7806  for (std::size_t i = 0; i < size_and_type.first; ++i)
7807  {
7808  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7809  {
7810  return false;
7811  }
7812  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_value(size_and_type.second)))
7813  {
7814  return false;
7815  }
7816  key.clear();
7817  }
7818  }
7819  else
7820  {
7821  for (std::size_t i = 0; i < size_and_type.first; ++i)
7822  {
7823  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
7824  {
7825  return false;
7826  }
7827  if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7828  {
7829  return false;
7830  }
7831  key.clear();
7832  }
7833  }
7834  }
7835  else
7836  {
7837  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
7838  {
7839  return false;
7840  }
7841 
7842  while (current != '}')
7843  {
7844  if (JSON_HEDLEY_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
7845  {
7846  return false;
7847  }
7848  if (JSON_HEDLEY_UNLIKELY(not parse_ubjson_internal()))
7849  {
7850  return false;
7851  }
7852  get_ignore_noop();
7853  key.clear();
7854  }
7855  }
7856 
7857  return sax->end_object();
7858  }
7859 
7860  // Note, no reader for UBJSON binary types is implemented because they do
7861  // not exist
7862 
7864  // Utility functions //
7866 
7876  int get()
7877  {
7878  ++chars_read;
7879  return current = ia.get_character();
7880  }
7881 
7885  int get_ignore_noop()
7886  {
7887  do
7888  {
7889  get();
7890  }
7891  while (current == 'N');
7892 
7893  return current;
7894  }
7895 
7896  /*
7897  @brief read a number from the input
7898 
7899  @tparam NumberType the type of the number
7900  @param[in] format the current format (for diagnostics)
7901  @param[out] result number of type @a NumberType
7902 
7903  @return whether conversion completed
7904 
7905  @note This function needs to respect the system's endianess, because
7906  bytes in CBOR, MessagePack, and UBJSON are stored in network order
7907  (big endian) and therefore need reordering on little endian systems.
7908  */
7909  template<typename NumberType, bool InputIsLittleEndian = false>
7910  bool get_number(const input_format_t format, NumberType& result)
7911  {
7912  // step 1: read input into array with system's byte order
7913  std::array<std::uint8_t, sizeof(NumberType)> vec;
7914  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
7915  {
7916  get();
7917  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "number")))
7918  {
7919  return false;
7920  }
7921 
7922  // reverse byte order prior to conversion if necessary
7923  if (is_little_endian != InputIsLittleEndian)
7924  {
7925  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
7926  }
7927  else
7928  {
7929  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
7930  }
7931  }
7932 
7933  // step 2: convert array into number of type T and return
7934  std::memcpy(&result, vec.data(), sizeof(NumberType));
7935  return true;
7936  }
7937 
7952  template<typename NumberType>
7953  bool get_string(const input_format_t format,
7954  const NumberType len,
7955  string_t& result)
7956  {
7957  bool success = true;
7958  std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7959  {
7960  get();
7961  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "string")))
7962  {
7963  success = false;
7964  }
7965  return static_cast<char>(current);
7966  });
7967  return success;
7968  }
7969 
7984  template<typename NumberType>
7985  bool get_binary(const input_format_t format,
7986  const NumberType len,
7987  binary_t& result)
7988  {
7989  bool success = true;
7990  std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
7991  {
7992  get();
7993  if (JSON_HEDLEY_UNLIKELY(not unexpect_eof(format, "binary")))
7994  {
7995  success = false;
7996  }
7997  return static_cast<std::uint8_t>(current);
7998  });
7999  return success;
8000  }
8001 
8007  JSON_HEDLEY_NON_NULL(3)
8008  bool unexpect_eof(const input_format_t format, const char* context) const
8009  {
8010  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char>::eof()))
8011  {
8012  return sax->parse_error(chars_read, "<end of file>",
8013  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
8014  }
8015  return true;
8016  }
8017 
8021  std::string get_token_string() const
8022  {
8023  std::array<char, 3> cr{{}};
8024  (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
8025  return std::string{cr.data()};
8026  }
8027 
8034  std::string exception_message(const input_format_t format,
8035  const std::string& detail,
8036  const std::string& context) const
8037  {
8038  std::string error_msg = "syntax error while parsing ";
8039 
8040  switch (format)
8041  {
8042  case input_format_t::cbor:
8043  error_msg += "CBOR";
8044  break;
8045 
8046  case input_format_t::msgpack:
8047  error_msg += "MessagePack";
8048  break;
8049 
8050  case input_format_t::ubjson:
8051  error_msg += "UBJSON";
8052  break;
8053 
8054  case input_format_t::bson:
8055  error_msg += "BSON";
8056  break;
8057 
8058  default: // LCOV_EXCL_LINE
8059  assert(false); // LCOV_EXCL_LINE
8060  }
8061 
8062  return error_msg + " " + context + ": " + detail;
8063  }
8064 
8065  private:
8067  InputAdapterType ia;
8068 
8070  int current = std::char_traits<char>::eof();
8071 
8073  std::size_t chars_read = 0;
8074 
8076  const bool is_little_endian = little_endianess();
8077 
8079  json_sax_t* sax = nullptr;
8080 };
8081 } // namespace detail
8082 } // namespace nlohmann
8083 
8084 // #include <nlohmann/detail/input/input_adapters.hpp>
8085 
8086 // #include <nlohmann/detail/input/lexer.hpp>
8087 
8088 
8089 #include <array> // array
8090 #include <clocale> // localeconv
8091 #include <cstddef> // size_t
8092 #include <cstdio> // snprintf
8093 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
8094 #include <initializer_list> // initializer_list
8095 #include <string> // char_traits, string
8096 #include <utility> // move
8097 #include <vector> // vector
8098 
8099 // #include <nlohmann/detail/input/input_adapters.hpp>
8100 
8101 // #include <nlohmann/detail/input/position_t.hpp>
8102 
8103 // #include <nlohmann/detail/macro_scope.hpp>
8104 
8105 
8106 namespace nlohmann
8107 {
8108 namespace detail
8109 {
8111 // lexer //
8113 
8114 template<typename BasicJsonType>
8115 class lexer_base
8116 {
8117  public:
8119  enum class token_type
8120  {
8121  uninitialized,
8122  literal_true,
8123  literal_false,
8124  literal_null,
8125  value_string,
8126  value_unsigned,
8127  value_integer,
8128  value_float,
8129  begin_array,
8130  begin_object,
8131  end_array,
8132  end_object,
8133  name_separator,
8134  value_separator,
8135  parse_error,
8136  end_of_input,
8137  literal_or_value
8138  };
8139 
8141 
8142  JSON_HEDLEY_CONST
8143  static const char* token_type_name(const token_type t) noexcept
8144  {
8145  switch (t)
8146  {
8147  case token_type::uninitialized:
8148  return "<uninitialized>";
8149  case token_type::literal_true:
8150  return "true literal";
8151  case token_type::literal_false:
8152  return "false literal";
8153  case token_type::literal_null:
8154  return "null literal";
8155  case token_type::value_string:
8156  return "string literal";
8157  case token_type::value_unsigned:
8158  case token_type::value_integer:
8159  case token_type::value_float:
8160  return "number literal";
8161  case token_type::begin_array:
8162  return "'['";
8163  case token_type::begin_object:
8164  return "'{'";
8165  case token_type::end_array:
8166  return "']'";
8167  case token_type::end_object:
8168  return "'}'";
8169  case token_type::name_separator:
8170  return "':'";
8171  case token_type::value_separator:
8172  return "','";
8173  case token_type::parse_error:
8174  return "<parse error>";
8175  case token_type::end_of_input:
8176  return "end of input";
8177  case token_type::literal_or_value:
8178  return "'[', '{', or a literal";
8179  // LCOV_EXCL_START
8180  default: // catch non-enum values
8181  return "unknown token";
8182  // LCOV_EXCL_STOP
8183  }
8184  }
8185 };
8191 template<typename BasicJsonType, typename InputAdapterType>
8192 class lexer : public lexer_base<BasicJsonType>
8193 {
8194  using number_integer_t = typename BasicJsonType::number_integer_t;
8195  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8196  using number_float_t = typename BasicJsonType::number_float_t;
8197  using string_t = typename BasicJsonType::string_t;
8198 
8199  public:
8200  using token_type = typename lexer_base<BasicJsonType>::token_type;
8201 
8202  explicit lexer(InputAdapterType&& adapter)
8203  : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
8204 
8205  // delete because of pointer members
8206  lexer(const lexer&) = delete;
8207  lexer(lexer&&) = default;
8208  lexer& operator=(lexer&) = delete;
8209  lexer& operator=(lexer&&) = default;
8210  ~lexer() = default;
8211 
8212  private:
8214  // locales
8216 
8218  JSON_HEDLEY_PURE
8219  static char get_decimal_point() noexcept
8220  {
8221  const auto loc = localeconv();
8222  assert(loc != nullptr);
8223  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
8224  }
8225 
8227  // scan functions
8229 
8245  int get_codepoint()
8246  {
8247  // this function only makes sense after reading `\u`
8248  assert(current == 'u');
8249  int codepoint = 0;
8250 
8251  const auto factors = { 12u, 8u, 4u, 0u };
8252  for (const auto factor : factors)
8253  {
8254  get();
8255 
8256  if (current >= '0' and current <= '9')
8257  {
8258  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
8259  }
8260  else if (current >= 'A' and current <= 'F')
8261  {
8262  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
8263  }
8264  else if (current >= 'a' and current <= 'f')
8265  {
8266  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
8267  }
8268  else
8269  {
8270  return -1;
8271  }
8272  }
8273 
8274  assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
8275  return codepoint;
8276  }
8277 
8293  bool next_byte_in_range(std::initializer_list<int> ranges)
8294  {
8295  assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
8296  add(current);
8297 
8298  for (auto range = ranges.begin(); range != ranges.end(); ++range)
8299  {
8300  get();
8301  if (JSON_HEDLEY_LIKELY(*range <= current and current <= *(++range)))
8302  {
8303  add(current);
8304  }
8305  else
8306  {
8307  error_message = "invalid string: ill-formed UTF-8 byte";
8308  return false;
8309  }
8310  }
8311 
8312  return true;
8313  }
8314 
8330  token_type scan_string()
8331  {
8332  // reset token_buffer (ignore opening quote)
8333  reset();
8334 
8335  // we entered the function by reading an open quote
8336  assert(current == '\"');
8337 
8338  while (true)
8339  {
8340  // get next character
8341  switch (get())
8342  {
8343  // end of file while parsing string
8344  case std::char_traits<char>::eof():
8345  {
8346  error_message = "invalid string: missing closing quote";
8347  return token_type::parse_error;
8348  }
8349 
8350  // closing quote
8351  case '\"':
8352  {
8353  return token_type::value_string;
8354  }
8355 
8356  // escapes
8357  case '\\':
8358  {
8359  switch (get())
8360  {
8361  // quotation mark
8362  case '\"':
8363  add('\"');
8364  break;
8365  // reverse solidus
8366  case '\\':
8367  add('\\');
8368  break;
8369  // solidus
8370  case '/':
8371  add('/');
8372  break;
8373  // backspace
8374  case 'b':
8375  add('\b');
8376  break;
8377  // form feed
8378  case 'f':
8379  add('\f');
8380  break;
8381  // line feed
8382  case 'n':
8383  add('\n');
8384  break;
8385  // carriage return
8386  case 'r':
8387  add('\r');
8388  break;
8389  // tab
8390  case 't':
8391  add('\t');
8392  break;
8393 
8394  // unicode escapes
8395  case 'u':
8396  {
8397  const int codepoint1 = get_codepoint();
8398  int codepoint = codepoint1; // start with codepoint1
8399 
8400  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
8401  {
8402  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
8403  return token_type::parse_error;
8404  }
8405 
8406  // check if code point is a high surrogate
8407  if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
8408  {
8409  // expect next \uxxxx entry
8410  if (JSON_HEDLEY_LIKELY(get() == '\\' and get() == 'u'))
8411  {
8412  const int codepoint2 = get_codepoint();
8413 
8414  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
8415  {
8416  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
8417  return token_type::parse_error;
8418  }
8419 
8420  // check if codepoint2 is a low surrogate
8421  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
8422  {
8423  // overwrite codepoint
8424  codepoint = static_cast<int>(
8425  // high surrogate occupies the most significant 22 bits
8426  (static_cast<unsigned int>(codepoint1) << 10u)
8427  // low surrogate occupies the least significant 15 bits
8428  + static_cast<unsigned int>(codepoint2)
8429  // there is still the 0xD800, 0xDC00 and 0x10000 noise
8430  // in the result so we have to subtract with:
8431  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
8432  - 0x35FDC00u);
8433  }
8434  else
8435  {
8436  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8437  return token_type::parse_error;
8438  }
8439  }
8440  else
8441  {
8442  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
8443  return token_type::parse_error;
8444  }
8445  }
8446  else
8447  {
8448  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
8449  {
8450  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
8451  return token_type::parse_error;
8452  }
8453  }
8454 
8455  // result of the above calculation yields a proper codepoint
8456  assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
8457 
8458  // translate codepoint into bytes
8459  if (codepoint < 0x80)
8460  {
8461  // 1-byte characters: 0xxxxxxx (ASCII)
8462  add(codepoint);
8463  }
8464  else if (codepoint <= 0x7FF)
8465  {
8466  // 2-byte characters: 110xxxxx 10xxxxxx
8467  add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
8468  add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8469  }
8470  else if (codepoint <= 0xFFFF)
8471  {
8472  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
8473  add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
8474  add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8475  add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8476  }
8477  else
8478  {
8479  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
8480  add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
8481  add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
8482  add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
8483  add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
8484  }
8485 
8486  break;
8487  }
8488 
8489  // other characters after escape
8490  default:
8491  error_message = "invalid string: forbidden character after backslash";
8492  return token_type::parse_error;
8493  }
8494 
8495  break;
8496  }
8497 
8498  // invalid control characters
8499  case 0x00:
8500  {
8501  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
8502  return token_type::parse_error;
8503  }
8504 
8505  case 0x01:
8506  {
8507  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
8508  return token_type::parse_error;
8509  }
8510 
8511  case 0x02:
8512  {
8513  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
8514  return token_type::parse_error;
8515  }
8516 
8517  case 0x03:
8518  {
8519  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
8520  return token_type::parse_error;
8521  }
8522 
8523  case 0x04:
8524  {
8525  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
8526  return token_type::parse_error;
8527  }
8528 
8529  case 0x05:
8530  {
8531  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
8532  return token_type::parse_error;
8533  }
8534 
8535  case 0x06:
8536  {
8537  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
8538  return token_type::parse_error;
8539  }
8540 
8541  case 0x07:
8542  {
8543  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
8544  return token_type::parse_error;
8545  }
8546 
8547  case 0x08:
8548  {
8549  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
8550  return token_type::parse_error;
8551  }
8552 
8553  case 0x09:
8554  {
8555  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
8556  return token_type::parse_error;
8557  }
8558 
8559  case 0x0A:
8560  {
8561  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
8562  return token_type::parse_error;
8563  }
8564 
8565  case 0x0B:
8566  {
8567  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
8568  return token_type::parse_error;
8569  }
8570 
8571  case 0x0C:
8572  {
8573  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
8574  return token_type::parse_error;
8575  }
8576 
8577  case 0x0D:
8578  {
8579  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
8580  return token_type::parse_error;
8581  }
8582 
8583  case 0x0E:
8584  {
8585  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
8586  return token_type::parse_error;
8587  }
8588 
8589  case 0x0F:
8590  {
8591  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
8592  return token_type::parse_error;
8593  }
8594 
8595  case 0x10:
8596  {
8597  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
8598  return token_type::parse_error;
8599  }
8600 
8601  case 0x11:
8602  {
8603  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
8604  return token_type::parse_error;
8605  }
8606 
8607  case 0x12:
8608  {
8609  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
8610  return token_type::parse_error;
8611  }
8612 
8613  case 0x13:
8614  {
8615  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
8616  return token_type::parse_error;
8617  }
8618 
8619  case 0x14:
8620  {
8621  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
8622  return token_type::parse_error;
8623  }
8624 
8625  case 0x15:
8626  {
8627  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
8628  return token_type::parse_error;
8629  }
8630 
8631  case 0x16:
8632  {
8633  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
8634  return token_type::parse_error;
8635  }
8636 
8637  case 0x17:
8638  {
8639  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
8640  return token_type::parse_error;
8641  }
8642 
8643  case 0x18:
8644  {
8645  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
8646  return token_type::parse_error;
8647  }
8648 
8649  case 0x19:
8650  {
8651  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
8652  return token_type::parse_error;
8653  }
8654 
8655  case 0x1A:
8656  {
8657  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
8658  return token_type::parse_error;
8659  }
8660 
8661  case 0x1B:
8662  {
8663  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
8664  return token_type::parse_error;
8665  }
8666 
8667  case 0x1C:
8668  {
8669  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
8670  return token_type::parse_error;
8671  }
8672 
8673  case 0x1D:
8674  {
8675  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
8676  return token_type::parse_error;
8677  }
8678 
8679  case 0x1E:
8680  {
8681  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
8682  return token_type::parse_error;
8683  }
8684 
8685  case 0x1F:
8686  {
8687  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
8688  return token_type::parse_error;
8689  }
8690 
8691  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
8692  case 0x20:
8693  case 0x21:
8694  case 0x23:
8695  case 0x24:
8696  case 0x25:
8697  case 0x26:
8698  case 0x27:
8699  case 0x28:
8700  case 0x29:
8701  case 0x2A:
8702  case 0x2B:
8703  case 0x2C:
8704  case 0x2D:
8705  case 0x2E:
8706  case 0x2F:
8707  case 0x30:
8708  case 0x31:
8709  case 0x32:
8710  case 0x33:
8711  case 0x34:
8712  case 0x35:
8713  case 0x36:
8714  case 0x37:
8715  case 0x38:
8716  case 0x39:
8717  case 0x3A:
8718  case 0x3B:
8719  case 0x3C:
8720  case 0x3D:
8721  case 0x3E:
8722  case 0x3F:
8723  case 0x40:
8724  case 0x41:
8725  case 0x42:
8726  case 0x43:
8727  case 0x44:
8728  case 0x45:
8729  case 0x46:
8730  case 0x47:
8731  case 0x48:
8732  case 0x49:
8733  case 0x4A:
8734  case 0x4B:
8735  case 0x4C:
8736  case 0x4D:
8737  case 0x4E:
8738  case 0x4F:
8739  case 0x50:
8740  case 0x51:
8741  case 0x52:
8742  case 0x53:
8743  case 0x54:
8744  case 0x55:
8745  case 0x56:
8746  case 0x57:
8747  case 0x58:
8748  case 0x59:
8749  case 0x5A:
8750  case 0x5B:
8751  case 0x5D:
8752  case 0x5E:
8753  case 0x5F:
8754  case 0x60:
8755  case 0x61:
8756  case 0x62:
8757  case 0x63:
8758  case 0x64:
8759  case 0x65:
8760  case 0x66:
8761  case 0x67:
8762  case 0x68:
8763  case 0x69:
8764  case 0x6A:
8765  case 0x6B:
8766  case 0x6C:
8767  case 0x6D:
8768  case 0x6E:
8769  case 0x6F:
8770  case 0x70:
8771  case 0x71:
8772  case 0x72:
8773  case 0x73:
8774  case 0x74:
8775  case 0x75:
8776  case 0x76:
8777  case 0x77:
8778  case 0x78:
8779  case 0x79:
8780  case 0x7A:
8781  case 0x7B:
8782  case 0x7C:
8783  case 0x7D:
8784  case 0x7E:
8785  case 0x7F:
8786  {
8787  add(current);
8788  break;
8789  }
8790 
8791  // U+0080..U+07FF: bytes C2..DF 80..BF
8792  case 0xC2:
8793  case 0xC3:
8794  case 0xC4:
8795  case 0xC5:
8796  case 0xC6:
8797  case 0xC7:
8798  case 0xC8:
8799  case 0xC9:
8800  case 0xCA:
8801  case 0xCB:
8802  case 0xCC:
8803  case 0xCD:
8804  case 0xCE:
8805  case 0xCF:
8806  case 0xD0:
8807  case 0xD1:
8808  case 0xD2:
8809  case 0xD3:
8810  case 0xD4:
8811  case 0xD5:
8812  case 0xD6:
8813  case 0xD7:
8814  case 0xD8:
8815  case 0xD9:
8816  case 0xDA:
8817  case 0xDB:
8818  case 0xDC:
8819  case 0xDD:
8820  case 0xDE:
8821  case 0xDF:
8822  {
8823  if (JSON_HEDLEY_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
8824  {
8825  return token_type::parse_error;
8826  }
8827  break;
8828  }
8829 
8830  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
8831  case 0xE0:
8832  {
8833  if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
8834  {
8835  return token_type::parse_error;
8836  }
8837  break;
8838  }
8839 
8840  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
8841  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
8842  case 0xE1:
8843  case 0xE2:
8844  case 0xE3:
8845  case 0xE4:
8846  case 0xE5:
8847  case 0xE6:
8848  case 0xE7:
8849  case 0xE8:
8850  case 0xE9:
8851  case 0xEA:
8852  case 0xEB:
8853  case 0xEC:
8854  case 0xEE:
8855  case 0xEF:
8856  {
8857  if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
8858  {
8859  return token_type::parse_error;
8860  }
8861  break;
8862  }
8863 
8864  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
8865  case 0xED:
8866  {
8867  if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
8868  {
8869  return token_type::parse_error;
8870  }
8871  break;
8872  }
8873 
8874  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
8875  case 0xF0:
8876  {
8877  if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8878  {
8879  return token_type::parse_error;
8880  }
8881  break;
8882  }
8883 
8884  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
8885  case 0xF1:
8886  case 0xF2:
8887  case 0xF3:
8888  {
8889  if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
8890  {
8891  return token_type::parse_error;
8892  }
8893  break;
8894  }
8895 
8896  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
8897  case 0xF4:
8898  {
8899  if (JSON_HEDLEY_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
8900  {
8901  return token_type::parse_error;
8902  }
8903  break;
8904  }
8905 
8906  // remaining bytes (80..C1 and F5..FF) are ill-formed
8907  default:
8908  {
8909  error_message = "invalid string: ill-formed UTF-8 byte";
8910  return token_type::parse_error;
8911  }
8912  }
8913  }
8914  }
8915 
8916  JSON_HEDLEY_NON_NULL(2)
8917  static void strtof(float& f, const char* str, char** endptr) noexcept
8918  {
8919  f = std::strtof(str, endptr);
8920  }
8921 
8922  JSON_HEDLEY_NON_NULL(2)
8923  static void strtof(double& f, const char* str, char** endptr) noexcept
8924  {
8925  f = std::strtod(str, endptr);
8926  }
8927 
8928  JSON_HEDLEY_NON_NULL(2)
8929  static void strtof(long double& f, const char* str, char** endptr) noexcept
8930  {
8931  f = std::strtold(str, endptr);
8932  }
8933 
8974  token_type scan_number() // lgtm [cpp/use-of-goto]
8975  {
8976  // reset token_buffer to store the number's bytes
8977  reset();
8978 
8979  // the type of the parsed number; initially set to unsigned; will be
8980  // changed if minus sign, decimal point or exponent is read
8981  token_type number_type = token_type::value_unsigned;
8982 
8983  // state (init): we just found out we need to scan a number
8984  switch (current)
8985  {
8986  case '-':
8987  {
8988  add(current);
8989  goto scan_number_minus;
8990  }
8991 
8992  case '0':
8993  {
8994  add(current);
8995  goto scan_number_zero;
8996  }
8997 
8998  case '1':
8999  case '2':
9000  case '3':
9001  case '4':
9002  case '5':
9003  case '6':
9004  case '7':
9005  case '8':
9006  case '9':
9007  {
9008  add(current);
9009  goto scan_number_any1;
9010  }
9011 
9012  // all other characters are rejected outside scan_number()
9013  default: // LCOV_EXCL_LINE
9014  assert(false); // LCOV_EXCL_LINE
9015  }
9016 
9017 scan_number_minus:
9018  // state: we just parsed a leading minus sign
9019  number_type = token_type::value_integer;
9020  switch (get())
9021  {
9022  case '0':
9023  {
9024  add(current);
9025  goto scan_number_zero;
9026  }
9027 
9028  case '1':
9029  case '2':
9030  case '3':
9031  case '4':
9032  case '5':
9033  case '6':
9034  case '7':
9035  case '8':
9036  case '9':
9037  {
9038  add(current);
9039  goto scan_number_any1;
9040  }
9041 
9042  default:
9043  {
9044  error_message = "invalid number; expected digit after '-'";
9045  return token_type::parse_error;
9046  }
9047  }
9048 
9049 scan_number_zero:
9050  // state: we just parse a zero (maybe with a leading minus sign)
9051  switch (get())
9052  {
9053  case '.':
9054  {
9055  add(decimal_point_char);
9056  goto scan_number_decimal1;
9057  }
9058 
9059  case 'e':
9060  case 'E':
9061  {
9062  add(current);
9063  goto scan_number_exponent;
9064  }
9065 
9066  default:
9067  goto scan_number_done;
9068  }
9069 
9070 scan_number_any1:
9071  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
9072  switch (get())
9073  {
9074  case '0':
9075  case '1':
9076  case '2':
9077  case '3':
9078  case '4':
9079  case '5':
9080  case '6':
9081  case '7':
9082  case '8':
9083  case '9':
9084  {
9085  add(current);
9086  goto scan_number_any1;
9087  }
9088 
9089  case '.':
9090  {
9091  add(decimal_point_char);
9092  goto scan_number_decimal1;
9093  }
9094 
9095  case 'e':
9096  case 'E':
9097  {
9098  add(current);
9099  goto scan_number_exponent;
9100  }
9101 
9102  default:
9103  goto scan_number_done;
9104  }
9105 
9106 scan_number_decimal1:
9107  // state: we just parsed a decimal point
9108  number_type = token_type::value_float;
9109  switch (get())
9110  {
9111  case '0':
9112  case '1':
9113  case '2':
9114  case '3':
9115  case '4':
9116  case '5':
9117  case '6':
9118  case '7':
9119  case '8':
9120  case '9':
9121  {
9122  add(current);
9123  goto scan_number_decimal2;
9124  }
9125 
9126  default:
9127  {
9128  error_message = "invalid number; expected digit after '.'";
9129  return token_type::parse_error;
9130  }
9131  }
9132 
9133 scan_number_decimal2:
9134  // we just parsed at least one number after a decimal point
9135  switch (get())
9136  {
9137  case '0':
9138  case '1':
9139  case '2':
9140  case '3':
9141  case '4':
9142  case '5':
9143  case '6':
9144  case '7':
9145  case '8':
9146  case '9':
9147  {
9148  add(current);
9149  goto scan_number_decimal2;
9150  }
9151 
9152  case 'e':
9153  case 'E':
9154  {
9155  add(current);
9156  goto scan_number_exponent;
9157  }
9158 
9159  default:
9160  goto scan_number_done;
9161  }
9162 
9163 scan_number_exponent:
9164  // we just parsed an exponent
9165  number_type = token_type::value_float;
9166  switch (get())
9167  {
9168  case '+':
9169  case '-':
9170  {
9171  add(current);
9172  goto scan_number_sign;
9173  }
9174 
9175  case '0':
9176  case '1':
9177  case '2':
9178  case '3':
9179  case '4':
9180  case '5':
9181  case '6':
9182  case '7':
9183  case '8':
9184  case '9':
9185  {
9186  add(current);
9187  goto scan_number_any2;
9188  }
9189 
9190  default:
9191  {
9192  error_message =
9193  "invalid number; expected '+', '-', or digit after exponent";
9194  return token_type::parse_error;
9195  }
9196  }
9197 
9198 scan_number_sign:
9199  // we just parsed an exponent sign
9200  switch (get())
9201  {
9202  case '0':
9203  case '1':
9204  case '2':
9205  case '3':
9206  case '4':
9207  case '5':
9208  case '6':
9209  case '7':
9210  case '8':
9211  case '9':
9212  {
9213  add(current);
9214  goto scan_number_any2;
9215  }
9216 
9217  default:
9218  {
9219  error_message = "invalid number; expected digit after exponent sign";
9220  return token_type::parse_error;
9221  }
9222  }
9223 
9224 scan_number_any2:
9225  // we just parsed a number after the exponent or exponent sign
9226  switch (get())
9227  {
9228  case '0':
9229  case '1':
9230  case '2':
9231  case '3':
9232  case '4':
9233  case '5':
9234  case '6':
9235  case '7':
9236  case '8':
9237  case '9':
9238  {
9239  add(current);
9240  goto scan_number_any2;
9241  }
9242 
9243  default:
9244  goto scan_number_done;
9245  }
9246 
9247 scan_number_done:
9248  // unget the character after the number (we only read it to know that
9249  // we are done scanning a number)
9250  unget();
9251 
9252  char* endptr = nullptr;
9253  errno = 0;
9254 
9255  // try to parse integers first and fall back to floats
9256  if (number_type == token_type::value_unsigned)
9257  {
9258  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
9259 
9260  // we checked the number format before
9261  assert(endptr == token_buffer.data() + token_buffer.size());
9262 
9263  if (errno == 0)
9264  {
9265  value_unsigned = static_cast<number_unsigned_t>(x);
9266  if (value_unsigned == x)
9267  {
9268  return token_type::value_unsigned;
9269  }
9270  }
9271  }
9272  else if (number_type == token_type::value_integer)
9273  {
9274  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
9275 
9276  // we checked the number format before
9277  assert(endptr == token_buffer.data() + token_buffer.size());
9278 
9279  if (errno == 0)
9280  {
9281  value_integer = static_cast<number_integer_t>(x);
9282  if (value_integer == x)
9283  {
9284  return token_type::value_integer;
9285  }
9286  }
9287  }
9288 
9289  // this code is reached if we parse a floating-point number or if an
9290  // integer conversion above failed
9291  strtof(value_float, token_buffer.data(), &endptr);
9292 
9293  // we checked the number format before
9294  assert(endptr == token_buffer.data() + token_buffer.size());
9295 
9296  return token_type::value_float;
9297  }
9298 
9304  JSON_HEDLEY_NON_NULL(2)
9305  token_type scan_literal(const char* literal_text, const std::size_t length,
9306  token_type return_type)
9307  {
9308  assert(current == literal_text[0]);
9309  for (std::size_t i = 1; i < length; ++i)
9310  {
9311  if (JSON_HEDLEY_UNLIKELY(get() != literal_text[i]))
9312  {
9313  error_message = "invalid literal";
9314  return token_type::parse_error;
9315  }
9316  }
9317  return return_type;
9318  }
9319 
9321  // input management
9323 
9325  void reset() noexcept
9326  {
9327  token_buffer.clear();
9328  token_string.clear();
9329  token_string.push_back(std::char_traits<char>::to_char_type(current));
9330  }
9331 
9332  /*
9333  @brief get next character from the input
9334 
9335  This function provides the interface to the used input adapter. It does
9336  not throw in case the input reached EOF, but returns a
9337  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
9338  for use in error messages.
9339 
9340  @return character read from the input
9341  */
9342  std::char_traits<char>::int_type get()
9343  {
9344  ++position.chars_read_total;
9345  ++position.chars_read_current_line;
9346 
9347  if (next_unget)
9348  {
9349  // just reset the next_unget variable and work with current
9350  next_unget = false;
9351  }
9352  else
9353  {
9354  current = ia.get_character();
9355  }
9356 
9357  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
9358  {
9359  token_string.push_back(std::char_traits<char>::to_char_type(current));
9360  }
9361 
9362  if (current == '\n')
9363  {
9364  ++position.lines_read;
9365  position.chars_read_current_line = 0;
9366  }
9367 
9368  return current;
9369  }
9370 
9379  void unget()
9380  {
9381  next_unget = true;
9382 
9383  --position.chars_read_total;
9384 
9385  // in case we "unget" a newline, we have to also decrement the lines_read
9386  if (position.chars_read_current_line == 0)
9387  {
9388  if (position.lines_read > 0)
9389  {
9390  --position.lines_read;
9391  }
9392  }
9393  else
9394  {
9395  --position.chars_read_current_line;
9396  }
9397 
9398  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char>::eof()))
9399  {
9400  assert(not token_string.empty());
9401  token_string.pop_back();
9402  }
9403  }
9404 
9406  void add(int c)
9407  {
9408  token_buffer.push_back(std::char_traits<char>::to_char_type(c));
9409  }
9410 
9411  public:
9413  // value getters
9415 
9417  constexpr number_integer_t get_number_integer() const noexcept
9418  {
9419  return value_integer;
9420  }
9421 
9423  constexpr number_unsigned_t get_number_unsigned() const noexcept
9424  {
9425  return value_unsigned;
9426  }
9427 
9429  constexpr number_float_t get_number_float() const noexcept
9430  {
9431  return value_float;
9432  }
9433 
9435  string_t& get_string()
9436  {
9437  return token_buffer;
9438  }
9439 
9441  // diagnostics
9443 
9445  constexpr position_t get_position() const noexcept
9446  {
9447  return position;
9448  }
9449 
9453  std::string get_token_string() const
9454  {
9455  // escape control characters
9456  std::string result;
9457  for (const auto c : token_string)
9458  {
9459  if ('\x00' <= c and c <= '\x1F')
9460  {
9461  // escape control characters
9462  std::array<char, 9> cs{{}};
9463  (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
9464  result += cs.data();
9465  }
9466  else
9467  {
9468  // add character as is
9469  result.push_back(c);
9470  }
9471  }
9472 
9473  return result;
9474  }
9475 
9477 
9478  constexpr const char* get_error_message() const noexcept
9479  {
9480  return error_message;
9481  }
9482 
9484  // actual scanner
9486 
9491  bool skip_bom()
9492  {
9493  if (get() == 0xEF)
9494  {
9495  // check if we completely parse the BOM
9496  return get() == 0xBB and get() == 0xBF;
9497  }
9498 
9499  // the first character is not the beginning of the BOM; unget it to
9500  // process is later
9501  unget();
9502  return true;
9503  }
9504 
9505  token_type scan()
9506  {
9507  // initially, skip the BOM
9508  if (position.chars_read_total == 0 and not skip_bom())
9509  {
9510  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
9511  return token_type::parse_error;
9512  }
9513 
9514  // read next character and ignore whitespace
9515  do
9516  {
9517  get();
9518  }
9519  while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
9520 
9521  switch (current)
9522  {
9523  // structural characters
9524  case '[':
9525  return token_type::begin_array;
9526  case ']':
9527  return token_type::end_array;
9528  case '{':
9529  return token_type::begin_object;
9530  case '}':
9531  return token_type::end_object;
9532  case ':':
9533  return token_type::name_separator;
9534  case ',':
9535  return token_type::value_separator;
9536 
9537  // literals
9538  case 't':
9539  return scan_literal("true", 4, token_type::literal_true);
9540  case 'f':
9541  return scan_literal("false", 5, token_type::literal_false);
9542  case 'n':
9543  return scan_literal("null", 4, token_type::literal_null);
9544 
9545  // string
9546  case '\"':
9547  return scan_string();
9548 
9549  // number
9550  case '-':
9551  case '0':
9552  case '1':
9553  case '2':
9554  case '3':
9555  case '4':
9556  case '5':
9557  case '6':
9558  case '7':
9559  case '8':
9560  case '9':
9561  return scan_number();
9562 
9563  // end of input (the null byte is needed when parsing from
9564  // string literals)
9565  case '\0':
9566  case std::char_traits<char>::eof():
9567  return token_type::end_of_input;
9568 
9569  // error
9570  default:
9571  error_message = "invalid literal";
9572  return token_type::parse_error;
9573  }
9574  }
9575 
9576  private:
9578  InputAdapterType ia;
9579 
9581  std::char_traits<char>::int_type current = std::char_traits<char>::eof();
9582 
9584  bool next_unget = false;
9585 
9587  position_t position {};
9588 
9590  std::vector<char> token_string {};
9591 
9593  string_t token_buffer {};
9594 
9596  const char* error_message = "";
9597 
9598  // number values
9599  number_integer_t value_integer = 0;
9600  number_unsigned_t value_unsigned = 0;
9601  number_float_t value_float = 0;
9602 
9604  const char decimal_point_char = '.';
9605 };
9606 } // namespace detail
9607 } // namespace nlohmann
9608 
9609 // #include <nlohmann/detail/input/parser.hpp>
9610 
9611 
9612 #include <cassert> // assert
9613 #include <cmath> // isfinite
9614 #include <cstdint> // uint8_t
9615 #include <functional> // function
9616 #include <string> // string
9617 #include <utility> // move
9618 #include <vector> // vector
9619 
9620 // #include <nlohmann/detail/exceptions.hpp>
9621 
9622 // #include <nlohmann/detail/input/input_adapters.hpp>
9623 
9624 // #include <nlohmann/detail/input/json_sax.hpp>
9625 
9626 // #include <nlohmann/detail/input/lexer.hpp>
9627 
9628 // #include <nlohmann/detail/macro_scope.hpp>
9629 
9630 // #include <nlohmann/detail/meta/is_sax.hpp>
9631 
9632 // #include <nlohmann/detail/value_t.hpp>
9633 
9634 
9635 namespace nlohmann
9636 {
9637 namespace detail
9638 {
9640 // parser //
9642 
9643 enum class parse_event_t : uint8_t
9644 {
9646  object_start,
9648  object_end,
9650  array_start,
9652  array_end,
9654  key,
9656  value
9657 };
9658 
9659 template<typename BasicJsonType>
9660 using parser_callback_t =
9661  std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
9662 
9668 template<typename BasicJsonType, typename InputAdapterType>
9669 class parser
9670 {
9671  using number_integer_t = typename BasicJsonType::number_integer_t;
9672  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
9673  using number_float_t = typename BasicJsonType::number_float_t;
9674  using string_t = typename BasicJsonType::string_t;
9675  using lexer_t = lexer<BasicJsonType, InputAdapterType>;
9676  using token_type = typename lexer_t::token_type;
9677 
9678  public:
9680  explicit parser(InputAdapterType&& adapter,
9681  const parser_callback_t<BasicJsonType> cb = nullptr,
9682  const bool allow_exceptions_ = true)
9683  : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
9684  {
9685  // read first token
9686  get_token();
9687  }
9688 
9699  void parse(const bool strict, BasicJsonType& result)
9700  {
9701  if (callback)
9702  {
9703  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
9704  sax_parse_internal(&sdp);
9705  result.assert_invariant();
9706 
9707  // in strict mode, input must be completely read
9708  if (strict and (get_token() != token_type::end_of_input))
9709  {
9710  sdp.parse_error(m_lexer.get_position(),
9711  m_lexer.get_token_string(),
9712  parse_error::create(101, m_lexer.get_position(),
9713  exception_message(token_type::end_of_input, "value")));
9714  }
9715 
9716  // in case of an error, return discarded value
9717  if (sdp.is_errored())
9718  {
9719  result = value_t::discarded;
9720  return;
9721  }
9722 
9723  // set top-level value to null if it was discarded by the callback
9724  // function
9725  if (result.is_discarded())
9726  {
9727  result = nullptr;
9728  }
9729  }
9730  else
9731  {
9732  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
9733  sax_parse_internal(&sdp);
9734  result.assert_invariant();
9735 
9736  // in strict mode, input must be completely read
9737  if (strict and (get_token() != token_type::end_of_input))
9738  {
9739  sdp.parse_error(m_lexer.get_position(),
9740  m_lexer.get_token_string(),
9741  parse_error::create(101, m_lexer.get_position(),
9742  exception_message(token_type::end_of_input, "value")));
9743  }
9744 
9745  // in case of an error, return discarded value
9746  if (sdp.is_errored())
9747  {
9748  result = value_t::discarded;
9749  return;
9750  }
9751  }
9752  }
9753 
9760  bool accept(const bool strict = true)
9761  {
9762  json_sax_acceptor<BasicJsonType> sax_acceptor;
9763  return sax_parse(&sax_acceptor, strict);
9764  }
9765 
9766  template <typename SAX>
9767  JSON_HEDLEY_NON_NULL(2)
9768  bool sax_parse(SAX* sax, const bool strict = true)
9769  {
9770  (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
9771  const bool result = sax_parse_internal(sax);
9772 
9773  // strict mode: next byte must be EOF
9774  if (result and strict and (get_token() != token_type::end_of_input))
9775  {
9776  return sax->parse_error(m_lexer.get_position(),
9777  m_lexer.get_token_string(),
9778  parse_error::create(101, m_lexer.get_position(),
9779  exception_message(token_type::end_of_input, "value")));
9780  }
9781 
9782  return result;
9783  }
9784 
9785  private:
9786  template <typename SAX>
9787  JSON_HEDLEY_NON_NULL(2)
9788  bool sax_parse_internal(SAX* sax)
9789  {
9790  // stack to remember the hierarchy of structured values we are parsing
9791  // true = array; false = object
9792  std::vector<bool> states;
9793  // value to avoid a goto (see comment where set to true)
9794  bool skip_to_state_evaluation = false;
9795 
9796  while (true)
9797  {
9798  if (not skip_to_state_evaluation)
9799  {
9800  // invariant: get_token() was called before each iteration
9801  switch (last_token)
9802  {
9803  case token_type::begin_object:
9804  {
9805  if (JSON_HEDLEY_UNLIKELY(not sax->start_object(std::size_t(-1))))
9806  {
9807  return false;
9808  }
9809 
9810  // closing } -> we are done
9811  if (get_token() == token_type::end_object)
9812  {
9813  if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
9814  {
9815  return false;
9816  }
9817  break;
9818  }
9819 
9820  // parse key
9821  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
9822  {
9823  return sax->parse_error(m_lexer.get_position(),
9824  m_lexer.get_token_string(),
9825  parse_error::create(101, m_lexer.get_position(),
9826  exception_message(token_type::value_string, "object key")));
9827  }
9828  if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
9829  {
9830  return false;
9831  }
9832 
9833  // parse separator (:)
9834  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
9835  {
9836  return sax->parse_error(m_lexer.get_position(),
9837  m_lexer.get_token_string(),
9838  parse_error::create(101, m_lexer.get_position(),
9839  exception_message(token_type::name_separator, "object separator")));
9840  }
9841 
9842  // remember we are now inside an object
9843  states.push_back(false);
9844 
9845  // parse values
9846  get_token();
9847  continue;
9848  }
9849 
9850  case token_type::begin_array:
9851  {
9852  if (JSON_HEDLEY_UNLIKELY(not sax->start_array(std::size_t(-1))))
9853  {
9854  return false;
9855  }
9856 
9857  // closing ] -> we are done
9858  if (get_token() == token_type::end_array)
9859  {
9860  if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9861  {
9862  return false;
9863  }
9864  break;
9865  }
9866 
9867  // remember we are now inside an array
9868  states.push_back(true);
9869 
9870  // parse values (no need to call get_token)
9871  continue;
9872  }
9873 
9874  case token_type::value_float:
9875  {
9876  const auto res = m_lexer.get_number_float();
9877 
9878  if (JSON_HEDLEY_UNLIKELY(not std::isfinite(res)))
9879  {
9880  return sax->parse_error(m_lexer.get_position(),
9881  m_lexer.get_token_string(),
9882  out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
9883  }
9884 
9885  if (JSON_HEDLEY_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
9886  {
9887  return false;
9888  }
9889 
9890  break;
9891  }
9892 
9893  case token_type::literal_false:
9894  {
9895  if (JSON_HEDLEY_UNLIKELY(not sax->boolean(false)))
9896  {
9897  return false;
9898  }
9899  break;
9900  }
9901 
9902  case token_type::literal_null:
9903  {
9904  if (JSON_HEDLEY_UNLIKELY(not sax->null()))
9905  {
9906  return false;
9907  }
9908  break;
9909  }
9910 
9911  case token_type::literal_true:
9912  {
9913  if (JSON_HEDLEY_UNLIKELY(not sax->boolean(true)))
9914  {
9915  return false;
9916  }
9917  break;
9918  }
9919 
9920  case token_type::value_integer:
9921  {
9922  if (JSON_HEDLEY_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
9923  {
9924  return false;
9925  }
9926  break;
9927  }
9928 
9929  case token_type::value_string:
9930  {
9931  if (JSON_HEDLEY_UNLIKELY(not sax->string(m_lexer.get_string())))
9932  {
9933  return false;
9934  }
9935  break;
9936  }
9937 
9938  case token_type::value_unsigned:
9939  {
9940  if (JSON_HEDLEY_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
9941  {
9942  return false;
9943  }
9944  break;
9945  }
9946 
9947  case token_type::parse_error:
9948  {
9949  // using "uninitialized" to avoid "expected" message
9950  return sax->parse_error(m_lexer.get_position(),
9951  m_lexer.get_token_string(),
9952  parse_error::create(101, m_lexer.get_position(),
9953  exception_message(token_type::uninitialized, "value")));
9954  }
9955 
9956  default: // the last token was unexpected
9957  {
9958  return sax->parse_error(m_lexer.get_position(),
9959  m_lexer.get_token_string(),
9960  parse_error::create(101, m_lexer.get_position(),
9961  exception_message(token_type::literal_or_value, "value")));
9962  }
9963  }
9964  }
9965  else
9966  {
9967  skip_to_state_evaluation = false;
9968  }
9969 
9970  // we reached this line after we successfully parsed a value
9971  if (states.empty())
9972  {
9973  // empty stack: we reached the end of the hierarchy: done
9974  return true;
9975  }
9976 
9977  if (states.back()) // array
9978  {
9979  // comma -> next value
9980  if (get_token() == token_type::value_separator)
9981  {
9982  // parse a new value
9983  get_token();
9984  continue;
9985  }
9986 
9987  // closing ]
9988  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
9989  {
9990  if (JSON_HEDLEY_UNLIKELY(not sax->end_array()))
9991  {
9992  return false;
9993  }
9994 
9995  // We are done with this array. Before we can parse a
9996  // new value, we need to evaluate the new state first.
9997  // By setting skip_to_state_evaluation to false, we
9998  // are effectively jumping to the beginning of this if.
9999  assert(not states.empty());
10000  states.pop_back();
10001  skip_to_state_evaluation = true;
10002  continue;
10003  }
10004 
10005  return sax->parse_error(m_lexer.get_position(),
10006  m_lexer.get_token_string(),
10007  parse_error::create(101, m_lexer.get_position(),
10008  exception_message(token_type::end_array, "array")));
10009  }
10010  else // object
10011  {
10012  // comma -> next value
10013  if (get_token() == token_type::value_separator)
10014  {
10015  // parse key
10016  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10017  {
10018  return sax->parse_error(m_lexer.get_position(),
10019  m_lexer.get_token_string(),
10020  parse_error::create(101, m_lexer.get_position(),
10021  exception_message(token_type::value_string, "object key")));
10022  }
10023 
10024  if (JSON_HEDLEY_UNLIKELY(not sax->key(m_lexer.get_string())))
10025  {
10026  return false;
10027  }
10028 
10029  // parse separator (:)
10030  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10031  {
10032  return sax->parse_error(m_lexer.get_position(),
10033  m_lexer.get_token_string(),
10034  parse_error::create(101, m_lexer.get_position(),
10035  exception_message(token_type::name_separator, "object separator")));
10036  }
10037 
10038  // parse values
10039  get_token();
10040  continue;
10041  }
10042 
10043  // closing }
10044  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10045  {
10046  if (JSON_HEDLEY_UNLIKELY(not sax->end_object()))
10047  {
10048  return false;
10049  }
10050 
10051  // We are done with this object. Before we can parse a
10052  // new value, we need to evaluate the new state first.
10053  // By setting skip_to_state_evaluation to false, we
10054  // are effectively jumping to the beginning of this if.
10055  assert(not states.empty());
10056  states.pop_back();
10057  skip_to_state_evaluation = true;
10058  continue;
10059  }
10060 
10061  return sax->parse_error(m_lexer.get_position(),
10062  m_lexer.get_token_string(),
10063  parse_error::create(101, m_lexer.get_position(),
10064  exception_message(token_type::end_object, "object")));
10065  }
10066  }
10067  }
10068 
10070  token_type get_token()
10071  {
10072  return last_token = m_lexer.scan();
10073  }
10074 
10075  std::string exception_message(const token_type expected, const std::string& context)
10076  {
10077  std::string error_msg = "syntax error ";
10078 
10079  if (not context.empty())
10080  {
10081  error_msg += "while parsing " + context + " ";
10082  }
10083 
10084  error_msg += "- ";
10085 
10086  if (last_token == token_type::parse_error)
10087  {
10088  error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10089  m_lexer.get_token_string() + "'";
10090  }
10091  else
10092  {
10093  error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10094  }
10095 
10096  if (expected != token_type::uninitialized)
10097  {
10098  error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10099  }
10100 
10101  return error_msg;
10102  }
10103 
10104  private:
10106  const parser_callback_t<BasicJsonType> callback = nullptr;
10108  token_type last_token = token_type::uninitialized;
10110  lexer_t m_lexer;
10112  const bool allow_exceptions = true;
10113 };
10114 } // namespace detail
10115 } // namespace nlohmann
10116 
10117 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10118 
10119 
10120 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10121 
10122 
10123 #include <cstddef> // ptrdiff_t
10124 #include <limits> // numeric_limits
10125 
10126 namespace nlohmann
10127 {
10128 namespace detail
10129 {
10130 /*
10131 @brief an iterator for primitive JSON types
10132 
10133 This class models an iterator for primitive JSON types (boolean, number,
10134 string). It's only purpose is to allow the iterator/const_iterator classes
10135 to "iterate" over primitive values. Internally, the iterator is modeled by
10136 a `difference_type` variable. Value begin_value (`0`) models the begin,
10137 end_value (`1`) models past the end.
10138 */
10139 class primitive_iterator_t
10140 {
10141  private:
10142  using difference_type = std::ptrdiff_t;
10143  static constexpr difference_type begin_value = 0;
10144  static constexpr difference_type end_value = begin_value + 1;
10145 
10147  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10148 
10149  public:
10150  constexpr difference_type get_value() const noexcept
10151  {
10152  return m_it;
10153  }
10154 
10156  void set_begin() noexcept
10157  {
10158  m_it = begin_value;
10159  }
10160 
10162  void set_end() noexcept
10163  {
10164  m_it = end_value;
10165  }
10166 
10168  constexpr bool is_begin() const noexcept
10169  {
10170  return m_it == begin_value;
10171  }
10172 
10174  constexpr bool is_end() const noexcept
10175  {
10176  return m_it == end_value;
10177  }
10178 
10179  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10180  {
10181  return lhs.m_it == rhs.m_it;
10182  }
10183 
10184  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10185  {
10186  return lhs.m_it < rhs.m_it;
10187  }
10188 
10189  primitive_iterator_t operator+(difference_type n) noexcept
10190  {
10191  auto result = *this;
10192  result += n;
10193  return result;
10194  }
10195 
10196  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10197  {
10198  return lhs.m_it - rhs.m_it;
10199  }
10200 
10201  primitive_iterator_t& operator++() noexcept
10202  {
10203  ++m_it;
10204  return *this;
10205  }
10206 
10207  primitive_iterator_t const operator++(int) noexcept
10208  {
10209  auto result = *this;
10210  ++m_it;
10211  return result;
10212  }
10213 
10214  primitive_iterator_t& operator--() noexcept
10215  {
10216  --m_it;
10217  return *this;
10218  }
10219 
10220  primitive_iterator_t const operator--(int) noexcept
10221  {
10222  auto result = *this;
10223  --m_it;
10224  return result;
10225  }
10226 
10227  primitive_iterator_t& operator+=(difference_type n) noexcept
10228  {
10229  m_it += n;
10230  return *this;
10231  }
10232 
10233  primitive_iterator_t& operator-=(difference_type n) noexcept
10234  {
10235  m_it -= n;
10236  return *this;
10237  }
10238 };
10239 } // namespace detail
10240 } // namespace nlohmann
10241 
10242 
10243 namespace nlohmann
10244 {
10245 namespace detail
10246 {
10253 template<typename BasicJsonType> struct internal_iterator
10254 {
10256  typename BasicJsonType::object_t::iterator object_iterator {};
10258  typename BasicJsonType::array_t::iterator array_iterator {};
10260  typename BasicJsonType::binary_t::container_type::iterator binary_iterator {};
10262  primitive_iterator_t primitive_iterator {};
10263 };
10264 } // namespace detail
10265 } // namespace nlohmann
10266 
10267 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10268 
10269 
10270 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10271 #include <type_traits> // conditional, is_const, remove_const
10272 
10273 // #include <nlohmann/detail/boolean_operators.hpp>
10274 
10275 // #include <nlohmann/detail/exceptions.hpp>
10276 
10277 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10278 
10279 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10280 
10281 // #include <nlohmann/detail/macro_scope.hpp>
10282 
10283 // #include <nlohmann/detail/meta/cpp_future.hpp>
10284 
10285 // #include <nlohmann/detail/meta/type_traits.hpp>
10286 
10287 // #include <nlohmann/detail/value_t.hpp>
10288 
10289 
10290 namespace nlohmann
10291 {
10292 namespace detail
10293 {
10294 // forward declare, to be able to friend it later on
10295 template<typename IteratorType> class iteration_proxy;
10296 template<typename IteratorType> class iteration_proxy_value;
10297 
10314 template<typename BasicJsonType>
10315 class iter_impl
10316 {
10318  friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10319  friend BasicJsonType;
10320  friend iteration_proxy<iter_impl>;
10321  friend iteration_proxy_value<iter_impl>;
10322 
10323  using object_t = typename BasicJsonType::object_t;
10324  using array_t = typename BasicJsonType::array_t;
10325  // make sure BasicJsonType is basic_json or const basic_json
10326  static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10327  "iter_impl only accepts (const) basic_json");
10328 
10329  public:
10330 
10336  using iterator_category = std::bidirectional_iterator_tag;
10337 
10339  using value_type = typename BasicJsonType::value_type;
10341  using difference_type = typename BasicJsonType::difference_type;
10343  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10344  typename BasicJsonType::const_pointer,
10345  typename BasicJsonType::pointer>::type;
10347  using reference =
10348  typename std::conditional<std::is_const<BasicJsonType>::value,
10349  typename BasicJsonType::const_reference,
10350  typename BasicJsonType::reference>::type;
10351 
10353  iter_impl() = default;
10354 
10361  explicit iter_impl(pointer object) noexcept : m_object(object)
10362  {
10363  assert(m_object != nullptr);
10364 
10365  switch (m_object->m_type)
10366  {
10367  case value_t::object:
10368  {
10369  m_it.object_iterator = typename object_t::iterator();
10370  break;
10371  }
10372 
10373  case value_t::array:
10374  {
10375  m_it.array_iterator = typename array_t::iterator();
10376  break;
10377  }
10378 
10379  default:
10380  {
10381  m_it.primitive_iterator = primitive_iterator_t();
10382  break;
10383  }
10384  }
10385  }
10386 
10403  iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10404  : m_object(other.m_object), m_it(other.m_it)
10405  {}
10406 
10413  iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10414  {
10415  m_object = other.m_object;
10416  m_it = other.m_it;
10417  return *this;
10418  }
10419 
10425  iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10426  : m_object(other.m_object), m_it(other.m_it)
10427  {}
10428 
10435  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10436  {
10437  m_object = other.m_object;
10438  m_it = other.m_it;
10439  return *this;
10440  }
10441 
10442  private:
10447  void set_begin() noexcept
10448  {
10449  assert(m_object != nullptr);
10450 
10451  switch (m_object->m_type)
10452  {
10453  case value_t::object:
10454  {
10455  m_it.object_iterator = m_object->m_value.object->begin();
10456  break;
10457  }
10458 
10459  case value_t::array:
10460  {
10461  m_it.array_iterator = m_object->m_value.array->begin();
10462  break;
10463  }
10464 
10465  case value_t::null:
10466  {
10467  // set to end so begin()==end() is true: null is empty
10468  m_it.primitive_iterator.set_end();
10469  break;
10470  }
10471 
10472  default:
10473  {
10474  m_it.primitive_iterator.set_begin();
10475  break;
10476  }
10477  }
10478  }
10479 
10484  void set_end() noexcept
10485  {
10486  assert(m_object != nullptr);
10487 
10488  switch (m_object->m_type)
10489  {
10490  case value_t::object:
10491  {
10492  m_it.object_iterator = m_object->m_value.object->end();
10493  break;
10494  }
10495 
10496  case value_t::array:
10497  {
10498  m_it.array_iterator = m_object->m_value.array->end();
10499  break;
10500  }
10501 
10502  default:
10503  {
10504  m_it.primitive_iterator.set_end();
10505  break;
10506  }
10507  }
10508  }
10509 
10510  public:
10515  reference operator*() const
10516  {
10517  assert(m_object != nullptr);
10518 
10519  switch (m_object->m_type)
10520  {
10521  case value_t::object:
10522  {
10523  assert(m_it.object_iterator != m_object->m_value.object->end());
10524  return m_it.object_iterator->second;
10525  }
10526 
10527  case value_t::array:
10528  {
10529  assert(m_it.array_iterator != m_object->m_value.array->end());
10530  return *m_it.array_iterator;
10531  }
10532 
10533  case value_t::null:
10534  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10535 
10536  default:
10537  {
10538  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10539  {
10540  return *m_object;
10541  }
10542 
10543  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10544  }
10545  }
10546  }
10547 
10552  pointer operator->() const
10553  {
10554  assert(m_object != nullptr);
10555 
10556  switch (m_object->m_type)
10557  {
10558  case value_t::object:
10559  {
10560  assert(m_it.object_iterator != m_object->m_value.object->end());
10561  return &(m_it.object_iterator->second);
10562  }
10563 
10564  case value_t::array:
10565  {
10566  assert(m_it.array_iterator != m_object->m_value.array->end());
10567  return &*m_it.array_iterator;
10568  }
10569 
10570  default:
10571  {
10572  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
10573  {
10574  return m_object;
10575  }
10576 
10577  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10578  }
10579  }
10580  }
10581 
10586  iter_impl const operator++(int)
10587  {
10588  auto result = *this;
10589  ++(*this);
10590  return result;
10591  }
10592 
10597  iter_impl& operator++()
10598  {
10599  assert(m_object != nullptr);
10600 
10601  switch (m_object->m_type)
10602  {
10603  case value_t::object:
10604  {
10605  std::advance(m_it.object_iterator, 1);
10606  break;
10607  }
10608 
10609  case value_t::array:
10610  {
10611  std::advance(m_it.array_iterator, 1);
10612  break;
10613  }
10614 
10615  default:
10616  {
10617  ++m_it.primitive_iterator;
10618  break;
10619  }
10620  }
10621 
10622  return *this;
10623  }
10624 
10629  iter_impl const operator--(int)
10630  {
10631  auto result = *this;
10632  --(*this);
10633  return result;
10634  }
10635 
10640  iter_impl& operator--()
10641  {
10642  assert(m_object != nullptr);
10643 
10644  switch (m_object->m_type)
10645  {
10646  case value_t::object:
10647  {
10648  std::advance(m_it.object_iterator, -1);
10649  break;
10650  }
10651 
10652  case value_t::array:
10653  {
10654  std::advance(m_it.array_iterator, -1);
10655  break;
10656  }
10657 
10658  default:
10659  {
10660  --m_it.primitive_iterator;
10661  break;
10662  }
10663  }
10664 
10665  return *this;
10666  }
10667 
10672  bool operator==(const iter_impl& other) const
10673  {
10674  // if objects are not the same, the comparison is undefined
10675  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10676  {
10677  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10678  }
10679 
10680  assert(m_object != nullptr);
10681 
10682  switch (m_object->m_type)
10683  {
10684  case value_t::object:
10685  return (m_it.object_iterator == other.m_it.object_iterator);
10686 
10687  case value_t::array:
10688  return (m_it.array_iterator == other.m_it.array_iterator);
10689 
10690  default:
10691  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
10692  }
10693  }
10694 
10699  bool operator!=(const iter_impl& other) const
10700  {
10701  return not operator==(other);
10702  }
10703 
10708  bool operator<(const iter_impl& other) const
10709  {
10710  // if objects are not the same, the comparison is undefined
10711  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
10712  {
10713  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
10714  }
10715 
10716  assert(m_object != nullptr);
10717 
10718  switch (m_object->m_type)
10719  {
10720  case value_t::object:
10721  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
10722 
10723  case value_t::array:
10724  return (m_it.array_iterator < other.m_it.array_iterator);
10725 
10726  default:
10727  return (m_it.primitive_iterator < other.m_it.primitive_iterator);
10728  }
10729  }
10730 
10735  bool operator<=(const iter_impl& other) const
10736  {
10737  return not other.operator < (*this);
10738  }
10739 
10744  bool operator>(const iter_impl& other) const
10745  {
10746  return not operator<=(other);
10747  }
10748 
10753  bool operator>=(const iter_impl& other) const
10754  {
10755  return not operator<(other);
10756  }
10757 
10762  iter_impl& operator+=(difference_type i)
10763  {
10764  assert(m_object != nullptr);
10765 
10766  switch (m_object->m_type)
10767  {
10768  case value_t::object:
10769  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10770 
10771  case value_t::array:
10772  {
10773  std::advance(m_it.array_iterator, i);
10774  break;
10775  }
10776 
10777  default:
10778  {
10779  m_it.primitive_iterator += i;
10780  break;
10781  }
10782  }
10783 
10784  return *this;
10785  }
10786 
10791  iter_impl& operator-=(difference_type i)
10792  {
10793  return operator+=(-i);
10794  }
10795 
10800  iter_impl operator+(difference_type i) const
10801  {
10802  auto result = *this;
10803  result += i;
10804  return result;
10805  }
10806 
10811  friend iter_impl operator+(difference_type i, const iter_impl& it)
10812  {
10813  auto result = it;
10814  result += i;
10815  return result;
10816  }
10817 
10822  iter_impl operator-(difference_type i) const
10823  {
10824  auto result = *this;
10825  result -= i;
10826  return result;
10827  }
10828 
10833  difference_type operator-(const iter_impl& other) const
10834  {
10835  assert(m_object != nullptr);
10836 
10837  switch (m_object->m_type)
10838  {
10839  case value_t::object:
10840  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
10841 
10842  case value_t::array:
10843  return m_it.array_iterator - other.m_it.array_iterator;
10844 
10845  default:
10846  return m_it.primitive_iterator - other.m_it.primitive_iterator;
10847  }
10848  }
10849 
10854  reference operator[](difference_type n) const
10855  {
10856  assert(m_object != nullptr);
10857 
10858  switch (m_object->m_type)
10859  {
10860  case value_t::object:
10861  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
10862 
10863  case value_t::array:
10864  return *std::next(m_it.array_iterator, n);
10865 
10866  case value_t::null:
10867  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10868 
10869  default:
10870  {
10871  if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
10872  {
10873  return *m_object;
10874  }
10875 
10876  JSON_THROW(invalid_iterator::create(214, "cannot get value"));
10877  }
10878  }
10879  }
10880 
10885  const typename object_t::key_type& key() const
10886  {
10887  assert(m_object != nullptr);
10888 
10889  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
10890  {
10891  return m_it.object_iterator->first;
10892  }
10893 
10894  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
10895  }
10896 
10901  reference value() const
10902  {
10903  return operator*();
10904  }
10905 
10906  private:
10908  pointer m_object = nullptr;
10910  internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
10911 };
10912 } // namespace detail
10913 } // namespace nlohmann
10914 
10915 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
10916 
10917 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
10918 
10919 
10920 #include <cstddef> // ptrdiff_t
10921 #include <iterator> // reverse_iterator
10922 #include <utility> // declval
10923 
10924 namespace nlohmann
10925 {
10926 namespace detail
10927 {
10929 // reverse_iterator //
10931 
10950 template<typename Base>
10951 class json_reverse_iterator : public std::reverse_iterator<Base>
10952 {
10953  public:
10954  using difference_type = std::ptrdiff_t;
10956  using base_iterator = std::reverse_iterator<Base>;
10958  using reference = typename Base::reference;
10959 
10961  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
10962  : base_iterator(it) {}
10963 
10965  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
10966 
10968  json_reverse_iterator const operator++(int)
10969  {
10970  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
10971  }
10972 
10974  json_reverse_iterator& operator++()
10975  {
10976  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
10977  }
10978 
10980  json_reverse_iterator const operator--(int)
10981  {
10982  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
10983  }
10984 
10986  json_reverse_iterator& operator--()
10987  {
10988  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
10989  }
10990 
10992  json_reverse_iterator& operator+=(difference_type i)
10993  {
10994  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
10995  }
10996 
10998  json_reverse_iterator operator+(difference_type i) const
10999  {
11000  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11001  }
11002 
11004  json_reverse_iterator operator-(difference_type i) const
11005  {
11006  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11007  }
11008 
11010  difference_type operator-(const json_reverse_iterator& other) const
11011  {
11012  return base_iterator(*this) - base_iterator(other);
11013  }
11014 
11016  reference operator[](difference_type n) const
11017  {
11018  return *(this->operator+(n));
11019  }
11020 
11022  auto key() const -> decltype(std::declval<Base>().key())
11023  {
11024  auto it = --this->base();
11025  return it.key();
11026  }
11027 
11029  reference value() const
11030  {
11031  auto it = --this->base();
11032  return it.operator * ();
11033  }
11034 };
11035 } // namespace detail
11036 } // namespace nlohmann
11037 
11038 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11039 
11040 // #include <nlohmann/detail/json_pointer.hpp>
11041 
11042 
11043 #include <algorithm> // all_of
11044 #include <cassert> // assert
11045 #include <cctype> // isdigit
11046 #include <numeric> // accumulate
11047 #include <string> // string
11048 #include <utility> // move
11049 #include <vector> // vector
11050 
11051 // #include <nlohmann/detail/exceptions.hpp>
11052 
11053 // #include <nlohmann/detail/macro_scope.hpp>
11054 
11055 // #include <nlohmann/detail/value_t.hpp>
11056 
11057 
11058 namespace nlohmann
11059 {
11060 template<typename BasicJsonType>
11062 {
11063  // allow basic_json to access private members
11064  NLOHMANN_BASIC_JSON_TPL_DECLARATION
11065  friend class basic_json;
11066 
11067  public:
11089  explicit json_pointer(const std::string& s = "")
11090  : reference_tokens(split(s))
11091  {}
11092 
11107  std::string to_string() const
11108  {
11109  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11110  std::string{},
11111  [](const std::string & a, const std::string & b)
11112  {
11113  return a + "/" + escape(b);
11114  });
11115  }
11116 
11118  operator std::string() const
11119  {
11120  return to_string();
11121  }
11122 
11140  {
11141  reference_tokens.insert(reference_tokens.end(),
11142  ptr.reference_tokens.begin(),
11143  ptr.reference_tokens.end());
11144  return *this;
11145  }
11146 
11163  json_pointer& operator/=(std::string token)
11164  {
11165  push_back(std::move(token));
11166  return *this;
11167  }
11168 
11185  json_pointer& operator/=(std::size_t array_idx)
11186  {
11187  return *this /= std::to_string(array_idx);
11188  }
11189 
11206  const json_pointer& rhs)
11207  {
11208  return json_pointer(lhs) /= rhs;
11209  }
11210 
11226  friend json_pointer operator/(const json_pointer& ptr, std::string token)
11227  {
11228  return json_pointer(ptr) /= std::move(token);
11229  }
11230 
11246  friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11247  {
11248  return json_pointer(ptr) /= array_idx;
11249  }
11250 
11265  {
11266  if (empty())
11267  {
11268  return *this;
11269  }
11270 
11271  json_pointer res = *this;
11272  res.pop_back();
11273  return res;
11274  }
11275 
11289  void pop_back()
11290  {
11291  if (JSON_HEDLEY_UNLIKELY(empty()))
11292  {
11293  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11294  }
11295 
11296  reference_tokens.pop_back();
11297  }
11298 
11313  const std::string& back() const
11314  {
11315  if (JSON_HEDLEY_UNLIKELY(empty()))
11316  {
11317  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11318  }
11319 
11320  return reference_tokens.back();
11321  }
11322 
11335  void push_back(const std::string& token)
11336  {
11337  reference_tokens.push_back(token);
11338  }
11339 
11341  void push_back(std::string&& token)
11342  {
11343  reference_tokens.push_back(std::move(token));
11344  }
11345 
11360  bool empty() const noexcept
11361  {
11362  return reference_tokens.empty();
11363  }
11364 
11365  private:
11373  static int array_index(const std::string& s)
11374  {
11375  // error condition (cf. RFC 6901, Sect. 4)
11376  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and s[0] == '0'))
11377  {
11378  JSON_THROW(detail::parse_error::create(106, 0,
11379  "array index '" + s +
11380  "' must not begin with '0'"));
11381  }
11382 
11383  // error condition (cf. RFC 6901, Sect. 4)
11384  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 and not (s[0] >= '1' and s[0] <= '9')))
11385  {
11386  JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11387  }
11388 
11389  std::size_t processed_chars = 0;
11390  int res = 0;
11391  JSON_TRY
11392  {
11393  res = std::stoi(s, &processed_chars);
11394  }
11395  JSON_CATCH(std::out_of_range&)
11396  {
11397  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11398  }
11399 
11400  // check if the string was completely read
11401  if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11402  {
11403  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11404  }
11405 
11406  return res;
11407  }
11408 
11409  json_pointer top() const
11410  {
11411  if (JSON_HEDLEY_UNLIKELY(empty()))
11412  {
11413  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11414  }
11415 
11416  json_pointer result = *this;
11417  result.reference_tokens = {reference_tokens[0]};
11418  return result;
11419  }
11420 
11429  BasicJsonType& get_and_create(BasicJsonType& j) const
11430  {
11431  using size_type = typename BasicJsonType::size_type;
11432  auto result = &j;
11433 
11434  // in case no reference tokens exist, return a reference to the JSON value
11435  // j which will be overwritten by a primitive value
11436  for (const auto& reference_token : reference_tokens)
11437  {
11438  switch (result->type())
11439  {
11440  case detail::value_t::null:
11441  {
11442  if (reference_token == "0")
11443  {
11444  // start a new array if reference token is 0
11445  result = &result->operator[](0);
11446  }
11447  else
11448  {
11449  // start a new object otherwise
11450  result = &result->operator[](reference_token);
11451  }
11452  break;
11453  }
11454 
11455  case detail::value_t::object:
11456  {
11457  // create an entry in the object
11458  result = &result->operator[](reference_token);
11459  break;
11460  }
11461 
11462  case detail::value_t::array:
11463  {
11464  // create an entry in the array
11465  result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
11466  break;
11467  }
11468 
11469  /*
11470  The following code is only reached if there exists a reference
11471  token _and_ the current value is primitive. In this case, we have
11472  an error situation, because primitive values may only occur as
11473  single value; that is, with an empty list of reference tokens.
11474  */
11475  default:
11476  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11477  }
11478  }
11479 
11480  return *result;
11481  }
11482 
11502  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
11503  {
11504  using size_type = typename BasicJsonType::size_type;
11505  for (const auto& reference_token : reference_tokens)
11506  {
11507  // convert null values to arrays or objects before continuing
11508  if (ptr->is_null())
11509  {
11510  // check if reference token is a number
11511  const bool nums =
11512  std::all_of(reference_token.begin(), reference_token.end(),
11513  [](const unsigned char x)
11514  {
11515  return std::isdigit(x);
11516  });
11517 
11518  // change value to array for numbers or "-" or to object otherwise
11519  *ptr = (nums or reference_token == "-")
11520  ? detail::value_t::array
11521  : detail::value_t::object;
11522  }
11523 
11524  switch (ptr->type())
11525  {
11526  case detail::value_t::object:
11527  {
11528  // use unchecked object access
11529  ptr = &ptr->operator[](reference_token);
11530  break;
11531  }
11532 
11533  case detail::value_t::array:
11534  {
11535  if (reference_token == "-")
11536  {
11537  // explicitly treat "-" as index beyond the end
11538  ptr = &ptr->operator[](ptr->m_value.array->size());
11539  }
11540  else
11541  {
11542  // convert array index to number; unchecked access
11543  ptr = &ptr->operator[](
11544  static_cast<size_type>(array_index(reference_token)));
11545  }
11546  break;
11547  }
11548 
11549  default:
11550  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11551  }
11552  }
11553 
11554  return *ptr;
11555  }
11556 
11563  BasicJsonType& get_checked(BasicJsonType* ptr) const
11564  {
11565  using size_type = typename BasicJsonType::size_type;
11566  for (const auto& reference_token : reference_tokens)
11567  {
11568  switch (ptr->type())
11569  {
11570  case detail::value_t::object:
11571  {
11572  // note: at performs range check
11573  ptr = &ptr->at(reference_token);
11574  break;
11575  }
11576 
11577  case detail::value_t::array:
11578  {
11579  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11580  {
11581  // "-" always fails the range check
11582  JSON_THROW(detail::out_of_range::create(402,
11583  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11584  ") is out of range"));
11585  }
11586 
11587  // note: at performs range check
11588  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11589  break;
11590  }
11591 
11592  default:
11593  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11594  }
11595  }
11596 
11597  return *ptr;
11598  }
11599 
11613  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
11614  {
11615  using size_type = typename BasicJsonType::size_type;
11616  for (const auto& reference_token : reference_tokens)
11617  {
11618  switch (ptr->type())
11619  {
11620  case detail::value_t::object:
11621  {
11622  // use unchecked object access
11623  ptr = &ptr->operator[](reference_token);
11624  break;
11625  }
11626 
11627  case detail::value_t::array:
11628  {
11629  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11630  {
11631  // "-" cannot be used for const access
11632  JSON_THROW(detail::out_of_range::create(402,
11633  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11634  ") is out of range"));
11635  }
11636 
11637  // use unchecked array access
11638  ptr = &ptr->operator[](
11639  static_cast<size_type>(array_index(reference_token)));
11640  break;
11641  }
11642 
11643  default:
11644  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11645  }
11646  }
11647 
11648  return *ptr;
11649  }
11650 
11657  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
11658  {
11659  using size_type = typename BasicJsonType::size_type;
11660  for (const auto& reference_token : reference_tokens)
11661  {
11662  switch (ptr->type())
11663  {
11664  case detail::value_t::object:
11665  {
11666  // note: at performs range check
11667  ptr = &ptr->at(reference_token);
11668  break;
11669  }
11670 
11671  case detail::value_t::array:
11672  {
11673  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11674  {
11675  // "-" always fails the range check
11676  JSON_THROW(detail::out_of_range::create(402,
11677  "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
11678  ") is out of range"));
11679  }
11680 
11681  // note: at performs range check
11682  ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
11683  break;
11684  }
11685 
11686  default:
11687  JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
11688  }
11689  }
11690 
11691  return *ptr;
11692  }
11693 
11698  bool contains(const BasicJsonType* ptr) const
11699  {
11700  using size_type = typename BasicJsonType::size_type;
11701  for (const auto& reference_token : reference_tokens)
11702  {
11703  switch (ptr->type())
11704  {
11705  case detail::value_t::object:
11706  {
11707  if (not ptr->contains(reference_token))
11708  {
11709  // we did not find the key in the object
11710  return false;
11711  }
11712 
11713  ptr = &ptr->operator[](reference_token);
11714  break;
11715  }
11716 
11717  case detail::value_t::array:
11718  {
11719  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
11720  {
11721  // "-" always fails the range check
11722  return false;
11723  }
11724  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 and not ("0" <= reference_token and reference_token <= "9")))
11725  {
11726  // invalid char
11727  return false;
11728  }
11729  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
11730  {
11731  if (JSON_HEDLEY_UNLIKELY(not ('1' <= reference_token[0] and reference_token[0] <= '9')))
11732  {
11733  // first char should be between '1' and '9'
11734  return false;
11735  }
11736  for (std::size_t i = 1; i < reference_token.size(); i++)
11737  {
11738  if (JSON_HEDLEY_UNLIKELY(not ('0' <= reference_token[i] and reference_token[i] <= '9')))
11739  {
11740  // other char should be between '0' and '9'
11741  return false;
11742  }
11743  }
11744  }
11745 
11746  const auto idx = static_cast<size_type>(array_index(reference_token));
11747  if (idx >= ptr->size())
11748  {
11749  // index out of range
11750  return false;
11751  }
11752 
11753  ptr = &ptr->operator[](idx);
11754  break;
11755  }
11756 
11757  default:
11758  {
11759  // we do not expect primitive values if there is still a
11760  // reference token to process
11761  return false;
11762  }
11763  }
11764  }
11765 
11766  // no reference token left means we found a primitive value
11767  return true;
11768  }
11769 
11779  static std::vector<std::string> split(const std::string& reference_string)
11780  {
11781  std::vector<std::string> result;
11782 
11783  // special case: empty reference string -> no reference tokens
11784  if (reference_string.empty())
11785  {
11786  return result;
11787  }
11788 
11789  // check if nonempty reference string begins with slash
11790  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
11791  {
11792  JSON_THROW(detail::parse_error::create(107, 1,
11793  "JSON pointer must be empty or begin with '/' - was: '" +
11794  reference_string + "'"));
11795  }
11796 
11797  // extract the reference tokens:
11798  // - slash: position of the last read slash (or end of string)
11799  // - start: position after the previous slash
11800  for (
11801  // search for the first slash after the first character
11802  std::size_t slash = reference_string.find_first_of('/', 1),
11803  // set the beginning of the first reference token
11804  start = 1;
11805  // we can stop if start == 0 (if slash == std::string::npos)
11806  start != 0;
11807  // set the beginning of the next reference token
11808  // (will eventually be 0 if slash == std::string::npos)
11809  start = (slash == std::string::npos) ? 0 : slash + 1,
11810  // find next slash
11811  slash = reference_string.find_first_of('/', start))
11812  {
11813  // use the text between the beginning of the reference token
11814  // (start) and the last slash (slash).
11815  auto reference_token = reference_string.substr(start, slash - start);
11816 
11817  // check reference tokens are properly escaped
11818  for (std::size_t pos = reference_token.find_first_of('~');
11819  pos != std::string::npos;
11820  pos = reference_token.find_first_of('~', pos + 1))
11821  {
11822  assert(reference_token[pos] == '~');
11823 
11824  // ~ must be followed by 0 or 1
11825  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 or
11826  (reference_token[pos + 1] != '0' and
11827  reference_token[pos + 1] != '1')))
11828  {
11829  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
11830  }
11831  }
11832 
11833  // finally, store the reference token
11834  unescape(reference_token);
11835  result.push_back(reference_token);
11836  }
11837 
11838  return result;
11839  }
11840 
11854  static void replace_substring(std::string& s, const std::string& f,
11855  const std::string& t)
11856  {
11857  assert(not f.empty());
11858  for (auto pos = s.find(f); // find first occurrence of f
11859  pos != std::string::npos; // make sure f was found
11860  s.replace(pos, f.size(), t), // replace with t, and
11861  pos = s.find(f, pos + t.size())) // find next occurrence of f
11862  {}
11863  }
11864 
11866  static std::string escape(std::string s)
11867  {
11868  replace_substring(s, "~", "~0");
11869  replace_substring(s, "/", "~1");
11870  return s;
11871  }
11872 
11874  static void unescape(std::string& s)
11875  {
11876  replace_substring(s, "~1", "/");
11877  replace_substring(s, "~0", "~");
11878  }
11879 
11887  static void flatten(const std::string& reference_string,
11888  const BasicJsonType& value,
11889  BasicJsonType& result)
11890  {
11891  switch (value.type())
11892  {
11893  case detail::value_t::array:
11894  {
11895  if (value.m_value.array->empty())
11896  {
11897  // flatten empty array as null
11898  result[reference_string] = nullptr;
11899  }
11900  else
11901  {
11902  // iterate array and use index as reference string
11903  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
11904  {
11905  flatten(reference_string + "/" + std::to_string(i),
11906  value.m_value.array->operator[](i), result);
11907  }
11908  }
11909  break;
11910  }
11911 
11912  case detail::value_t::object:
11913  {
11914  if (value.m_value.object->empty())
11915  {
11916  // flatten empty object as null
11917  result[reference_string] = nullptr;
11918  }
11919  else
11920  {
11921  // iterate object and use keys as reference string
11922  for (const auto& element : *value.m_value.object)
11923  {
11924  flatten(reference_string + "/" + escape(element.first), element.second, result);
11925  }
11926  }
11927  break;
11928  }
11929 
11930  default:
11931  {
11932  // add primitive value with its reference string
11933  result[reference_string] = value;
11934  break;
11935  }
11936  }
11937  }
11938 
11949  static BasicJsonType
11950  unflatten(const BasicJsonType& value)
11951  {
11952  if (JSON_HEDLEY_UNLIKELY(not value.is_object()))
11953  {
11954  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
11955  }
11956 
11957  BasicJsonType result;
11958 
11959  // iterate the JSON object values
11960  for (const auto& element : *value.m_value.object)
11961  {
11962  if (JSON_HEDLEY_UNLIKELY(not element.second.is_primitive()))
11963  {
11964  JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
11965  }
11966 
11967  // assign value to reference pointed to by JSON pointer; Note that if
11968  // the JSON pointer is "" (i.e., points to the whole value), function
11969  // get_and_create returns a reference to result itself. An assignment
11970  // will then create a primitive value.
11971  json_pointer(element.first).get_and_create(result) = element.second;
11972  }
11973 
11974  return result;
11975  }
11976 
11988  friend bool operator==(json_pointer const& lhs,
11989  json_pointer const& rhs) noexcept
11990  {
11991  return lhs.reference_tokens == rhs.reference_tokens;
11992  }
11993 
12005  friend bool operator!=(json_pointer const& lhs,
12006  json_pointer const& rhs) noexcept
12007  {
12008  return not (lhs == rhs);
12009  }
12010 
12012  std::vector<std::string> reference_tokens;
12013 };
12014 } // namespace nlohmann
12015 
12016 // #include <nlohmann/detail/json_ref.hpp>
12017 
12018 
12019 #include <initializer_list>
12020 #include <utility>
12021 
12022 // #include <nlohmann/detail/meta/type_traits.hpp>
12023 
12024 
12025 namespace nlohmann
12026 {
12027 namespace detail
12028 {
12029 template<typename BasicJsonType>
12030 class json_ref
12031 {
12032  public:
12033  using value_type = BasicJsonType;
12034 
12035  json_ref(value_type&& value)
12036  : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
12037  {}
12038 
12039  json_ref(const value_type& value)
12040  : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
12041  {}
12042 
12043  json_ref(std::initializer_list<json_ref> init)
12044  : owned_value(init), value_ref(&owned_value), is_rvalue(true)
12045  {}
12046 
12047  template <
12048  class... Args,
12049  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
12050  json_ref(Args && ... args)
12051  : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
12052  is_rvalue(true) {}
12053 
12054  // class should be movable only
12055  json_ref(json_ref&&) = default;
12056  json_ref(const json_ref&) = delete;
12057  json_ref& operator=(const json_ref&) = delete;
12058  json_ref& operator=(json_ref&&) = delete;
12059  ~json_ref() = default;
12060 
12061  value_type moved_or_copied() const
12062  {
12063  if (is_rvalue)
12064  {
12065  return std::move(*value_ref);
12066  }
12067  return *value_ref;
12068  }
12069 
12070  value_type const& operator*() const
12071  {
12072  return *static_cast<value_type const*>(value_ref);
12073  }
12074 
12075  value_type const* operator->() const
12076  {
12077  return static_cast<value_type const*>(value_ref);
12078  }
12079 
12080  private:
12081  mutable value_type owned_value = nullptr;
12082  value_type* value_ref = nullptr;
12083  const bool is_rvalue;
12084 };
12085 } // namespace detail
12086 } // namespace nlohmann
12087 
12088 // #include <nlohmann/detail/macro_scope.hpp>
12089 
12090 // #include <nlohmann/detail/meta/cpp_future.hpp>
12091 
12092 // #include <nlohmann/detail/meta/type_traits.hpp>
12093 
12094 // #include <nlohmann/detail/output/binary_writer.hpp>
12095 
12096 
12097 #include <algorithm> // reverse
12098 #include <array> // array
12099 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12100 #include <cstring> // memcpy
12101 #include <limits> // numeric_limits
12102 #include <string> // string
12103 #include <cmath> // isnan, isinf
12104 
12105 // #include <nlohmann/detail/input/binary_reader.hpp>
12106 
12107 // #include <nlohmann/detail/macro_scope.hpp>
12108 
12109 // #include <nlohmann/detail/output/output_adapters.hpp>
12110 
12111 
12112 #include <algorithm> // copy
12113 #include <cstddef> // size_t
12114 #include <ios> // streamsize
12115 #include <iterator> // back_inserter
12116 #include <memory> // shared_ptr, make_shared
12117 #include <ostream> // basic_ostream
12118 #include <string> // basic_string
12119 #include <vector> // vector
12120 // #include <nlohmann/detail/macro_scope.hpp>
12121 
12122 
12123 namespace nlohmann
12124 {
12125 namespace detail
12126 {
12128 template<typename CharType> struct output_adapter_protocol
12129 {
12130  virtual void write_character(CharType c) = 0;
12131  virtual void write_characters(const CharType* s, std::size_t length) = 0;
12132  virtual ~output_adapter_protocol() = default;
12133 };
12134 
12136 template<typename CharType>
12137 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12138 
12140 template<typename CharType>
12141 class output_vector_adapter : public output_adapter_protocol<CharType>
12142 {
12143  public:
12144  explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12145  : v(vec)
12146  {}
12147 
12148  void write_character(CharType c) override
12149  {
12150  v.push_back(c);
12151  }
12152 
12153  JSON_HEDLEY_NON_NULL(2)
12154  void write_characters(const CharType* s, std::size_t length) override
12155  {
12156  std::copy(s, s + length, std::back_inserter(v));
12157  }
12158 
12159  private:
12160  std::vector<CharType>& v;
12161 };
12162 
12164 template<typename CharType>
12165 class output_stream_adapter : public output_adapter_protocol<CharType>
12166 {
12167  public:
12168  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12169  : stream(s)
12170  {}
12171 
12172  void write_character(CharType c) override
12173  {
12174  stream.put(c);
12175  }
12176 
12177  JSON_HEDLEY_NON_NULL(2)
12178  void write_characters(const CharType* s, std::size_t length) override
12179  {
12180  stream.write(s, static_cast<std::streamsize>(length));
12181  }
12182 
12183  private:
12184  std::basic_ostream<CharType>& stream;
12185 };
12186 
12188 template<typename CharType, typename StringType = std::basic_string<CharType>>
12189 class output_string_adapter : public output_adapter_protocol<CharType>
12190 {
12191  public:
12192  explicit output_string_adapter(StringType& s) noexcept
12193  : str(s)
12194  {}
12195 
12196  void write_character(CharType c) override
12197  {
12198  str.push_back(c);
12199  }
12200 
12201  JSON_HEDLEY_NON_NULL(2)
12202  void write_characters(const CharType* s, std::size_t length) override
12203  {
12204  str.append(s, length);
12205  }
12206 
12207  private:
12208  StringType& str;
12209 };
12210 
12211 template<typename CharType, typename StringType = std::basic_string<CharType>>
12212 class output_adapter
12213 {
12214  public:
12215  output_adapter(std::vector<CharType>& vec)
12216  : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12217 
12218  output_adapter(std::basic_ostream<CharType>& s)
12219  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12220 
12221  output_adapter(StringType& s)
12222  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12223 
12224  operator output_adapter_t<CharType>()
12225  {
12226  return oa;
12227  }
12228 
12229  private:
12230  output_adapter_t<CharType> oa = nullptr;
12231 };
12232 } // namespace detail
12233 } // namespace nlohmann
12234 
12235 
12236 namespace nlohmann
12237 {
12238 namespace detail
12239 {
12241 // binary writer //
12243 
12247 template<typename BasicJsonType, typename CharType>
12248 class binary_writer
12249 {
12250  using string_t = typename BasicJsonType::string_t;
12251  using binary_t = typename BasicJsonType::binary_t;
12252 
12253  public:
12259  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12260  {
12261  assert(oa);
12262  }
12263 
12268  void write_bson(const BasicJsonType& j)
12269  {
12270  switch (j.type())
12271  {
12272  case value_t::object:
12273  {
12274  write_bson_object(*j.m_value.object);
12275  break;
12276  }
12277 
12278  default:
12279  {
12280  JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12281  }
12282  }
12283  }
12284 
12288  void write_cbor(const BasicJsonType& j)
12289  {
12290  switch (j.type())
12291  {
12292  case value_t::null:
12293  {
12294  oa->write_character(to_char_type(0xF6));
12295  break;
12296  }
12297 
12298  case value_t::boolean:
12299  {
12300  oa->write_character(j.m_value.boolean
12301  ? to_char_type(0xF5)
12302  : to_char_type(0xF4));
12303  break;
12304  }
12305 
12306  case value_t::number_integer:
12307  {
12308  if (j.m_value.number_integer >= 0)
12309  {
12310  // CBOR does not differentiate between positive signed
12311  // integers and unsigned integers. Therefore, we used the
12312  // code from the value_t::number_unsigned case here.
12313  if (j.m_value.number_integer <= 0x17)
12314  {
12315  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12316  }
12317  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12318  {
12319  oa->write_character(to_char_type(0x18));
12320  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12321  }
12322  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12323  {
12324  oa->write_character(to_char_type(0x19));
12325  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12326  }
12327  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12328  {
12329  oa->write_character(to_char_type(0x1A));
12330  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12331  }
12332  else
12333  {
12334  oa->write_character(to_char_type(0x1B));
12335  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12336  }
12337  }
12338  else
12339  {
12340  // The conversions below encode the sign in the first
12341  // byte, and the value is converted to a positive number.
12342  const auto positive_number = -1 - j.m_value.number_integer;
12343  if (j.m_value.number_integer >= -24)
12344  {
12345  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12346  }
12347  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12348  {
12349  oa->write_character(to_char_type(0x38));
12350  write_number(static_cast<std::uint8_t>(positive_number));
12351  }
12352  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12353  {
12354  oa->write_character(to_char_type(0x39));
12355  write_number(static_cast<std::uint16_t>(positive_number));
12356  }
12357  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12358  {
12359  oa->write_character(to_char_type(0x3A));
12360  write_number(static_cast<std::uint32_t>(positive_number));
12361  }
12362  else
12363  {
12364  oa->write_character(to_char_type(0x3B));
12365  write_number(static_cast<std::uint64_t>(positive_number));
12366  }
12367  }
12368  break;
12369  }
12370 
12371  case value_t::number_unsigned:
12372  {
12373  if (j.m_value.number_unsigned <= 0x17)
12374  {
12375  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12376  }
12377  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12378  {
12379  oa->write_character(to_char_type(0x18));
12380  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12381  }
12382  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12383  {
12384  oa->write_character(to_char_type(0x19));
12385  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12386  }
12387  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12388  {
12389  oa->write_character(to_char_type(0x1A));
12390  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12391  }
12392  else
12393  {
12394  oa->write_character(to_char_type(0x1B));
12395  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12396  }
12397  break;
12398  }
12399 
12400  case value_t::number_float:
12401  {
12402  if (std::isnan(j.m_value.number_float))
12403  {
12404  // NaN is 0xf97e00 in CBOR
12405  oa->write_character(to_char_type(0xF9));
12406  oa->write_character(to_char_type(0x7E));
12407  oa->write_character(to_char_type(0x00));
12408  }
12409  else if (std::isinf(j.m_value.number_float))
12410  {
12411  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12412  oa->write_character(to_char_type(0xf9));
12413  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12414  oa->write_character(to_char_type(0x00));
12415  }
12416  else
12417  {
12418  if (static_cast<double>(j.m_value.number_float) >= static_cast<double>(std::numeric_limits<float>::lowest()) and
12419  static_cast<double>(j.m_value.number_float) <= static_cast<double>((std::numeric_limits<float>::max)()) and
12420  static_cast<double>(static_cast<float>(j.m_value.number_float)) == static_cast<double>(j.m_value.number_float))
12421  {
12422  oa->write_character(get_cbor_float_prefix(static_cast<float>(j.m_value.number_float)));
12423  write_number(static_cast<float>(j.m_value.number_float));
12424  }
12425  else
12426  {
12427  oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
12428  write_number(j.m_value.number_float);
12429  }
12430  }
12431  break;
12432  }
12433 
12434  case value_t::string:
12435  {
12436  // step 1: write control byte and the string length
12437  const auto N = j.m_value.string->size();
12438  if (N <= 0x17)
12439  {
12440  write_number(static_cast<std::uint8_t>(0x60 + N));
12441  }
12442  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12443  {
12444  oa->write_character(to_char_type(0x78));
12445  write_number(static_cast<std::uint8_t>(N));
12446  }
12447  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12448  {
12449  oa->write_character(to_char_type(0x79));
12450  write_number(static_cast<std::uint16_t>(N));
12451  }
12452  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12453  {
12454  oa->write_character(to_char_type(0x7A));
12455  write_number(static_cast<std::uint32_t>(N));
12456  }
12457  // LCOV_EXCL_START
12458  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12459  {
12460  oa->write_character(to_char_type(0x7B));
12461  write_number(static_cast<std::uint64_t>(N));
12462  }
12463  // LCOV_EXCL_STOP
12464 
12465  // step 2: write the string
12466  oa->write_characters(
12467  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12468  j.m_value.string->size());
12469  break;
12470  }
12471 
12472  case value_t::array:
12473  {
12474  // step 1: write control byte and the array size
12475  const auto N = j.m_value.array->size();
12476  if (N <= 0x17)
12477  {
12478  write_number(static_cast<std::uint8_t>(0x80 + N));
12479  }
12480  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12481  {
12482  oa->write_character(to_char_type(0x98));
12483  write_number(static_cast<std::uint8_t>(N));
12484  }
12485  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12486  {
12487  oa->write_character(to_char_type(0x99));
12488  write_number(static_cast<std::uint16_t>(N));
12489  }
12490  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12491  {
12492  oa->write_character(to_char_type(0x9A));
12493  write_number(static_cast<std::uint32_t>(N));
12494  }
12495  // LCOV_EXCL_START
12496  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12497  {
12498  oa->write_character(to_char_type(0x9B));
12499  write_number(static_cast<std::uint64_t>(N));
12500  }
12501  // LCOV_EXCL_STOP
12502 
12503  // step 2: write each element
12504  for (const auto& el : *j.m_value.array)
12505  {
12506  write_cbor(el);
12507  }
12508  break;
12509  }
12510 
12511  case value_t::binary:
12512  {
12513  // step 1: write control byte and the binary array size
12514  const auto N = j.m_value.binary->size();
12515  if (N <= 0x17)
12516  {
12517  write_number(static_cast<std::uint8_t>(0x40 + N));
12518  }
12519  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12520  {
12521  oa->write_character(to_char_type(0x58));
12522  write_number(static_cast<std::uint8_t>(N));
12523  }
12524  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12525  {
12526  oa->write_character(to_char_type(0x59));
12527  write_number(static_cast<std::uint16_t>(N));
12528  }
12529  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12530  {
12531  oa->write_character(to_char_type(0x5A));
12532  write_number(static_cast<std::uint32_t>(N));
12533  }
12534  // LCOV_EXCL_START
12535  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12536  {
12537  oa->write_character(to_char_type(0x5B));
12538  write_number(static_cast<std::uint64_t>(N));
12539  }
12540  // LCOV_EXCL_STOP
12541 
12542  // step 2: write each element
12543  oa->write_characters(
12544  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
12545  N);
12546 
12547  break;
12548  }
12549 
12550  case value_t::object:
12551  {
12552  // step 1: write control byte and the object size
12553  const auto N = j.m_value.object->size();
12554  if (N <= 0x17)
12555  {
12556  write_number(static_cast<std::uint8_t>(0xA0 + N));
12557  }
12558  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12559  {
12560  oa->write_character(to_char_type(0xB8));
12561  write_number(static_cast<std::uint8_t>(N));
12562  }
12563  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12564  {
12565  oa->write_character(to_char_type(0xB9));
12566  write_number(static_cast<std::uint16_t>(N));
12567  }
12568  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12569  {
12570  oa->write_character(to_char_type(0xBA));
12571  write_number(static_cast<std::uint32_t>(N));
12572  }
12573  // LCOV_EXCL_START
12574  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12575  {
12576  oa->write_character(to_char_type(0xBB));
12577  write_number(static_cast<std::uint64_t>(N));
12578  }
12579  // LCOV_EXCL_STOP
12580 
12581  // step 2: write each element
12582  for (const auto& el : *j.m_value.object)
12583  {
12584  write_cbor(el.first);
12585  write_cbor(el.second);
12586  }
12587  break;
12588  }
12589 
12590  default:
12591  break;
12592  }
12593  }
12594 
12598  void write_msgpack(const BasicJsonType& j)
12599  {
12600  switch (j.type())
12601  {
12602  case value_t::null: // nil
12603  {
12604  oa->write_character(to_char_type(0xC0));
12605  break;
12606  }
12607 
12608  case value_t::boolean: // true and false
12609  {
12610  oa->write_character(j.m_value.boolean
12611  ? to_char_type(0xC3)
12612  : to_char_type(0xC2));
12613  break;
12614  }
12615 
12616  case value_t::number_integer:
12617  {
12618  if (j.m_value.number_integer >= 0)
12619  {
12620  // MessagePack does not differentiate between positive
12621  // signed integers and unsigned integers. Therefore, we used
12622  // the code from the value_t::number_unsigned case here.
12623  if (j.m_value.number_unsigned < 128)
12624  {
12625  // positive fixnum
12626  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12627  }
12628  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12629  {
12630  // uint 8
12631  oa->write_character(to_char_type(0xCC));
12632  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12633  }
12634  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12635  {
12636  // uint 16
12637  oa->write_character(to_char_type(0xCD));
12638  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12639  }
12640  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12641  {
12642  // uint 32
12643  oa->write_character(to_char_type(0xCE));
12644  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12645  }
12646  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12647  {
12648  // uint 64
12649  oa->write_character(to_char_type(0xCF));
12650  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12651  }
12652  }
12653  else
12654  {
12655  if (j.m_value.number_integer >= -32)
12656  {
12657  // negative fixnum
12658  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
12659  }
12660  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
12661  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
12662  {
12663  // int 8
12664  oa->write_character(to_char_type(0xD0));
12665  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
12666  }
12667  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
12668  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
12669  {
12670  // int 16
12671  oa->write_character(to_char_type(0xD1));
12672  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
12673  }
12674  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
12675  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
12676  {
12677  // int 32
12678  oa->write_character(to_char_type(0xD2));
12679  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
12680  }
12681  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
12682  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
12683  {
12684  // int 64
12685  oa->write_character(to_char_type(0xD3));
12686  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
12687  }
12688  }
12689  break;
12690  }
12691 
12692  case value_t::number_unsigned:
12693  {
12694  if (j.m_value.number_unsigned < 128)
12695  {
12696  // positive fixnum
12697  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12698  }
12699  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12700  {
12701  // uint 8
12702  oa->write_character(to_char_type(0xCC));
12703  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12704  }
12705  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12706  {
12707  // uint 16
12708  oa->write_character(to_char_type(0xCD));
12709  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12710  }
12711  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12712  {
12713  // uint 32
12714  oa->write_character(to_char_type(0xCE));
12715  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12716  }
12717  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
12718  {
12719  // uint 64
12720  oa->write_character(to_char_type(0xCF));
12721  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12722  }
12723  break;
12724  }
12725 
12726  case value_t::number_float:
12727  {
12728  oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
12729  write_number(j.m_value.number_float);
12730  break;
12731  }
12732 
12733  case value_t::string:
12734  {
12735  // step 1: write control byte and the string length
12736  const auto N = j.m_value.string->size();
12737  if (N <= 31)
12738  {
12739  // fixstr
12740  write_number(static_cast<std::uint8_t>(0xA0 | N));
12741  }
12742  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12743  {
12744  // str 8
12745  oa->write_character(to_char_type(0xD9));
12746  write_number(static_cast<std::uint8_t>(N));
12747  }
12748  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12749  {
12750  // str 16
12751  oa->write_character(to_char_type(0xDA));
12752  write_number(static_cast<std::uint16_t>(N));
12753  }
12754  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12755  {
12756  // str 32
12757  oa->write_character(to_char_type(0xDB));
12758  write_number(static_cast<std::uint32_t>(N));
12759  }
12760 
12761  // step 2: write the string
12762  oa->write_characters(
12763  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12764  j.m_value.string->size());
12765  break;
12766  }
12767 
12768  case value_t::array:
12769  {
12770  // step 1: write control byte and the array size
12771  const auto N = j.m_value.array->size();
12772  if (N <= 15)
12773  {
12774  // fixarray
12775  write_number(static_cast<std::uint8_t>(0x90 | N));
12776  }
12777  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12778  {
12779  // array 16
12780  oa->write_character(to_char_type(0xDC));
12781  write_number(static_cast<std::uint16_t>(N));
12782  }
12783  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12784  {
12785  // array 32
12786  oa->write_character(to_char_type(0xDD));
12787  write_number(static_cast<std::uint32_t>(N));
12788  }
12789 
12790  // step 2: write each element
12791  for (const auto& el : *j.m_value.array)
12792  {
12793  write_msgpack(el);
12794  }
12795  break;
12796  }
12797 
12798  case value_t::binary:
12799  {
12800  // step 0: determine if the binary type has a set subtype to
12801  // determine whether or not to use the ext or fixext types
12802  const bool use_ext = j.m_value.binary->has_subtype();
12803 
12804  // step 1: write control byte and the byte string length
12805  const auto N = j.m_value.binary->size();
12806  if (N <= (std::numeric_limits<std::uint8_t>::max)())
12807  {
12808  std::uint8_t output_type;
12809  bool fixed = true;
12810  if (use_ext)
12811  {
12812  switch (N)
12813  {
12814  case 1:
12815  output_type = 0xD4; // fixext 1
12816  break;
12817  case 2:
12818  output_type = 0xD5; // fixext 2
12819  break;
12820  case 4:
12821  output_type = 0xD6; // fixext 4
12822  break;
12823  case 8:
12824  output_type = 0xD7; // fixext 8
12825  break;
12826  case 16:
12827  output_type = 0xD8; // fixext 16
12828  break;
12829  default:
12830  output_type = 0xC7; // ext 8
12831  fixed = false;
12832  break;
12833  }
12834 
12835  }
12836  else
12837  {
12838  output_type = 0xC4; // bin 8
12839  fixed = false;
12840  }
12841 
12842  oa->write_character(to_char_type(output_type));
12843  if (not fixed)
12844  {
12845  write_number(static_cast<std::uint8_t>(N));
12846  }
12847  }
12848  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12849  {
12850  std::uint8_t output_type;
12851  if (use_ext)
12852  {
12853  output_type = 0xC8; // ext 16
12854  }
12855  else
12856  {
12857  output_type = 0xC5; // bin 16
12858  }
12859 
12860  oa->write_character(to_char_type(output_type));
12861  write_number(static_cast<std::uint16_t>(N));
12862  }
12863  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12864  {
12865  std::uint8_t output_type;
12866  if (use_ext)
12867  {
12868  output_type = 0xC9; // ext 32
12869  }
12870  else
12871  {
12872  output_type = 0xC6; // bin 32
12873  }
12874 
12875  oa->write_character(to_char_type(output_type));
12876  write_number(static_cast<std::uint32_t>(N));
12877  }
12878 
12879  // step 1.5: if this is an ext type, write the subtype
12880  if (use_ext)
12881  {
12882  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
12883  }
12884 
12885  // step 2: write the byte string
12886  oa->write_characters(
12887  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
12888  N);
12889 
12890  break;
12891  }
12892 
12893  case value_t::object:
12894  {
12895  // step 1: write control byte and the object size
12896  const auto N = j.m_value.object->size();
12897  if (N <= 15)
12898  {
12899  // fixmap
12900  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
12901  }
12902  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12903  {
12904  // map 16
12905  oa->write_character(to_char_type(0xDE));
12906  write_number(static_cast<std::uint16_t>(N));
12907  }
12908  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12909  {
12910  // map 32
12911  oa->write_character(to_char_type(0xDF));
12912  write_number(static_cast<std::uint32_t>(N));
12913  }
12914 
12915  // step 2: write each element
12916  for (const auto& el : *j.m_value.object)
12917  {
12918  write_msgpack(el.first);
12919  write_msgpack(el.second);
12920  }
12921  break;
12922  }
12923 
12924  default:
12925  break;
12926  }
12927  }
12928 
12935  void write_ubjson(const BasicJsonType& j, const bool use_count,
12936  const bool use_type, const bool add_prefix = true)
12937  {
12938  switch (j.type())
12939  {
12940  case value_t::null:
12941  {
12942  if (add_prefix)
12943  {
12944  oa->write_character(to_char_type('Z'));
12945  }
12946  break;
12947  }
12948 
12949  case value_t::boolean:
12950  {
12951  if (add_prefix)
12952  {
12953  oa->write_character(j.m_value.boolean
12954  ? to_char_type('T')
12955  : to_char_type('F'));
12956  }
12957  break;
12958  }
12959 
12960  case value_t::number_integer:
12961  {
12962  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
12963  break;
12964  }
12965 
12966  case value_t::number_unsigned:
12967  {
12968  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
12969  break;
12970  }
12971 
12972  case value_t::number_float:
12973  {
12974  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
12975  break;
12976  }
12977 
12978  case value_t::string:
12979  {
12980  if (add_prefix)
12981  {
12982  oa->write_character(to_char_type('S'));
12983  }
12984  write_number_with_ubjson_prefix(j.m_value.string->size(), true);
12985  oa->write_characters(
12986  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12987  j.m_value.string->size());
12988  break;
12989  }
12990 
12991  case value_t::array:
12992  {
12993  if (add_prefix)
12994  {
12995  oa->write_character(to_char_type('['));
12996  }
12997 
12998  bool prefix_required = true;
12999  if (use_type and not j.m_value.array->empty())
13000  {
13001  assert(use_count);
13002  const CharType first_prefix = ubjson_prefix(j.front());
13003  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13004  [this, first_prefix](const BasicJsonType & v)
13005  {
13006  return ubjson_prefix(v) == first_prefix;
13007  });
13008 
13009  if (same_prefix)
13010  {
13011  prefix_required = false;
13012  oa->write_character(to_char_type('$'));
13013  oa->write_character(first_prefix);
13014  }
13015  }
13016 
13017  if (use_count)
13018  {
13019  oa->write_character(to_char_type('#'));
13020  write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13021  }
13022 
13023  for (const auto& el : *j.m_value.array)
13024  {
13025  write_ubjson(el, use_count, use_type, prefix_required);
13026  }
13027 
13028  if (not use_count)
13029  {
13030  oa->write_character(to_char_type(']'));
13031  }
13032 
13033  break;
13034  }
13035 
13036  case value_t::binary:
13037  {
13038  if (add_prefix)
13039  {
13040  oa->write_character(to_char_type('['));
13041  }
13042 
13043  if (use_type and not j.m_value.binary->empty())
13044  {
13045  assert(use_count);
13046  oa->write_character(to_char_type('$'));
13047  oa->write_character('U');
13048  }
13049 
13050  if (use_count)
13051  {
13052  oa->write_character(to_char_type('#'));
13053  write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13054  }
13055 
13056  if (use_type)
13057  {
13058  oa->write_characters(
13059  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13060  j.m_value.binary->size());
13061  }
13062  else
13063  {
13064  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13065  {
13066  oa->write_character(to_char_type('U'));
13067  oa->write_character(j.m_value.binary->data()[i]);
13068  }
13069  }
13070 
13071  if (not use_count)
13072  {
13073  oa->write_character(to_char_type(']'));
13074  }
13075 
13076  break;
13077  }
13078 
13079  case value_t::object:
13080  {
13081  if (add_prefix)
13082  {
13083  oa->write_character(to_char_type('{'));
13084  }
13085 
13086  bool prefix_required = true;
13087  if (use_type and not j.m_value.object->empty())
13088  {
13089  assert(use_count);
13090  const CharType first_prefix = ubjson_prefix(j.front());
13091  const bool same_prefix = std::all_of(j.begin(), j.end(),
13092  [this, first_prefix](const BasicJsonType & v)
13093  {
13094  return ubjson_prefix(v) == first_prefix;
13095  });
13096 
13097  if (same_prefix)
13098  {
13099  prefix_required = false;
13100  oa->write_character(to_char_type('$'));
13101  oa->write_character(first_prefix);
13102  }
13103  }
13104 
13105  if (use_count)
13106  {
13107  oa->write_character(to_char_type('#'));
13108  write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13109  }
13110 
13111  for (const auto& el : *j.m_value.object)
13112  {
13113  write_number_with_ubjson_prefix(el.first.size(), true);
13114  oa->write_characters(
13115  reinterpret_cast<const CharType*>(el.first.c_str()),
13116  el.first.size());
13117  write_ubjson(el.second, use_count, use_type, prefix_required);
13118  }
13119 
13120  if (not use_count)
13121  {
13122  oa->write_character(to_char_type('}'));
13123  }
13124 
13125  break;
13126  }
13127 
13128  default:
13129  break;
13130  }
13131  }
13132 
13133  private:
13135  // BSON //
13137 
13142  static std::size_t calc_bson_entry_header_size(const string_t& name)
13143  {
13144  const auto it = name.find(static_cast<typename string_t::value_type>(0));
13145  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13146  {
13147  JSON_THROW(out_of_range::create(409,
13148  "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13149  }
13150 
13151  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13152  }
13153 
13157  void write_bson_entry_header(const string_t& name,
13158  const std::uint8_t element_type)
13159  {
13160  oa->write_character(to_char_type(element_type)); // boolean
13161  oa->write_characters(
13162  reinterpret_cast<const CharType*>(name.c_str()),
13163  name.size() + 1u);
13164  }
13165 
13169  void write_bson_boolean(const string_t& name,
13170  const bool value)
13171  {
13172  write_bson_entry_header(name, 0x08);
13173  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13174  }
13175 
13179  void write_bson_double(const string_t& name,
13180  const double value)
13181  {
13182  write_bson_entry_header(name, 0x01);
13183  write_number<double, true>(value);
13184  }
13185 
13189  static std::size_t calc_bson_string_size(const string_t& value)
13190  {
13191  return sizeof(std::int32_t) + value.size() + 1ul;
13192  }
13193 
13197  void write_bson_string(const string_t& name,
13198  const string_t& value)
13199  {
13200  write_bson_entry_header(name, 0x02);
13201 
13202  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13203  oa->write_characters(
13204  reinterpret_cast<const CharType*>(value.c_str()),
13205  value.size() + 1);
13206  }
13207 
13211  void write_bson_null(const string_t& name)
13212  {
13213  write_bson_entry_header(name, 0x0A);
13214  }
13215 
13219  static std::size_t calc_bson_integer_size(const std::int64_t value)
13220  {
13221  return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
13222  ? sizeof(std::int32_t)
13223  : sizeof(std::int64_t);
13224  }
13225 
13229  void write_bson_integer(const string_t& name,
13230  const std::int64_t value)
13231  {
13232  if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
13233  {
13234  write_bson_entry_header(name, 0x10); // int32
13235  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13236  }
13237  else
13238  {
13239  write_bson_entry_header(name, 0x12); // int64
13240  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13241  }
13242  }
13243 
13247  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13248  {
13249  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13250  ? sizeof(std::int32_t)
13251  : sizeof(std::int64_t);
13252  }
13253 
13257  void write_bson_unsigned(const string_t& name,
13258  const std::uint64_t value)
13259  {
13260  if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13261  {
13262  write_bson_entry_header(name, 0x10 /* int32 */);
13263  write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13264  }
13265  else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13266  {
13267  write_bson_entry_header(name, 0x12 /* int64 */);
13268  write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13269  }
13270  else
13271  {
13272  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13273  }
13274  }
13275 
13279  void write_bson_object_entry(const string_t& name,
13280  const typename BasicJsonType::object_t& value)
13281  {
13282  write_bson_entry_header(name, 0x03); // object
13283  write_bson_object(value);
13284  }
13285 
13289  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13290  {
13291  std::size_t array_index = 0ul;
13292 
13293  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)
13294  {
13295  return result + calc_bson_element_size(std::to_string(array_index++), el);
13296  });
13297 
13298  return sizeof(std::int32_t) + embedded_document_size + 1ul;
13299  }
13300 
13304  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13305  {
13306  return sizeof(std::int32_t) + value.size() + 1ul;
13307  }
13308 
13312  void write_bson_array(const string_t& name,
13313  const typename BasicJsonType::array_t& value)
13314  {
13315  write_bson_entry_header(name, 0x04); // array
13316  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13317 
13318  std::size_t array_index = 0ul;
13319 
13320  for (const auto& el : value)
13321  {
13322  write_bson_element(std::to_string(array_index++), el);
13323  }
13324 
13325  oa->write_character(to_char_type(0x00));
13326  }
13327 
13331  void write_bson_binary(const string_t& name,
13332  const binary_t& value)
13333  {
13334  write_bson_entry_header(name, 0x05);
13335 
13336  write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13337  write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13338 
13339  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13340  }
13341 
13346  static std::size_t calc_bson_element_size(const string_t& name,
13347  const BasicJsonType& j)
13348  {
13349  const auto header_size = calc_bson_entry_header_size(name);
13350  switch (j.type())
13351  {
13352  case value_t::object:
13353  return header_size + calc_bson_object_size(*j.m_value.object);
13354 
13355  case value_t::array:
13356  return header_size + calc_bson_array_size(*j.m_value.array);
13357 
13358  case value_t::binary:
13359  return header_size + calc_bson_binary_size(*j.m_value.binary);
13360 
13361  case value_t::boolean:
13362  return header_size + 1ul;
13363 
13364  case value_t::number_float:
13365  return header_size + 8ul;
13366 
13367  case value_t::number_integer:
13368  return header_size + calc_bson_integer_size(j.m_value.number_integer);
13369 
13370  case value_t::number_unsigned:
13371  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13372 
13373  case value_t::string:
13374  return header_size + calc_bson_string_size(*j.m_value.string);
13375 
13376  case value_t::null:
13377  return header_size + 0ul;
13378 
13379  // LCOV_EXCL_START
13380  default:
13381  assert(false);
13382  return 0ul;
13383  // LCOV_EXCL_STOP
13384  }
13385  }
13386 
13394  void write_bson_element(const string_t& name,
13395  const BasicJsonType& j)
13396  {
13397  switch (j.type())
13398  {
13399  case value_t::object:
13400  return write_bson_object_entry(name, *j.m_value.object);
13401 
13402  case value_t::array:
13403  return write_bson_array(name, *j.m_value.array);
13404 
13405  case value_t::binary:
13406  return write_bson_binary(name, *j.m_value.binary);
13407 
13408  case value_t::boolean:
13409  return write_bson_boolean(name, j.m_value.boolean);
13410 
13411  case value_t::number_float:
13412  return write_bson_double(name, j.m_value.number_float);
13413 
13414  case value_t::number_integer:
13415  return write_bson_integer(name, j.m_value.number_integer);
13416 
13417  case value_t::number_unsigned:
13418  return write_bson_unsigned(name, j.m_value.number_unsigned);
13419 
13420  case value_t::string:
13421  return write_bson_string(name, *j.m_value.string);
13422 
13423  case value_t::null:
13424  return write_bson_null(name);
13425 
13426  // LCOV_EXCL_START
13427  default:
13428  assert(false);
13429  return;
13430  // LCOV_EXCL_STOP
13431  }
13432  }
13433 
13440  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13441  {
13442  std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13443  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13444  {
13445  return result += calc_bson_element_size(el.first, el.second);
13446  });
13447 
13448  return sizeof(std::int32_t) + document_size + 1ul;
13449  }
13450 
13455  void write_bson_object(const typename BasicJsonType::object_t& value)
13456  {
13457  write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13458 
13459  for (const auto& el : value)
13460  {
13461  write_bson_element(el.first, el.second);
13462  }
13463 
13464  oa->write_character(to_char_type(0x00));
13465  }
13466 
13468  // CBOR //
13470 
13471  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13472  {
13473  return to_char_type(0xFA); // Single-Precision Float
13474  }
13475 
13476  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13477  {
13478  return to_char_type(0xFB); // Double-Precision Float
13479  }
13480 
13482  // MsgPack //
13484 
13485  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13486  {
13487  return to_char_type(0xCA); // float 32
13488  }
13489 
13490  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13491  {
13492  return to_char_type(0xCB); // float 64
13493  }
13494 
13496  // UBJSON //
13498 
13499  // UBJSON: write number (floating point)
13500  template<typename NumberType, typename std::enable_if<
13501  std::is_floating_point<NumberType>::value, int>::type = 0>
13502  void write_number_with_ubjson_prefix(const NumberType n,
13503  const bool add_prefix)
13504  {
13505  if (add_prefix)
13506  {
13507  oa->write_character(get_ubjson_float_prefix(n));
13508  }
13509  write_number(n);
13510  }
13511 
13512  // UBJSON: write number (unsigned integer)
13513  template<typename NumberType, typename std::enable_if<
13514  std::is_unsigned<NumberType>::value, int>::type = 0>
13515  void write_number_with_ubjson_prefix(const NumberType n,
13516  const bool add_prefix)
13517  {
13518  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
13519  {
13520  if (add_prefix)
13521  {
13522  oa->write_character(to_char_type('i')); // int8
13523  }
13524  write_number(static_cast<std::uint8_t>(n));
13525  }
13526  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
13527  {
13528  if (add_prefix)
13529  {
13530  oa->write_character(to_char_type('U')); // uint8
13531  }
13532  write_number(static_cast<std::uint8_t>(n));
13533  }
13534  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
13535  {
13536  if (add_prefix)
13537  {
13538  oa->write_character(to_char_type('I')); // int16
13539  }
13540  write_number(static_cast<std::int16_t>(n));
13541  }
13542  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13543  {
13544  if (add_prefix)
13545  {
13546  oa->write_character(to_char_type('l')); // int32
13547  }
13548  write_number(static_cast<std::int32_t>(n));
13549  }
13550  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13551  {
13552  if (add_prefix)
13553  {
13554  oa->write_character(to_char_type('L')); // int64
13555  }
13556  write_number(static_cast<std::int64_t>(n));
13557  }
13558  else
13559  {
13560  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
13561  }
13562  }
13563 
13564  // UBJSON: write number (signed integer)
13565  template<typename NumberType, typename std::enable_if<
13566  std::is_signed<NumberType>::value and
13567  not std::is_floating_point<NumberType>::value, int>::type = 0>
13568  void write_number_with_ubjson_prefix(const NumberType n,
13569  const bool add_prefix)
13570  {
13571  if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
13572  {
13573  if (add_prefix)
13574  {
13575  oa->write_character(to_char_type('i')); // int8
13576  }
13577  write_number(static_cast<std::int8_t>(n));
13578  }
13579  else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
13580  {
13581  if (add_prefix)
13582  {
13583  oa->write_character(to_char_type('U')); // uint8
13584  }
13585  write_number(static_cast<std::uint8_t>(n));
13586  }
13587  else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
13588  {
13589  if (add_prefix)
13590  {
13591  oa->write_character(to_char_type('I')); // int16
13592  }
13593  write_number(static_cast<std::int16_t>(n));
13594  }
13595  else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
13596  {
13597  if (add_prefix)
13598  {
13599  oa->write_character(to_char_type('l')); // int32
13600  }
13601  write_number(static_cast<std::int32_t>(n));
13602  }
13603  else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
13604  {
13605  if (add_prefix)
13606  {
13607  oa->write_character(to_char_type('L')); // int64
13608  }
13609  write_number(static_cast<std::int64_t>(n));
13610  }
13611  // LCOV_EXCL_START
13612  else
13613  {
13614  JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
13615  }
13616  // LCOV_EXCL_STOP
13617  }
13618 
13628  CharType ubjson_prefix(const BasicJsonType& j) const noexcept
13629  {
13630  switch (j.type())
13631  {
13632  case value_t::null:
13633  return 'Z';
13634 
13635  case value_t::boolean:
13636  return j.m_value.boolean ? 'T' : 'F';
13637 
13638  case value_t::number_integer:
13639  {
13640  if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13641  {
13642  return 'i';
13643  }
13644  if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13645  {
13646  return 'U';
13647  }
13648  if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13649  {
13650  return 'I';
13651  }
13652  if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13653  {
13654  return 'l';
13655  }
13656  // no check and assume int64_t (see note above)
13657  return 'L';
13658  }
13659 
13660  case value_t::number_unsigned:
13661  {
13662  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
13663  {
13664  return 'i';
13665  }
13666  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
13667  {
13668  return 'U';
13669  }
13670  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
13671  {
13672  return 'I';
13673  }
13674  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13675  {
13676  return 'l';
13677  }
13678  // no check and assume int64_t (see note above)
13679  return 'L';
13680  }
13681 
13682  case value_t::number_float:
13683  return get_ubjson_float_prefix(j.m_value.number_float);
13684 
13685  case value_t::string:
13686  return 'S';
13687 
13688  case value_t::array: // fallthrough
13689  case value_t::binary:
13690  return '[';
13691 
13692  case value_t::object:
13693  return '{';
13694 
13695  default: // discarded values
13696  return 'N';
13697  }
13698  }
13699 
13700  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
13701  {
13702  return 'd'; // float 32
13703  }
13704 
13705  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
13706  {
13707  return 'D'; // float 64
13708  }
13709 
13711  // Utility functions //
13713 
13714  /*
13715  @brief write a number to output input
13716  @param[in] n number of type @a NumberType
13717  @tparam NumberType the type of the number
13718  @tparam OutputIsLittleEndian Set to true if output data is
13719  required to be little endian
13720 
13721  @note This function needs to respect the system's endianess, because bytes
13722  in CBOR, MessagePack, and UBJSON are stored in network order (big
13723  endian) and therefore need reordering on little endian systems.
13724  */
13725  template<typename NumberType, bool OutputIsLittleEndian = false>
13726  void write_number(const NumberType n)
13727  {
13728  // step 1: write number to array of length NumberType
13729  std::array<CharType, sizeof(NumberType)> vec;
13730  std::memcpy(vec.data(), &n, sizeof(NumberType));
13731 
13732  // step 2: write array to output (with possible reordering)
13733  if (is_little_endian != OutputIsLittleEndian)
13734  {
13735  // reverse byte order prior to conversion if necessary
13736  std::reverse(vec.begin(), vec.end());
13737  }
13738 
13739  oa->write_characters(vec.data(), sizeof(NumberType));
13740  }
13741 
13742  public:
13743  // The following to_char_type functions are implement the conversion
13744  // between uint8_t and CharType. In case CharType is not unsigned,
13745  // such a conversion is required to allow values greater than 128.
13746  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
13747  template < typename C = CharType,
13748  enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
13749  static constexpr CharType to_char_type(std::uint8_t x) noexcept
13750  {
13751  return *reinterpret_cast<char*>(&x);
13752  }
13753 
13754  template < typename C = CharType,
13755  enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
13756  static CharType to_char_type(std::uint8_t x) noexcept
13757  {
13758  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
13759  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
13760  CharType result;
13761  std::memcpy(&result, &x, sizeof(x));
13762  return result;
13763  }
13764 
13765  template<typename C = CharType,
13766  enable_if_t<std::is_unsigned<C>::value>* = nullptr>
13767  static constexpr CharType to_char_type(std::uint8_t x) noexcept
13768  {
13769  return x;
13770  }
13771 
13772  template < typename InputCharType, typename C = CharType,
13773  enable_if_t <
13774  std::is_signed<C>::value and
13775  std::is_signed<char>::value and
13776  std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
13777  > * = nullptr >
13778  static constexpr CharType to_char_type(InputCharType x) noexcept
13779  {
13780  return x;
13781  }
13782 
13783  private:
13785  const bool is_little_endian = little_endianess();
13786 
13788  output_adapter_t<CharType> oa = nullptr;
13789 };
13790 } // namespace detail
13791 } // namespace nlohmann
13792 
13793 // #include <nlohmann/detail/output/output_adapters.hpp>
13794 
13795 // #include <nlohmann/detail/output/serializer.hpp>
13796 
13797 
13798 #include <algorithm> // reverse, remove, fill, find, none_of
13799 #include <array> // array
13800 #include <cassert> // assert
13801 #include <clocale> // localeconv, lconv
13802 #include <cmath> // labs, isfinite, isnan, signbit
13803 #include <cstddef> // size_t, ptrdiff_t
13804 #include <cstdint> // uint8_t
13805 #include <cstdio> // snprintf
13806 #include <limits> // numeric_limits
13807 #include <string> // string
13808 #include <type_traits> // is_same
13809 #include <utility> // move
13810 
13811 // #include <nlohmann/detail/boolean_operators.hpp>
13812 
13813 // #include <nlohmann/detail/conversions/to_chars.hpp>
13814 
13815 
13816 #include <array> // array
13817 #include <cassert> // assert
13818 #include <cmath> // signbit, isfinite
13819 #include <cstdint> // intN_t, uintN_t
13820 #include <cstring> // memcpy, memmove
13821 #include <limits> // numeric_limits
13822 #include <type_traits> // conditional
13823 
13824 // #include <nlohmann/detail/boolean_operators.hpp>
13825 
13826 // #include <nlohmann/detail/macro_scope.hpp>
13827 
13828 
13829 namespace nlohmann
13830 {
13831 namespace detail
13832 {
13833 
13853 namespace dtoa_impl
13854 {
13855 
13856 template <typename Target, typename Source>
13857 Target reinterpret_bits(const Source source)
13858 {
13859  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
13860 
13861  Target target;
13862  std::memcpy(&target, &source, sizeof(Source));
13863  return target;
13864 }
13865 
13866 struct diyfp // f * 2^e
13867 {
13868  static constexpr int kPrecision = 64; // = q
13869 
13870  std::uint64_t f = 0;
13871  int e = 0;
13872 
13873  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
13874 
13879  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
13880  {
13881  assert(x.e == y.e);
13882  assert(x.f >= y.f);
13883 
13884  return {x.f - y.f, x.e};
13885  }
13886 
13891  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
13892  {
13893  static_assert(kPrecision == 64, "internal error");
13894 
13895  // Computes:
13896  // f = round((x.f * y.f) / 2^q)
13897  // e = x.e + y.e + q
13898 
13899  // Emulate the 64-bit * 64-bit multiplication:
13900  //
13901  // p = u * v
13902  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
13903  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
13904  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
13905  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
13906  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
13907  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
13908  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
13909  //
13910  // (Since Q might be larger than 2^32 - 1)
13911  //
13912  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
13913  //
13914  // (Q_hi + H does not overflow a 64-bit int)
13915  //
13916  // = p_lo + 2^64 p_hi
13917 
13918  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
13919  const std::uint64_t u_hi = x.f >> 32u;
13920  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
13921  const std::uint64_t v_hi = y.f >> 32u;
13922 
13923  const std::uint64_t p0 = u_lo * v_lo;
13924  const std::uint64_t p1 = u_lo * v_hi;
13925  const std::uint64_t p2 = u_hi * v_lo;
13926  const std::uint64_t p3 = u_hi * v_hi;
13927 
13928  const std::uint64_t p0_hi = p0 >> 32u;
13929  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
13930  const std::uint64_t p1_hi = p1 >> 32u;
13931  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
13932  const std::uint64_t p2_hi = p2 >> 32u;
13933 
13934  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
13935 
13936  // The full product might now be computed as
13937  //
13938  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
13939  // p_lo = p0_lo + (Q << 32)
13940  //
13941  // But in this particular case here, the full p_lo is not required.
13942  // Effectively we only need to add the highest bit in p_lo to p_hi (and
13943  // Q_hi + 1 does not overflow).
13944 
13945  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
13946 
13947  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
13948 
13949  return {h, x.e + y.e + 64};
13950  }
13951 
13956  static diyfp normalize(diyfp x) noexcept
13957  {
13958  assert(x.f != 0);
13959 
13960  while ((x.f >> 63u) == 0)
13961  {
13962  x.f <<= 1u;
13963  x.e--;
13964  }
13965 
13966  return x;
13967  }
13968 
13973  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
13974  {
13975  const int delta = x.e - target_exponent;
13976 
13977  assert(delta >= 0);
13978  assert(((x.f << delta) >> delta) == x.f);
13979 
13980  return {x.f << delta, target_exponent};
13981  }
13982 };
13983 
13984 struct boundaries
13985 {
13986  diyfp w;
13987  diyfp minus;
13988  diyfp plus;
13989 };
13990 
13997 template <typename FloatType>
13998 boundaries compute_boundaries(FloatType value)
13999 {
14000  assert(std::isfinite(value));
14001  assert(value > 0);
14002 
14003  // Convert the IEEE representation into a diyfp.
14004  //
14005  // If v is denormal:
14006  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
14007  // If v is normalized:
14008  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14009 
14010  static_assert(std::numeric_limits<FloatType>::is_iec559,
14011  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14012 
14013  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14014  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14015  constexpr int kMinExp = 1 - kBias;
14016  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14017 
14018  using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14019 
14020  const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14021  const std::uint64_t E = bits >> (kPrecision - 1);
14022  const std::uint64_t F = bits & (kHiddenBit - 1);
14023 
14024  const bool is_denormal = E == 0;
14025  const diyfp v = is_denormal
14026  ? diyfp(F, kMinExp)
14027  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14028 
14029  // Compute the boundaries m- and m+ of the floating-point value
14030  // v = f * 2^e.
14031  //
14032  // Determine v- and v+, the floating-point predecessor and successor if v,
14033  // respectively.
14034  //
14035  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
14036  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
14037  //
14038  // v+ = v + 2^e
14039  //
14040  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14041  // between m- and m+ round to v, regardless of how the input rounding
14042  // algorithm breaks ties.
14043  //
14044  // ---+-------------+-------------+-------------+-------------+--- (A)
14045  // v- m- v m+ v+
14046  //
14047  // -----------------+------+------+-------------+-------------+--- (B)
14048  // v- m- v m+ v+
14049 
14050  const bool lower_boundary_is_closer = F == 0 and E > 1;
14051  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14052  const diyfp m_minus = lower_boundary_is_closer
14053  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
14054  : diyfp(2 * v.f - 1, v.e - 1); // (A)
14055 
14056  // Determine the normalized w+ = m+.
14057  const diyfp w_plus = diyfp::normalize(m_plus);
14058 
14059  // Determine w- = m- such that e_(w-) = e_(w+).
14060  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14061 
14062  return {diyfp::normalize(v), w_minus, w_plus};
14063 }
14064 
14065 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14066 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14067 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14068 //
14069 // alpha <= e = e_c + e_w + q <= gamma
14070 //
14071 // or
14072 //
14073 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14074 // <= f_c * f_w * 2^gamma
14075 //
14076 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14077 //
14078 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14079 //
14080 // or
14081 //
14082 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14083 //
14084 // The choice of (alpha,gamma) determines the size of the table and the form of
14085 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14086 // in practice:
14087 //
14088 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14089 // processed independently: An integral part p1, and a fractional part p2:
14090 //
14091 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14092 // = (f div 2^-e) + (f mod 2^-e) * 2^e
14093 // = p1 + p2 * 2^e
14094 //
14095 // The conversion of p1 into decimal form requires a series of divisions and
14096 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14097 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14098 // achieved by choosing
14099 //
14100 // -e >= 32 or e <= -32 := gamma
14101 //
14102 // In order to convert the fractional part
14103 //
14104 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14105 //
14106 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14107 // d[-i] are extracted in order:
14108 //
14109 // (10 * p2) div 2^-e = d[-1]
14110 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14111 //
14112 // The multiplication by 10 must not overflow. It is sufficient to choose
14113 //
14114 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14115 //
14116 // Since p2 = f mod 2^-e < 2^-e,
14117 //
14118 // -e <= 60 or e >= -60 := alpha
14119 
14120 constexpr int kAlpha = -60;
14121 constexpr int kGamma = -32;
14122 
14123 struct cached_power // c = f * 2^e ~= 10^k
14124 {
14125  std::uint64_t f;
14126  int e;
14127  int k;
14128 };
14129 
14137 inline cached_power get_cached_power_for_binary_exponent(int e)
14138 {
14139  // Now
14140  //
14141  // alpha <= e_c + e + q <= gamma (1)
14142  // ==> f_c * 2^alpha <= c * 2^e * 2^q
14143  //
14144  // and since the c's are normalized, 2^(q-1) <= f_c,
14145  //
14146  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14147  // ==> 2^(alpha - e - 1) <= c
14148  //
14149  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14150  //
14151  // k = ceil( log_10( 2^(alpha - e - 1) ) )
14152  // = ceil( (alpha - e - 1) * log_10(2) )
14153  //
14154  // From the paper:
14155  // "In theory the result of the procedure could be wrong since c is rounded,
14156  // and the computation itself is approximated [...]. In practice, however,
14157  // this simple function is sufficient."
14158  //
14159  // For IEEE double precision floating-point numbers converted into
14160  // normalized diyfp's w = f * 2^e, with q = 64,
14161  //
14162  // e >= -1022 (min IEEE exponent)
14163  // -52 (p - 1)
14164  // -52 (p - 1, possibly normalize denormal IEEE numbers)
14165  // -11 (normalize the diyfp)
14166  // = -1137
14167  //
14168  // and
14169  //
14170  // e <= +1023 (max IEEE exponent)
14171  // -52 (p - 1)
14172  // -11 (normalize the diyfp)
14173  // = 960
14174  //
14175  // This binary exponent range [-1137,960] results in a decimal exponent
14176  // range [-307,324]. One does not need to store a cached power for each
14177  // k in this range. For each such k it suffices to find a cached power
14178  // such that the exponent of the product lies in [alpha,gamma].
14179  // This implies that the difference of the decimal exponents of adjacent
14180  // table entries must be less than or equal to
14181  //
14182  // floor( (gamma - alpha) * log_10(2) ) = 8.
14183  //
14184  // (A smaller distance gamma-alpha would require a larger table.)
14185 
14186  // NB:
14187  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14188 
14189  constexpr int kCachedPowersMinDecExp = -300;
14190  constexpr int kCachedPowersDecStep = 8;
14191 
14192  static constexpr std::array<cached_power, 79> kCachedPowers =
14193  {
14194  {
14195  { 0xAB70FE17C79AC6CA, -1060, -300 },
14196  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14197  { 0xBE5691EF416BD60C, -1007, -284 },
14198  { 0x8DD01FAD907FFC3C, -980, -276 },
14199  { 0xD3515C2831559A83, -954, -268 },
14200  { 0x9D71AC8FADA6C9B5, -927, -260 },
14201  { 0xEA9C227723EE8BCB, -901, -252 },
14202  { 0xAECC49914078536D, -874, -244 },
14203  { 0x823C12795DB6CE57, -847, -236 },
14204  { 0xC21094364DFB5637, -821, -228 },
14205  { 0x9096EA6F3848984F, -794, -220 },
14206  { 0xD77485CB25823AC7, -768, -212 },
14207  { 0xA086CFCD97BF97F4, -741, -204 },
14208  { 0xEF340A98172AACE5, -715, -196 },
14209  { 0xB23867FB2A35B28E, -688, -188 },
14210  { 0x84C8D4DFD2C63F3B, -661, -180 },
14211  { 0xC5DD44271AD3CDBA, -635, -172 },
14212  { 0x936B9FCEBB25C996, -608, -164 },
14213  { 0xDBAC6C247D62A584, -582, -156 },
14214  { 0xA3AB66580D5FDAF6, -555, -148 },
14215  { 0xF3E2F893DEC3F126, -529, -140 },
14216  { 0xB5B5ADA8AAFF80B8, -502, -132 },
14217  { 0x87625F056C7C4A8B, -475, -124 },
14218  { 0xC9BCFF6034C13053, -449, -116 },
14219  { 0x964E858C91BA2655, -422, -108 },
14220  { 0xDFF9772470297EBD, -396, -100 },
14221  { 0xA6DFBD9FB8E5B88F, -369, -92 },
14222  { 0xF8A95FCF88747D94, -343, -84 },
14223  { 0xB94470938FA89BCF, -316, -76 },
14224  { 0x8A08F0F8BF0F156B, -289, -68 },
14225  { 0xCDB02555653131B6, -263, -60 },
14226  { 0x993FE2C6D07B7FAC, -236, -52 },
14227  { 0xE45C10C42A2B3B06, -210, -44 },
14228  { 0xAA242499697392D3, -183, -36 },
14229  { 0xFD87B5F28300CA0E, -157, -28 },
14230  { 0xBCE5086492111AEB, -130, -20 },
14231  { 0x8CBCCC096F5088CC, -103, -12 },
14232  { 0xD1B71758E219652C, -77, -4 },
14233  { 0x9C40000000000000, -50, 4 },
14234  { 0xE8D4A51000000000, -24, 12 },
14235  { 0xAD78EBC5AC620000, 3, 20 },
14236  { 0x813F3978F8940984, 30, 28 },
14237  { 0xC097CE7BC90715B3, 56, 36 },
14238  { 0x8F7E32CE7BEA5C70, 83, 44 },
14239  { 0xD5D238A4ABE98068, 109, 52 },
14240  { 0x9F4F2726179A2245, 136, 60 },
14241  { 0xED63A231D4C4FB27, 162, 68 },
14242  { 0xB0DE65388CC8ADA8, 189, 76 },
14243  { 0x83C7088E1AAB65DB, 216, 84 },
14244  { 0xC45D1DF942711D9A, 242, 92 },
14245  { 0x924D692CA61BE758, 269, 100 },
14246  { 0xDA01EE641A708DEA, 295, 108 },
14247  { 0xA26DA3999AEF774A, 322, 116 },
14248  { 0xF209787BB47D6B85, 348, 124 },
14249  { 0xB454E4A179DD1877, 375, 132 },
14250  { 0x865B86925B9BC5C2, 402, 140 },
14251  { 0xC83553C5C8965D3D, 428, 148 },
14252  { 0x952AB45CFA97A0B3, 455, 156 },
14253  { 0xDE469FBD99A05FE3, 481, 164 },
14254  { 0xA59BC234DB398C25, 508, 172 },
14255  { 0xF6C69A72A3989F5C, 534, 180 },
14256  { 0xB7DCBF5354E9BECE, 561, 188 },
14257  { 0x88FCF317F22241E2, 588, 196 },
14258  { 0xCC20CE9BD35C78A5, 614, 204 },
14259  { 0x98165AF37B2153DF, 641, 212 },
14260  { 0xE2A0B5DC971F303A, 667, 220 },
14261  { 0xA8D9D1535CE3B396, 694, 228 },
14262  { 0xFB9B7CD9A4A7443C, 720, 236 },
14263  { 0xBB764C4CA7A44410, 747, 244 },
14264  { 0x8BAB8EEFB6409C1A, 774, 252 },
14265  { 0xD01FEF10A657842C, 800, 260 },
14266  { 0x9B10A4E5E9913129, 827, 268 },
14267  { 0xE7109BFBA19C0C9D, 853, 276 },
14268  { 0xAC2820D9623BF429, 880, 284 },
14269  { 0x80444B5E7AA7CF85, 907, 292 },
14270  { 0xBF21E44003ACDD2D, 933, 300 },
14271  { 0x8E679C2F5E44FF8F, 960, 308 },
14272  { 0xD433179D9C8CB841, 986, 316 },
14273  { 0x9E19DB92B4E31BA9, 1013, 324 },
14274  }
14275  };
14276 
14277  // This computation gives exactly the same results for k as
14278  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14279  // for |e| <= 1500, but doesn't require floating-point operations.
14280  // NB: log_10(2) ~= 78913 / 2^18
14281  assert(e >= -1500);
14282  assert(e <= 1500);
14283  const int f = kAlpha - e - 1;
14284  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14285 
14286  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14287  assert(index >= 0);
14288  assert(static_cast<std::size_t>(index) < kCachedPowers.size());
14289 
14290  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14291  assert(kAlpha <= cached.e + e + 64);
14292  assert(kGamma >= cached.e + e + 64);
14293 
14294  return cached;
14295 }
14296 
14301 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14302 {
14303  // LCOV_EXCL_START
14304  if (n >= 1000000000)
14305  {
14306  pow10 = 1000000000;
14307  return 10;
14308  }
14309  // LCOV_EXCL_STOP
14310  else if (n >= 100000000)
14311  {
14312  pow10 = 100000000;
14313  return 9;
14314  }
14315  else if (n >= 10000000)
14316  {
14317  pow10 = 10000000;
14318  return 8;
14319  }
14320  else if (n >= 1000000)
14321  {
14322  pow10 = 1000000;
14323  return 7;
14324  }
14325  else if (n >= 100000)
14326  {
14327  pow10 = 100000;
14328  return 6;
14329  }
14330  else if (n >= 10000)
14331  {
14332  pow10 = 10000;
14333  return 5;
14334  }
14335  else if (n >= 1000)
14336  {
14337  pow10 = 1000;
14338  return 4;
14339  }
14340  else if (n >= 100)
14341  {
14342  pow10 = 100;
14343  return 3;
14344  }
14345  else if (n >= 10)
14346  {
14347  pow10 = 10;
14348  return 2;
14349  }
14350  else
14351  {
14352  pow10 = 1;
14353  return 1;
14354  }
14355 }
14356 
14357 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14358  std::uint64_t rest, std::uint64_t ten_k)
14359 {
14360  assert(len >= 1);
14361  assert(dist <= delta);
14362  assert(rest <= delta);
14363  assert(ten_k > 0);
14364 
14365  // <--------------------------- delta ---->
14366  // <---- dist --------->
14367  // --------------[------------------+-------------------]--------------
14368  // M- w M+
14369  //
14370  // ten_k
14371  // <------>
14372  // <---- rest ---->
14373  // --------------[------------------+----+--------------]--------------
14374  // w V
14375  // = buf * 10^k
14376  //
14377  // ten_k represents a unit-in-the-last-place in the decimal representation
14378  // stored in buf.
14379  // Decrement buf by ten_k while this takes buf closer to w.
14380 
14381  // The tests are written in this order to avoid overflow in unsigned
14382  // integer arithmetic.
14383 
14384  while (rest < dist
14385  and delta - rest >= ten_k
14386  and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
14387  {
14388  assert(buf[len - 1] != '0');
14389  buf[len - 1]--;
14390  rest += ten_k;
14391  }
14392 }
14393 
14398 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14399  diyfp M_minus, diyfp w, diyfp M_plus)
14400 {
14401  static_assert(kAlpha >= -60, "internal error");
14402  static_assert(kGamma <= -32, "internal error");
14403 
14404  // Generates the digits (and the exponent) of a decimal floating-point
14405  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14406  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14407  //
14408  // <--------------------------- delta ---->
14409  // <---- dist --------->
14410  // --------------[------------------+-------------------]--------------
14411  // M- w M+
14412  //
14413  // Grisu2 generates the digits of M+ from left to right and stops as soon as
14414  // V is in [M-,M+].
14415 
14416  assert(M_plus.e >= kAlpha);
14417  assert(M_plus.e <= kGamma);
14418 
14419  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14420  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
14421 
14422  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14423  //
14424  // M+ = f * 2^e
14425  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14426  // = ((p1 ) * 2^-e + (p2 )) * 2^e
14427  // = p1 + p2 * 2^e
14428 
14429  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14430 
14431  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.)
14432  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
14433 
14434  // 1)
14435  //
14436  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14437 
14438  assert(p1 > 0);
14439 
14440  std::uint32_t pow10;
14441  const int k = find_largest_pow10(p1, pow10);
14442 
14443  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14444  //
14445  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14446  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
14447  //
14448  // M+ = p1 + p2 * 2^e
14449  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
14450  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14451  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
14452  //
14453  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14454  //
14455  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14456  //
14457  // but stop as soon as
14458  //
14459  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14460 
14461  int n = k;
14462  while (n > 0)
14463  {
14464  // Invariants:
14465  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
14466  // pow10 = 10^(n-1) <= p1 < 10^n
14467  //
14468  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
14469  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
14470  //
14471  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
14472  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
14473  //
14474  assert(d <= 9);
14475  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14476  //
14477  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
14478  //
14479  p1 = r;
14480  n--;
14481  //
14482  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
14483  // pow10 = 10^n
14484  //
14485 
14486  // Now check if enough digits have been generated.
14487  // Compute
14488  //
14489  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
14490  //
14491  // Note:
14492  // Since rest and delta share the same exponent e, it suffices to
14493  // compare the significands.
14494  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
14495  if (rest <= delta)
14496  {
14497  // V = buffer * 10^n, with M- <= V <= M+.
14498 
14499  decimal_exponent += n;
14500 
14501  // We may now just stop. But instead look if the buffer could be
14502  // decremented to bring V closer to w.
14503  //
14504  // pow10 = 10^n is now 1 ulp in the decimal representation V.
14505  // The rounding procedure works with diyfp's with an implicit
14506  // exponent of e.
14507  //
14508  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
14509  //
14510  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
14511  grisu2_round(buffer, length, dist, delta, rest, ten_n);
14512 
14513  return;
14514  }
14515 
14516  pow10 /= 10;
14517  //
14518  // pow10 = 10^(n-1) <= p1 < 10^n
14519  // Invariants restored.
14520  }
14521 
14522  // 2)
14523  //
14524  // The digits of the integral part have been generated:
14525  //
14526  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
14527  // = buffer + p2 * 2^e
14528  //
14529  // Now generate the digits of the fractional part p2 * 2^e.
14530  //
14531  // Note:
14532  // No decimal point is generated: the exponent is adjusted instead.
14533  //
14534  // p2 actually represents the fraction
14535  //
14536  // p2 * 2^e
14537  // = p2 / 2^-e
14538  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
14539  //
14540  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
14541  //
14542  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
14543  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
14544  //
14545  // using
14546  //
14547  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
14548  // = ( d) * 2^-e + ( r)
14549  //
14550  // or
14551  // 10^m * p2 * 2^e = d + r * 2^e
14552  //
14553  // i.e.
14554  //
14555  // M+ = buffer + p2 * 2^e
14556  // = buffer + 10^-m * (d + r * 2^e)
14557  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
14558  //
14559  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
14560 
14561  assert(p2 > delta);
14562 
14563  int m = 0;
14564  for (;;)
14565  {
14566  // Invariant:
14567  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
14568  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
14569  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
14570  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
14571  //
14572  assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
14573  p2 *= 10;
14574  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
14575  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
14576  //
14577  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
14578  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
14579  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
14580  //
14581  assert(d <= 9);
14582  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14583  //
14584  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
14585  //
14586  p2 = r;
14587  m++;
14588  //
14589  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
14590  // Invariant restored.
14591 
14592  // Check if enough digits have been generated.
14593  //
14594  // 10^-m * p2 * 2^e <= delta * 2^e
14595  // p2 * 2^e <= 10^m * delta * 2^e
14596  // p2 <= 10^m * delta
14597  delta *= 10;
14598  dist *= 10;
14599  if (p2 <= delta)
14600  {
14601  break;
14602  }
14603  }
14604 
14605  // V = buffer * 10^-m, with M- <= V <= M+.
14606 
14607  decimal_exponent -= m;
14608 
14609  // 1 ulp in the decimal representation is now 10^-m.
14610  // Since delta and dist are now scaled by 10^m, we need to do the
14611  // same with ulp in order to keep the units in sync.
14612  //
14613  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
14614  //
14615  const std::uint64_t ten_m = one.f;
14616  grisu2_round(buffer, length, dist, delta, p2, ten_m);
14617 
14618  // By construction this algorithm generates the shortest possible decimal
14619  // number (Loitsch, Theorem 6.2) which rounds back to w.
14620  // For an input number of precision p, at least
14621  //
14622  // N = 1 + ceil(p * log_10(2))
14623  //
14624  // decimal digits are sufficient to identify all binary floating-point
14625  // numbers (Matula, "In-and-Out conversions").
14626  // This implies that the algorithm does not produce more than N decimal
14627  // digits.
14628  //
14629  // N = 17 for p = 53 (IEEE double precision)
14630  // N = 9 for p = 24 (IEEE single precision)
14631 }
14632 
14638 JSON_HEDLEY_NON_NULL(1)
14639 inline void grisu2(char* buf, int& len, int& decimal_exponent,
14640  diyfp m_minus, diyfp v, diyfp m_plus)
14641 {
14642  assert(m_plus.e == m_minus.e);
14643  assert(m_plus.e == v.e);
14644 
14645  // --------(-----------------------+-----------------------)-------- (A)
14646  // m- v m+
14647  //
14648  // --------------------(-----------+-----------------------)-------- (B)
14649  // m- v m+
14650  //
14651  // First scale v (and m- and m+) such that the exponent is in the range
14652  // [alpha, gamma].
14653 
14654  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
14655 
14656  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
14657 
14658  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
14659  const diyfp w = diyfp::mul(v, c_minus_k);
14660  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
14661  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
14662 
14663  // ----(---+---)---------------(---+---)---------------(---+---)----
14664  // w- w w+
14665  // = c*m- = c*v = c*m+
14666  //
14667  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
14668  // w+ are now off by a small amount.
14669  // In fact:
14670  //
14671  // w - v * 10^k < 1 ulp
14672  //
14673  // To account for this inaccuracy, add resp. subtract 1 ulp.
14674  //
14675  // --------+---[---------------(---+---)---------------]---+--------
14676  // w- M- w M+ w+
14677  //
14678  // Now any number in [M-, M+] (bounds included) will round to w when input,
14679  // regardless of how the input rounding algorithm breaks ties.
14680  //
14681  // And digit_gen generates the shortest possible such number in [M-, M+].
14682  // Note that this does not mean that Grisu2 always generates the shortest
14683  // possible number in the interval (m-, m+).
14684  const diyfp M_minus(w_minus.f + 1, w_minus.e);
14685  const diyfp M_plus (w_plus.f - 1, w_plus.e );
14686 
14687  decimal_exponent = -cached.k; // = -(-k) = k
14688 
14689  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
14690 }
14691 
14697 template <typename FloatType>
14698 JSON_HEDLEY_NON_NULL(1)
14699 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
14700 {
14701  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
14702  "internal error: not enough precision");
14703 
14704  assert(std::isfinite(value));
14705  assert(value > 0);
14706 
14707  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
14708  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
14709  // decimal representations are not exactly "short".
14710  //
14711  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
14712  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
14713  // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
14714  // does.
14715  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
14716  // representation using the corresponding std::from_chars function recovers value exactly". That
14717  // indicates that single precision floating-point numbers should be recovered using
14718  // 'std::strtof'.
14719  //
14720  // NB: If the neighbors are computed for single-precision numbers, there is a single float
14721  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
14722  // value is off by 1 ulp.
14723 #if 0
14724  const boundaries w = compute_boundaries(static_cast<double>(value));
14725 #else
14726  const boundaries w = compute_boundaries(value);
14727 #endif
14728 
14729  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
14730 }
14731 
14737 JSON_HEDLEY_NON_NULL(1)
14738 
14739 inline char* append_exponent(char* buf, int e)
14740 {
14741  assert(e > -1000);
14742  assert(e < 1000);
14743 
14744  if (e < 0)
14745  {
14746  e = -e;
14747  *buf++ = '-';
14748  }
14749  else
14750  {
14751  *buf++ = '+';
14752  }
14753 
14754  auto k = static_cast<std::uint32_t>(e);
14755  if (k < 10)
14756  {
14757  // Always print at least two digits in the exponent.
14758  // This is for compatibility with printf("%g").
14759  *buf++ = '0';
14760  *buf++ = static_cast<char>('0' + k);
14761  }
14762  else if (k < 100)
14763  {
14764  *buf++ = static_cast<char>('0' + k / 10);
14765  k %= 10;
14766  *buf++ = static_cast<char>('0' + k);
14767  }
14768  else
14769  {
14770  *buf++ = static_cast<char>('0' + k / 100);
14771  k %= 100;
14772  *buf++ = static_cast<char>('0' + k / 10);
14773  k %= 10;
14774  *buf++ = static_cast<char>('0' + k);
14775  }
14776 
14777  return buf;
14778 }
14779 
14789 JSON_HEDLEY_NON_NULL(1)
14790 
14791 inline char* format_buffer(char* buf, int len, int decimal_exponent,
14792  int min_exp, int max_exp)
14793 {
14794  assert(min_exp < 0);
14795  assert(max_exp > 0);
14796 
14797  const int k = len;
14798  const int n = len + decimal_exponent;
14799 
14800  // v = buf * 10^(n-k)
14801  // k is the length of the buffer (number of decimal digits)
14802  // n is the position of the decimal point relative to the start of the buffer.
14803 
14804  if (k <= n and n <= max_exp)
14805  {
14806  // digits[000]
14807  // len <= max_exp + 2
14808 
14809  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
14810  // Make it look like a floating-point number (#362, #378)
14811  buf[n + 0] = '.';
14812  buf[n + 1] = '0';
14813  return buf + (static_cast<size_t>(n) + 2);
14814  }
14815 
14816  if (0 < n and n <= max_exp)
14817  {
14818  // dig.its
14819  // len <= max_digits10 + 1
14820 
14821  assert(k > n);
14822 
14823  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
14824  buf[n] = '.';
14825  return buf + (static_cast<size_t>(k) + 1U);
14826  }
14827 
14828  if (min_exp < n and n <= 0)
14829  {
14830  // 0.[000]digits
14831  // len <= 2 + (-min_exp - 1) + max_digits10
14832 
14833  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
14834  buf[0] = '0';
14835  buf[1] = '.';
14836  std::memset(buf + 2, '0', static_cast<size_t>(-n));
14837  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
14838  }
14839 
14840  if (k == 1)
14841  {
14842  // dE+123
14843  // len <= 1 + 5
14844 
14845  buf += 1;
14846  }
14847  else
14848  {
14849  // d.igitsE+123
14850  // len <= max_digits10 + 1 + 5
14851 
14852  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
14853  buf[1] = '.';
14854  buf += 1 + static_cast<size_t>(k);
14855  }
14856 
14857  *buf++ = 'e';
14858  return append_exponent(buf, n - 1);
14859 }
14860 
14861 } // namespace dtoa_impl
14862 
14873 template <typename FloatType>
14874 JSON_HEDLEY_NON_NULL(1, 2)
14875 
14876 char* to_chars(char* first, const char* last, FloatType value)
14877 {
14878  static_cast<void>(last); // maybe unused - fix warning
14879  assert(std::isfinite(value));
14880 
14881  // Use signbit(value) instead of (value < 0) since signbit works for -0.
14882  if (std::signbit(value))
14883  {
14884  value = -value;
14885  *first++ = '-';
14886  }
14887 
14888  if (value == 0) // +-0
14889  {
14890  *first++ = '0';
14891  // Make it look like a floating-point number (#362, #378)
14892  *first++ = '.';
14893  *first++ = '0';
14894  return first;
14895  }
14896 
14897  assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
14898 
14899  // Compute v = buffer * 10^decimal_exponent.
14900  // The decimal digits are stored in the buffer, which needs to be interpreted
14901  // as an unsigned decimal integer.
14902  // len is the length of the buffer, i.e. the number of decimal digits.
14903  int len = 0;
14904  int decimal_exponent = 0;
14905  dtoa_impl::grisu2(first, len, decimal_exponent, value);
14906 
14907  assert(len <= std::numeric_limits<FloatType>::max_digits10);
14908 
14909  // Format the buffer like printf("%.*g", prec, value)
14910  constexpr int kMinExp = -4;
14911  // Use digits10 here to increase compatibility with version 2.
14912  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
14913 
14914  assert(last - first >= kMaxExp + 2);
14915  assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
14916  assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
14917 
14918  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
14919 }
14920 
14921 } // namespace detail
14922 } // namespace nlohmann
14923 
14924 // #include <nlohmann/detail/exceptions.hpp>
14925 
14926 // #include <nlohmann/detail/macro_scope.hpp>
14927 
14928 // #include <nlohmann/detail/meta/cpp_future.hpp>
14929 
14930 // #include <nlohmann/detail/output/binary_writer.hpp>
14931 
14932 // #include <nlohmann/detail/output/output_adapters.hpp>
14933 
14934 // #include <nlohmann/detail/value_t.hpp>
14935 
14936 
14937 namespace nlohmann
14938 {
14939 namespace detail
14940 {
14942 // serialization //
14944 
14946 enum class error_handler_t
14947 {
14948  strict,
14949  replace,
14950  ignore
14951 };
14952 
14953 template<typename BasicJsonType>
14954 class serializer
14955 {
14956  using string_t = typename BasicJsonType::string_t;
14957  using number_float_t = typename BasicJsonType::number_float_t;
14958  using number_integer_t = typename BasicJsonType::number_integer_t;
14959  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
14960  using binary_char_t = typename BasicJsonType::binary_t::value_type;
14961  static constexpr std::uint8_t UTF8_ACCEPT = 0;
14962  static constexpr std::uint8_t UTF8_REJECT = 1;
14963 
14964  public:
14970  serializer(output_adapter_t<char> s, const char ichar,
14971  error_handler_t error_handler_ = error_handler_t::strict)
14972  : o(std::move(s))
14973  , loc(std::localeconv())
14974  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
14975  , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
14976  , indent_char(ichar)
14977  , indent_string(512, indent_char)
14978  , error_handler(error_handler_)
14979  {}
14980 
14981  // delete because of pointer members
14982  serializer(const serializer&) = delete;
14983  serializer& operator=(const serializer&) = delete;
14984  serializer(serializer&&) = delete;
14985  serializer& operator=(serializer&&) = delete;
14986  ~serializer() = default;
14987 
15010  void dump(const BasicJsonType& val,
15011  const bool pretty_print,
15012  const bool ensure_ascii,
15013  const unsigned int indent_step,
15014  const unsigned int current_indent = 0)
15015  {
15016  switch (val.m_type)
15017  {
15018  case value_t::object:
15019  {
15020  if (val.m_value.object->empty())
15021  {
15022  o->write_characters("{}", 2);
15023  return;
15024  }
15025 
15026  if (pretty_print)
15027  {
15028  o->write_characters("{\n", 2);
15029 
15030  // variable to hold indentation for recursive calls
15031  const auto new_indent = current_indent + indent_step;
15032  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15033  {
15034  indent_string.resize(indent_string.size() * 2, ' ');
15035  }
15036 
15037  // first n-1 elements
15038  auto i = val.m_value.object->cbegin();
15039  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15040  {
15041  o->write_characters(indent_string.c_str(), new_indent);
15042  o->write_character('\"');
15043  dump_escaped(i->first, ensure_ascii);
15044  o->write_characters("\": ", 3);
15045  dump(i->second, true, ensure_ascii, indent_step, new_indent);
15046  o->write_characters(",\n", 2);
15047  }
15048 
15049  // last element
15050  assert(i != val.m_value.object->cend());
15051  assert(std::next(i) == val.m_value.object->cend());
15052  o->write_characters(indent_string.c_str(), new_indent);
15053  o->write_character('\"');
15054  dump_escaped(i->first, ensure_ascii);
15055  o->write_characters("\": ", 3);
15056  dump(i->second, true, ensure_ascii, indent_step, new_indent);
15057 
15058  o->write_character('\n');
15059  o->write_characters(indent_string.c_str(), current_indent);
15060  o->write_character('}');
15061  }
15062  else
15063  {
15064  o->write_character('{');
15065 
15066  // first n-1 elements
15067  auto i = val.m_value.object->cbegin();
15068  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15069  {
15070  o->write_character('\"');
15071  dump_escaped(i->first, ensure_ascii);
15072  o->write_characters("\":", 2);
15073  dump(i->second, false, ensure_ascii, indent_step, current_indent);
15074  o->write_character(',');
15075  }
15076 
15077  // last element
15078  assert(i != val.m_value.object->cend());
15079  assert(std::next(i) == val.m_value.object->cend());
15080  o->write_character('\"');
15081  dump_escaped(i->first, ensure_ascii);
15082  o->write_characters("\":", 2);
15083  dump(i->second, false, ensure_ascii, indent_step, current_indent);
15084 
15085  o->write_character('}');
15086  }
15087 
15088  return;
15089  }
15090 
15091  case value_t::array:
15092  {
15093  if (val.m_value.array->empty())
15094  {
15095  o->write_characters("[]", 2);
15096  return;
15097  }
15098 
15099  if (pretty_print)
15100  {
15101  o->write_characters("[\n", 2);
15102 
15103  // variable to hold indentation for recursive calls
15104  const auto new_indent = current_indent + indent_step;
15105  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15106  {
15107  indent_string.resize(indent_string.size() * 2, ' ');
15108  }
15109 
15110  // first n-1 elements
15111  for (auto i = val.m_value.array->cbegin();
15112  i != val.m_value.array->cend() - 1; ++i)
15113  {
15114  o->write_characters(indent_string.c_str(), new_indent);
15115  dump(*i, true, ensure_ascii, indent_step, new_indent);
15116  o->write_characters(",\n", 2);
15117  }
15118 
15119  // last element
15120  assert(not val.m_value.array->empty());
15121  o->write_characters(indent_string.c_str(), new_indent);
15122  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15123 
15124  o->write_character('\n');
15125  o->write_characters(indent_string.c_str(), current_indent);
15126  o->write_character(']');
15127  }
15128  else
15129  {
15130  o->write_character('[');
15131 
15132  // first n-1 elements
15133  for (auto i = val.m_value.array->cbegin();
15134  i != val.m_value.array->cend() - 1; ++i)
15135  {
15136  dump(*i, false, ensure_ascii, indent_step, current_indent);
15137  o->write_character(',');
15138  }
15139 
15140  // last element
15141  assert(not val.m_value.array->empty());
15142  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15143 
15144  o->write_character(']');
15145  }
15146 
15147  return;
15148  }
15149 
15150  case value_t::string:
15151  {
15152  o->write_character('\"');
15153  dump_escaped(*val.m_value.string, ensure_ascii);
15154  o->write_character('\"');
15155  return;
15156  }
15157 
15158  case value_t::binary:
15159  {
15160  if (pretty_print)
15161  {
15162  o->write_characters("{\n", 2);
15163 
15164  // variable to hold indentation for recursive calls
15165  const auto new_indent = current_indent + indent_step;
15166  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15167  {
15168  indent_string.resize(indent_string.size() * 2, ' ');
15169  }
15170 
15171  o->write_characters(indent_string.c_str(), new_indent);
15172 
15173  o->write_characters("\"bytes\": [", 10);
15174 
15175  if (not val.m_value.binary->empty())
15176  {
15177  for (auto i = val.m_value.binary->cbegin();
15178  i != val.m_value.binary->cend() - 1; ++i)
15179  {
15180  dump_integer(*i);
15181  o->write_characters(", ", 2);
15182  }
15183  dump_integer(val.m_value.binary->back());
15184  }
15185 
15186  o->write_characters("],\n", 3);
15187  o->write_characters(indent_string.c_str(), new_indent);
15188 
15189  o->write_characters("\"subtype\": ", 11);
15190  if (val.m_value.binary->has_subtype())
15191  {
15192  dump_integer(val.m_value.binary->subtype());
15193  }
15194  else
15195  {
15196  o->write_characters("null", 4);
15197  }
15198  o->write_character('\n');
15199  o->write_characters(indent_string.c_str(), current_indent);
15200  o->write_character('}');
15201  }
15202  else
15203  {
15204  o->write_characters("{\"bytes\":[", 10);
15205 
15206  if (not val.m_value.binary->empty())
15207  {
15208  for (auto i = val.m_value.binary->cbegin();
15209  i != val.m_value.binary->cend() - 1; ++i)
15210  {
15211  dump_integer(*i);
15212  o->write_character(',');
15213  }
15214  dump_integer(val.m_value.binary->back());
15215  }
15216 
15217  o->write_characters("],\"subtype\":", 12);
15218  if (val.m_value.binary->has_subtype())
15219  {
15220  dump_integer(val.m_value.binary->subtype());
15221  o->write_character('}');
15222  }
15223  else
15224  {
15225  o->write_characters("null}", 5);
15226  }
15227  }
15228  return;
15229  }
15230 
15231  case value_t::boolean:
15232  {
15233  if (val.m_value.boolean)
15234  {
15235  o->write_characters("true", 4);
15236  }
15237  else
15238  {
15239  o->write_characters("false", 5);
15240  }
15241  return;
15242  }
15243 
15244  case value_t::number_integer:
15245  {
15246  dump_integer(val.m_value.number_integer);
15247  return;
15248  }
15249 
15250  case value_t::number_unsigned:
15251  {
15252  dump_integer(val.m_value.number_unsigned);
15253  return;
15254  }
15255 
15256  case value_t::number_float:
15257  {
15258  dump_float(val.m_value.number_float);
15259  return;
15260  }
15261 
15262  case value_t::discarded:
15263  {
15264  o->write_characters("<discarded>", 11);
15265  return;
15266  }
15267 
15268  case value_t::null:
15269  {
15270  o->write_characters("null", 4);
15271  return;
15272  }
15273 
15274  default: // LCOV_EXCL_LINE
15275  assert(false); // LCOV_EXCL_LINE
15276  }
15277  }
15278 
15279  private:
15294  void dump_escaped(const string_t& s, const bool ensure_ascii)
15295  {
15296  std::uint32_t codepoint;
15297  std::uint8_t state = UTF8_ACCEPT;
15298  std::size_t bytes = 0; // number of bytes written to string_buffer
15299 
15300  // number of bytes written at the point of the last valid byte
15301  std::size_t bytes_after_last_accept = 0;
15302  std::size_t undumped_chars = 0;
15303 
15304  for (std::size_t i = 0; i < s.size(); ++i)
15305  {
15306  const auto byte = static_cast<uint8_t>(s[i]);
15307 
15308  switch (decode(state, codepoint, byte))
15309  {
15310  case UTF8_ACCEPT: // decode found a new code point
15311  {
15312  switch (codepoint)
15313  {
15314  case 0x08: // backspace
15315  {
15316  string_buffer[bytes++] = '\\';
15317  string_buffer[bytes++] = 'b';
15318  break;
15319  }
15320 
15321  case 0x09: // horizontal tab
15322  {
15323  string_buffer[bytes++] = '\\';
15324  string_buffer[bytes++] = 't';
15325  break;
15326  }
15327 
15328  case 0x0A: // newline
15329  {
15330  string_buffer[bytes++] = '\\';
15331  string_buffer[bytes++] = 'n';
15332  break;
15333  }
15334 
15335  case 0x0C: // formfeed
15336  {
15337  string_buffer[bytes++] = '\\';
15338  string_buffer[bytes++] = 'f';
15339  break;
15340  }
15341 
15342  case 0x0D: // carriage return
15343  {
15344  string_buffer[bytes++] = '\\';
15345  string_buffer[bytes++] = 'r';
15346  break;
15347  }
15348 
15349  case 0x22: // quotation mark
15350  {
15351  string_buffer[bytes++] = '\\';
15352  string_buffer[bytes++] = '\"';
15353  break;
15354  }
15355 
15356  case 0x5C: // reverse solidus
15357  {
15358  string_buffer[bytes++] = '\\';
15359  string_buffer[bytes++] = '\\';
15360  break;
15361  }
15362 
15363  default:
15364  {
15365  // escape control characters (0x00..0x1F) or, if
15366  // ensure_ascii parameter is used, non-ASCII characters
15367  if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
15368  {
15369  if (codepoint <= 0xFFFF)
15370  {
15371  (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15372  static_cast<std::uint16_t>(codepoint));
15373  bytes += 6;
15374  }
15375  else
15376  {
15377  (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15378  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15379  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15380  bytes += 12;
15381  }
15382  }
15383  else
15384  {
15385  // copy byte to buffer (all previous bytes
15386  // been copied have in default case above)
15387  string_buffer[bytes++] = s[i];
15388  }
15389  break;
15390  }
15391  }
15392 
15393  // write buffer and reset index; there must be 13 bytes
15394  // left, as this is the maximal number of bytes to be
15395  // written ("\uxxxx\uxxxx\0") for one code point
15396  if (string_buffer.size() - bytes < 13)
15397  {
15398  o->write_characters(string_buffer.data(), bytes);
15399  bytes = 0;
15400  }
15401 
15402  // remember the byte position of this accept
15403  bytes_after_last_accept = bytes;
15404  undumped_chars = 0;
15405  break;
15406  }
15407 
15408  case UTF8_REJECT: // decode found invalid UTF-8 byte
15409  {
15410  switch (error_handler)
15411  {
15412  case error_handler_t::strict:
15413  {
15414  std::string sn(3, '\0');
15415  (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15416  JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15417  }
15418 
15419  case error_handler_t::ignore:
15420  case error_handler_t::replace:
15421  {
15422  // in case we saw this character the first time, we
15423  // would like to read it again, because the byte
15424  // may be OK for itself, but just not OK for the
15425  // previous sequence
15426  if (undumped_chars > 0)
15427  {
15428  --i;
15429  }
15430 
15431  // reset length buffer to the last accepted index;
15432  // thus removing/ignoring the invalid characters
15433  bytes = bytes_after_last_accept;
15434 
15435  if (error_handler == error_handler_t::replace)
15436  {
15437  // add a replacement character
15438  if (ensure_ascii)
15439  {
15440  string_buffer[bytes++] = '\\';
15441  string_buffer[bytes++] = 'u';
15442  string_buffer[bytes++] = 'f';
15443  string_buffer[bytes++] = 'f';
15444  string_buffer[bytes++] = 'f';
15445  string_buffer[bytes++] = 'd';
15446  }
15447  else
15448  {
15449  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15450  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15451  string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15452  }
15453 
15454  // write buffer and reset index; there must be 13 bytes
15455  // left, as this is the maximal number of bytes to be
15456  // written ("\uxxxx\uxxxx\0") for one code point
15457  if (string_buffer.size() - bytes < 13)
15458  {
15459  o->write_characters(string_buffer.data(), bytes);
15460  bytes = 0;
15461  }
15462 
15463  bytes_after_last_accept = bytes;
15464  }
15465 
15466  undumped_chars = 0;
15467 
15468  // continue processing the string
15469  state = UTF8_ACCEPT;
15470  break;
15471  }
15472 
15473  default: // LCOV_EXCL_LINE
15474  assert(false); // LCOV_EXCL_LINE
15475  }
15476  break;
15477  }
15478 
15479  default: // decode found yet incomplete multi-byte code point
15480  {
15481  if (not ensure_ascii)
15482  {
15483  // code point will not be escaped - copy byte to buffer
15484  string_buffer[bytes++] = s[i];
15485  }
15486  ++undumped_chars;
15487  break;
15488  }
15489  }
15490  }
15491 
15492  // we finished processing the string
15493  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
15494  {
15495  // write buffer
15496  if (bytes > 0)
15497  {
15498  o->write_characters(string_buffer.data(), bytes);
15499  }
15500  }
15501  else
15502  {
15503  // we finish reading, but do not accept: string was incomplete
15504  switch (error_handler)
15505  {
15506  case error_handler_t::strict:
15507  {
15508  std::string sn(3, '\0');
15509  (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
15510  JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
15511  }
15512 
15513  case error_handler_t::ignore:
15514  {
15515  // write all accepted bytes
15516  o->write_characters(string_buffer.data(), bytes_after_last_accept);
15517  break;
15518  }
15519 
15520  case error_handler_t::replace:
15521  {
15522  // write all accepted bytes
15523  o->write_characters(string_buffer.data(), bytes_after_last_accept);
15524  // add a replacement character
15525  if (ensure_ascii)
15526  {
15527  o->write_characters("\\ufffd", 6);
15528  }
15529  else
15530  {
15531  o->write_characters("\xEF\xBF\xBD", 3);
15532  }
15533  break;
15534  }
15535 
15536  default: // LCOV_EXCL_LINE
15537  assert(false); // LCOV_EXCL_LINE
15538  }
15539  }
15540  }
15541 
15550  inline unsigned int count_digits(number_unsigned_t x) noexcept
15551  {
15552  unsigned int n_digits = 1;
15553  for (;;)
15554  {
15555  if (x < 10)
15556  {
15557  return n_digits;
15558  }
15559  if (x < 100)
15560  {
15561  return n_digits + 1;
15562  }
15563  if (x < 1000)
15564  {
15565  return n_digits + 2;
15566  }
15567  if (x < 10000)
15568  {
15569  return n_digits + 3;
15570  }
15571  x = x / 10000u;
15572  n_digits += 4;
15573  }
15574  }
15575 
15585  template<typename NumberType, detail::enable_if_t<
15586  std::is_same<NumberType, number_unsigned_t>::value or
15587  std::is_same<NumberType, number_integer_t>::value or
15588  std::is_same<NumberType, binary_char_t>::value,
15589  int> = 0>
15590  void dump_integer(NumberType x)
15591  {
15592  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
15593  {
15594  {
15595  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
15596  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
15597  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
15598  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
15599  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
15600  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
15601  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
15602  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
15603  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
15604  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
15605  }
15606  };
15607 
15608  // special case for "0"
15609  if (x == 0)
15610  {
15611  o->write_character('0');
15612  return;
15613  }
15614 
15615  // use a pointer to fill the buffer
15616  auto buffer_ptr = number_buffer.begin();
15617 
15618  const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
15619  number_unsigned_t abs_value;
15620 
15621  unsigned int n_chars;
15622 
15623  if (is_negative)
15624  {
15625  *buffer_ptr = '-';
15626  abs_value = remove_sign(static_cast<number_integer_t>(x));
15627 
15628  // account one more byte for the minus sign
15629  n_chars = 1 + count_digits(abs_value);
15630  }
15631  else
15632  {
15633  abs_value = static_cast<number_unsigned_t>(x);
15634  n_chars = count_digits(abs_value);
15635  }
15636 
15637  // spare 1 byte for '\0'
15638  assert(n_chars < number_buffer.size() - 1);
15639 
15640  // jump to the end to generate the string from backward
15641  // so we later avoid reversing the result
15642  buffer_ptr += n_chars;
15643 
15644  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
15645  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
15646  while (abs_value >= 100)
15647  {
15648  const auto digits_index = static_cast<unsigned>((abs_value % 100));
15649  abs_value /= 100;
15650  *(--buffer_ptr) = digits_to_99[digits_index][1];
15651  *(--buffer_ptr) = digits_to_99[digits_index][0];
15652  }
15653 
15654  if (abs_value >= 10)
15655  {
15656  const auto digits_index = static_cast<unsigned>(abs_value);
15657  *(--buffer_ptr) = digits_to_99[digits_index][1];
15658  *(--buffer_ptr) = digits_to_99[digits_index][0];
15659  }
15660  else
15661  {
15662  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
15663  }
15664 
15665  o->write_characters(number_buffer.data(), n_chars);
15666  }
15667 
15676  void dump_float(number_float_t x)
15677  {
15678  // NaN / inf
15679  if (not std::isfinite(x))
15680  {
15681  o->write_characters("null", 4);
15682  return;
15683  }
15684 
15685  // If number_float_t is an IEEE-754 single or double precision number,
15686  // use the Grisu2 algorithm to produce short numbers which are
15687  // guaranteed to round-trip, using strtof and strtod, resp.
15688  //
15689  // NB: The test below works if <long double> == <double>.
15690  static constexpr bool is_ieee_single_or_double
15691  = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
15692  (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
15693 
15694  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
15695  }
15696 
15697  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
15698  {
15699  char* begin = number_buffer.data();
15700  char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
15701 
15702  o->write_characters(begin, static_cast<size_t>(end - begin));
15703  }
15704 
15705  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
15706  {
15707  // get number of digits for a float -> text -> float round-trip
15708  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
15709 
15710  // the actual conversion
15711  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
15712 
15713  // negative value indicates an error
15714  assert(len > 0);
15715  // check if buffer was large enough
15716  assert(static_cast<std::size_t>(len) < number_buffer.size());
15717 
15718  // erase thousands separator
15719  if (thousands_sep != '\0')
15720  {
15721  const auto end = std::remove(number_buffer.begin(),
15722  number_buffer.begin() + len, thousands_sep);
15723  std::fill(end, number_buffer.end(), '\0');
15724  assert((end - number_buffer.begin()) <= len);
15725  len = (end - number_buffer.begin());
15726  }
15727 
15728  // convert decimal point to '.'
15729  if (decimal_point != '\0' and decimal_point != '.')
15730  {
15731  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
15732  if (dec_pos != number_buffer.end())
15733  {
15734  *dec_pos = '.';
15735  }
15736  }
15737 
15738  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
15739 
15740  // determine if need to append ".0"
15741  const bool value_is_int_like =
15742  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
15743  [](char c)
15744  {
15745  return c == '.' or c == 'e';
15746  });
15747 
15748  if (value_is_int_like)
15749  {
15750  o->write_characters(".0", 2);
15751  }
15752  }
15753 
15775  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
15776  {
15777  static const std::array<std::uint8_t, 400> utf8d =
15778  {
15779  {
15780  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
15781  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
15782  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
15783  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
15784  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
15785  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
15786  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
15787  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
15788  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
15789  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
15790  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
15791  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
15792  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
15793  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
15794  }
15795  };
15796 
15797  const std::uint8_t type = utf8d[byte];
15798 
15799  codep = (state != UTF8_ACCEPT)
15800  ? (byte & 0x3fu) | (codep << 6u)
15801  : (0xFFu >> type) & (byte);
15802 
15803  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
15804  assert(index < 400);
15805  state = utf8d[index];
15806  return state;
15807  }
15808 
15809  /*
15810  * Overload to make the compiler happy while it is instantiating
15811  * dump_integer for number_unsigned_t.
15812  * Must never be called.
15813  */
15814  number_unsigned_t remove_sign(number_unsigned_t x)
15815  {
15816  assert(false); // LCOV_EXCL_LINE
15817  return x; // LCOV_EXCL_LINE
15818  }
15819 
15820  /*
15821  * Helper function for dump_integer
15822  *
15823  * This function takes a negative signed integer and returns its absolute
15824  * value as unsigned integer. The plus/minus shuffling is necessary as we can
15825  * not directly remove the sign of an arbitrary signed integer as the
15826  * absolute values of INT_MIN and INT_MAX are usually not the same. See
15827  * #1708 for details.
15828  */
15829  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
15830  {
15831  assert(x < 0 and x < (std::numeric_limits<number_integer_t>::max)());
15832  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
15833  }
15834 
15835  private:
15837  output_adapter_t<char> o = nullptr;
15838 
15840  std::array<char, 64> number_buffer{{}};
15841 
15843  const std::lconv* loc = nullptr;
15845  const char thousands_sep = '\0';
15847  const char decimal_point = '\0';
15848 
15850  std::array<char, 512> string_buffer{{}};
15851 
15853  const char indent_char;
15855  string_t indent_string;
15856 
15858  const error_handler_t error_handler;
15859 };
15860 } // namespace detail
15861 } // namespace nlohmann
15862 
15863 // #include <nlohmann/detail/value_t.hpp>
15864 
15865 // #include <nlohmann/json_fwd.hpp>
15866 
15867 
15873 namespace nlohmann
15874 {
15875 
15960 NLOHMANN_BASIC_JSON_TPL_DECLARATION
15962 {
15963  private:
15964  template<detail::value_t> friend struct detail::external_constructor;
15965  friend ::nlohmann::json_pointer<basic_json>;
15966 
15967  template<typename BasicJsonType, typename InputType>
15968  friend class ::nlohmann::detail::parser;
15969  friend ::nlohmann::detail::serializer<basic_json>;
15970  template<typename BasicJsonType>
15971  friend class ::nlohmann::detail::iter_impl;
15972  template<typename BasicJsonType, typename CharType>
15973  friend class ::nlohmann::detail::binary_writer;
15974  template<typename BasicJsonType, typename InputType, typename SAX>
15975  friend class ::nlohmann::detail::binary_reader;
15976  template<typename BasicJsonType>
15977  friend class ::nlohmann::detail::json_sax_dom_parser;
15978  template<typename BasicJsonType>
15979  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
15980 
15982  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
15983 
15984  // convenience aliases for types residing in namespace detail;
15985  using lexer = ::nlohmann::detail::lexer_base<basic_json>;
15986 
15987  template<typename InputAdapterType>
15988  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
15989  InputAdapterType adapter,
15990  detail::parser_callback_t<basic_json>cb = nullptr,
15991  bool allow_exceptions = true
15992  )
15993  {
15994  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), std::move(cb), allow_exceptions);
15995  }
15996 
15997  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
15998  template<typename BasicJsonType>
15999  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16000  template<typename BasicJsonType>
16001  using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16002  template<typename Iterator>
16003  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16004  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16005 
16006  template<typename CharType>
16007  using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16008 
16009  template<typename InputType>
16010  using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16011  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16012 
16013  using serializer = ::nlohmann::detail::serializer<basic_json>;
16014 
16015  public:
16016  using value_t = detail::value_t;
16019  template<typename T, typename SFINAE>
16020  using json_serializer = JSONSerializer<T, SFINAE>;
16022  using error_handler_t = detail::error_handler_t;
16024  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16025 
16026  using input_format_t = detail::input_format_t;
16029 
16031  // exceptions //
16033 
16037 
16039  using exception = detail::exception;
16041  using parse_error = detail::parse_error;
16043  using invalid_iterator = detail::invalid_iterator;
16045  using type_error = detail::type_error;
16047  using out_of_range = detail::out_of_range;
16049  using other_error = detail::other_error;
16050 
16052 
16053 
16055  // container types //
16057 
16062 
16065 
16069  using const_reference = const value_type&;
16070 
16072  using difference_type = std::ptrdiff_t;
16074  using size_type = std::size_t;
16075 
16077  using allocator_type = AllocatorType<basic_json>;
16078 
16080  using pointer = typename std::allocator_traits<allocator_type>::pointer;
16082  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16083 
16085  using iterator = iter_impl<basic_json>;
16087  using const_iterator = iter_impl<const basic_json>;
16089  using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16091  using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16092 
16094 
16095 
16100  {
16101  return allocator_type();
16102  }
16103 
16130 
16131  static basic_json meta()
16132  {
16133  basic_json result;
16134 
16135  result["copyright"] = "(C) 2013-2017 Niels Lohmann";
16136  result["name"] = "JSON for Modern C++";
16137  result["url"] = "https://github.com/nlohmann/json";
16138  result["version"]["string"] =
16139  std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16140  std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16141  std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16142  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16143  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16144  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16145 
16146 #ifdef _WIN32
16147  result["platform"] = "win32";
16148 #elif defined __linux__
16149  result["platform"] = "linux";
16150 #elif defined __APPLE__
16151  result["platform"] = "apple";
16152 #elif defined __unix__
16153  result["platform"] = "unix";
16154 #else
16155  result["platform"] = "unknown";
16156 #endif
16157 
16158 #if defined(__ICC) || defined(__INTEL_COMPILER)
16159  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16160 #elif defined(__clang__)
16161  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16162 #elif defined(__GNUC__) || defined(__GNUG__)
16163  result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16164 #elif defined(__HP_cc) || defined(__HP_aCC)
16165  result["compiler"] = "hp"
16166 #elif defined(__IBMCPP__)
16167  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16168 #elif defined(_MSC_VER)
16169  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16170 #elif defined(__PGI)
16171  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16172 #elif defined(__SUNPRO_CC)
16173  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16174 #else
16175  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16176 #endif
16177 
16178 #ifdef __cplusplus
16179  result["compiler"]["c++"] = std::to_string(__cplusplus);
16180 #else
16181  result["compiler"]["c++"] = "unknown";
16182 #endif
16183  return result;
16184  }
16185 
16186 
16188  // JSON value data types //
16190 
16195 
16196 #if defined(JSON_HAS_CPP_14)
16197  // Use transparent comparator if possible, combined with perfect forwarding
16198  // on find() and count() calls prevents unnecessary string construction.
16199  using object_comparator_t = std::less<>;
16200 #else
16201  using object_comparator_t = std::less<StringType>;
16202 #endif
16203 
16287  using object_t = ObjectType<StringType,
16288  basic_json,
16290  AllocatorType<std::pair<const StringType,
16291  basic_json>>>;
16292 
16337  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16338 
16390  using string_t = StringType;
16391 
16416  using boolean_t = BooleanType;
16417 
16488  using number_integer_t = NumberIntegerType;
16489 
16559  using number_unsigned_t = NumberUnsignedType;
16560 
16627  using number_float_t = NumberFloatType;
16628 
16700 
16701  private:
16702 
16704  template<typename T, typename... Args>
16705 
16706  static T* create(Args&& ... args)
16707  {
16708  AllocatorType<T> alloc;
16709  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
16710 
16711  auto deleter = [&](T * object)
16712  {
16713  AllocatorTraits::deallocate(alloc, object, 1);
16714  };
16715  std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
16716  AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
16717  assert(object != nullptr);
16718  return object.release();
16719  }
16720 
16722  // JSON value storage //
16724 
16750  union json_value
16751  {
16753  object_t* object;
16755  array_t* array;
16757  string_t* string;
16759  binary_t* binary;
16761  boolean_t boolean;
16763  number_integer_t number_integer;
16765  number_unsigned_t number_unsigned;
16767  number_float_t number_float;
16768 
16770  json_value() = default;
16772  json_value(boolean_t v) noexcept : boolean(v) {}
16774  json_value(number_integer_t v) noexcept : number_integer(v) {}
16776  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
16778  json_value(number_float_t v) noexcept : number_float(v) {}
16780  json_value(value_t t)
16781  {
16782  switch (t)
16783  {
16784  case value_t::object:
16785  {
16786  object = create<object_t>();
16787  break;
16788  }
16789 
16790  case value_t::array:
16791  {
16792  array = create<array_t>();
16793  break;
16794  }
16795 
16796  case value_t::string:
16797  {
16798  string = create<string_t>("");
16799  break;
16800  }
16801 
16802  case value_t::binary:
16803  {
16804  binary = create<binary_t>();
16805  break;
16806  }
16807 
16808  case value_t::boolean:
16809  {
16810  boolean = boolean_t(false);
16811  break;
16812  }
16813 
16814  case value_t::number_integer:
16815  {
16816  number_integer = number_integer_t(0);
16817  break;
16818  }
16819 
16820  case value_t::number_unsigned:
16821  {
16822  number_unsigned = number_unsigned_t(0);
16823  break;
16824  }
16825 
16826  case value_t::number_float:
16827  {
16828  number_float = number_float_t(0.0);
16829  break;
16830  }
16831 
16832  case value_t::null:
16833  {
16834  object = nullptr; // silence warning, see #821
16835  break;
16836  }
16837 
16838  default:
16839  {
16840  object = nullptr; // silence warning, see #821
16841  if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
16842  {
16843  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.7.3")); // LCOV_EXCL_LINE
16844  }
16845  break;
16846  }
16847  }
16848  }
16849 
16851  json_value(const string_t& value)
16852  {
16853  string = create<string_t>(value);
16854  }
16855 
16857  json_value(string_t&& value)
16858  {
16859  string = create<string_t>(std::move(value));
16860  }
16861 
16863  json_value(const object_t& value)
16864  {
16865  object = create<object_t>(value);
16866  }
16867 
16869  json_value(object_t&& value)
16870  {
16871  object = create<object_t>(std::move(value));
16872  }
16873 
16875  json_value(const array_t& value)
16876  {
16877  array = create<array_t>(value);
16878  }
16879 
16881  json_value(array_t&& value)
16882  {
16883  array = create<array_t>(std::move(value));
16884  }
16885 
16887  json_value(const typename binary_t::container_type& value)
16888  {
16889  binary = create<binary_t>(value);
16890  }
16891 
16893  json_value(typename binary_t::container_type&& value)
16894  {
16895  binary = create<binary_t>(std::move(value));
16896  }
16897 
16899  json_value(const binary_t& value)
16900  {
16901  binary = create<binary_t>(value);
16902  }
16903 
16905  json_value(binary_t&& value)
16906  {
16907  binary = create<binary_t>(std::move(value));
16908  }
16909 
16910  void destroy(value_t t) noexcept
16911  {
16912  // flatten the current json_value to a heap-allocated stack
16913  std::vector<basic_json> stack;
16914 
16915  // move the top-level items to stack
16916  if (t == value_t::array)
16917  {
16918  stack.reserve(array->size());
16919  std::move(array->begin(), array->end(), std::back_inserter(stack));
16920  }
16921  else if (t == value_t::object)
16922  {
16923  stack.reserve(object->size());
16924  for (auto&& it : *object)
16925  {
16926  stack.push_back(std::move(it.second));
16927  }
16928  }
16929 
16930  while (not stack.empty())
16931  {
16932  // move the last item to local variable to be processed
16933  basic_json current_item(std::move(stack.back()));
16934  stack.pop_back();
16935 
16936  // if current_item is array/object, move
16937  // its children to the stack to be processed later
16938  if (current_item.is_array())
16939  {
16940  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
16941  std::back_inserter(stack));
16942 
16943  current_item.m_value.array->clear();
16944  }
16945  else if (current_item.is_object())
16946  {
16947  for (auto&& it : *current_item.m_value.object)
16948  {
16949  stack.push_back(std::move(it.second));
16950  }
16951 
16952  current_item.m_value.object->clear();
16953  }
16954 
16955  // it's now safe that current_item get destructed
16956  // since it doesn't have any children
16957  }
16958 
16959  switch (t)
16960  {
16961  case value_t::object:
16962  {
16963  AllocatorType<object_t> alloc;
16964  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
16965  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
16966  break;
16967  }
16968 
16969  case value_t::array:
16970  {
16971  AllocatorType<array_t> alloc;
16972  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
16973  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
16974  break;
16975  }
16976 
16977  case value_t::string:
16978  {
16979  AllocatorType<string_t> alloc;
16980  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
16981  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
16982  break;
16983  }
16984 
16985  case value_t::binary:
16986  {
16987  AllocatorType<binary_t> alloc;
16988  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
16989  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
16990  break;
16991  }
16992 
16993  default:
16994  {
16995  break;
16996  }
16997  }
16998  }
16999  };
17000 
17010  void assert_invariant() const noexcept
17011  {
17012  assert(m_type != value_t::object or m_value.object != nullptr);
17013  assert(m_type != value_t::array or m_value.array != nullptr);
17014  assert(m_type != value_t::string or m_value.string != nullptr);
17015  assert(m_type != value_t::binary or m_value.binary != nullptr);
17016  }
17017 
17018  public:
17020  // JSON parser callback //
17022 
17038  using parse_event_t = detail::parse_event_t;
17039 
17089  using parser_callback_t = detail::parser_callback_t<basic_json>;
17090 
17092  // constructors //
17094 
17099 
17130  basic_json(const value_t v)
17131  : m_type(v), m_value(v)
17132  {
17133  assert_invariant();
17134  }
17135 
17154  basic_json(std::nullptr_t = nullptr) noexcept
17155  : basic_json(value_t::null)
17156  {
17157  assert_invariant();
17158  }
17159 
17223  template <typename CompatibleType,
17224  typename U = detail::uncvref_t<CompatibleType>,
17225  detail::enable_if_t<
17226  not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
17227  basic_json(CompatibleType && val) noexcept(noexcept(
17228  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17229  std::forward<CompatibleType>(val))))
17230  {
17231  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17232  assert_invariant();
17233  }
17234 
17261  template <typename BasicJsonType,
17262  detail::enable_if_t<
17263  detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
17264  basic_json(const BasicJsonType& val)
17265  {
17266  using other_boolean_t = typename BasicJsonType::boolean_t;
17267  using other_number_float_t = typename BasicJsonType::number_float_t;
17268  using other_number_integer_t = typename BasicJsonType::number_integer_t;
17269  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17270  using other_string_t = typename BasicJsonType::string_t;
17271  using other_object_t = typename BasicJsonType::object_t;
17272  using other_array_t = typename BasicJsonType::array_t;
17273  using other_binary_t = typename BasicJsonType::binary_t;
17274 
17275  switch (val.type())
17276  {
17277  case value_t::boolean:
17278  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17279  break;
17280  case value_t::number_float:
17281  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17282  break;
17283  case value_t::number_integer:
17284  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17285  break;
17286  case value_t::number_unsigned:
17287  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17288  break;
17289  case value_t::string:
17290  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17291  break;
17292  case value_t::object:
17293  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17294  break;
17295  case value_t::array:
17296  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17297  break;
17298  case value_t::binary:
17299  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
17300  break;
17301  case value_t::null:
17302  *this = nullptr;
17303  break;
17304  case value_t::discarded:
17305  m_type = value_t::discarded;
17306  break;
17307  default: // LCOV_EXCL_LINE
17308  assert(false); // LCOV_EXCL_LINE
17309  }
17310  assert_invariant();
17311  }
17312 
17388  bool type_deduction = true,
17389  value_t manual_type = value_t::array)
17390  {
17391  // check if each element is an array with two elements whose first
17392  // element is a string
17393  bool is_an_object = std::all_of(init.begin(), init.end(),
17394  [](const detail::json_ref<basic_json>& element_ref)
17395  {
17396  return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
17397  });
17398 
17399  // adjust type if type deduction is not wanted
17400  if (not type_deduction)
17401  {
17402  // if array is wanted, do not create an object though possible
17403  if (manual_type == value_t::array)
17404  {
17405  is_an_object = false;
17406  }
17407 
17408  // if object is wanted but impossible, throw an exception
17409  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object and not is_an_object))
17410  {
17411  JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
17412  }
17413  }
17414 
17415  if (is_an_object)
17416  {
17417  // the initializer list is a list of pairs -> create object
17418  m_type = value_t::object;
17419  m_value = value_t::object;
17420 
17421  std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
17422  {
17423  auto element = element_ref.moved_or_copied();
17424  m_value.object->emplace(
17425  std::move(*((*element.m_value.array)[0].m_value.string)),
17426  std::move((*element.m_value.array)[1]));
17427  });
17428  }
17429  else
17430  {
17431  // the initializer list describes an array -> create array
17432  m_type = value_t::array;
17433  m_value.array = create<array_t>(init.begin(), init.end());
17434  }
17435 
17436  assert_invariant();
17437  }
17438 
17466 
17467  static basic_json binary(const typename binary_t::container_type& init)
17468  {
17469  auto res = basic_json();
17470  res.m_type = value_t::binary;
17471  res.m_value = init;
17472  return res;
17473  }
17474 
17503 
17504  static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
17505  {
17506  auto res = basic_json();
17507  res.m_type = value_t::binary;
17508  res.m_value = binary_t(init, subtype);
17509  return res;
17510  }
17511 
17513 
17515  {
17516  auto res = basic_json();
17517  res.m_type = value_t::binary;
17518  res.m_value = std::move(init);
17519  return res;
17520  }
17521 
17523 
17524  static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
17525  {
17526  auto res = basic_json();
17527  res.m_type = value_t::binary;
17528  res.m_value = binary_t(std::move(init), subtype);
17529  return res;
17530  }
17531 
17569 
17571  {
17572  return basic_json(init, false, value_t::array);
17573  }
17574 
17613 
17615  {
17616  return basic_json(init, false, value_t::object);
17617  }
17618 
17642  : m_type(value_t::array)
17643  {
17644  m_value.array = create<array_t>(cnt, val);
17645  assert_invariant();
17646  }
17647 
17703  template<class InputIT, typename std::enable_if<
17704  std::is_same<InputIT, typename basic_json_t::iterator>::value or
17705  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
17706  basic_json(InputIT first, InputIT last)
17707  {
17708  assert(first.m_object != nullptr);
17709  assert(last.m_object != nullptr);
17710 
17711  // make sure iterator fits the current value
17712  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
17713  {
17714  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
17715  }
17716 
17717  // copy type from first iterator
17718  m_type = first.m_object->m_type;
17719 
17720  // check if iterator range is complete for primitive values
17721  switch (m_type)
17722  {
17723  case value_t::boolean:
17724  case value_t::number_float:
17725  case value_t::number_integer:
17726  case value_t::number_unsigned:
17727  case value_t::string:
17728  {
17729  if (JSON_HEDLEY_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
17730  or not last.m_it.primitive_iterator.is_end()))
17731  {
17732  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
17733  }
17734  break;
17735  }
17736 
17737  default:
17738  break;
17739  }
17740 
17741  switch (m_type)
17742  {
17743  case value_t::number_integer:
17744  {
17745  m_value.number_integer = first.m_object->m_value.number_integer;
17746  break;
17747  }
17748 
17749  case value_t::number_unsigned:
17750  {
17751  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
17752  break;
17753  }
17754 
17755  case value_t::number_float:
17756  {
17757  m_value.number_float = first.m_object->m_value.number_float;
17758  break;
17759  }
17760 
17761  case value_t::boolean:
17762  {
17763  m_value.boolean = first.m_object->m_value.boolean;
17764  break;
17765  }
17766 
17767  case value_t::string:
17768  {
17769  m_value = *first.m_object->m_value.string;
17770  break;
17771  }
17772 
17773  case value_t::object:
17774  {
17775  m_value.object = create<object_t>(first.m_it.object_iterator,
17776  last.m_it.object_iterator);
17777  break;
17778  }
17779 
17780  case value_t::array:
17781  {
17782  m_value.array = create<array_t>(first.m_it.array_iterator,
17783  last.m_it.array_iterator);
17784  break;
17785  }
17786 
17787  case value_t::binary:
17788  {
17789  m_value = *first.m_object->m_value.binary;
17790  break;
17791  }
17792 
17793  default:
17794  JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
17795  std::string(first.m_object->type_name())));
17796  }
17797 
17798  assert_invariant();
17799  }
17800 
17801 
17803  // other constructors and destructor //
17805 
17806  template <typename JsonRef,
17807  detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
17808  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
17809  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
17810 
17836  basic_json(const basic_json& other)
17837  : m_type(other.m_type)
17838  {
17839  // check of passed value is valid
17840  other.assert_invariant();
17841 
17842  switch (m_type)
17843  {
17844  case value_t::object:
17845  {
17846  m_value = *other.m_value.object;
17847  break;
17848  }
17849 
17850  case value_t::array:
17851  {
17852  m_value = *other.m_value.array;
17853  break;
17854  }
17855 
17856  case value_t::string:
17857  {
17858  m_value = *other.m_value.string;
17859  break;
17860  }
17861 
17862  case value_t::boolean:
17863  {
17864  m_value = other.m_value.boolean;
17865  break;
17866  }
17867 
17868  case value_t::number_integer:
17869  {
17870  m_value = other.m_value.number_integer;
17871  break;
17872  }
17873 
17874  case value_t::number_unsigned:
17875  {
17876  m_value = other.m_value.number_unsigned;
17877  break;
17878  }
17879 
17880  case value_t::number_float:
17881  {
17882  m_value = other.m_value.number_float;
17883  break;
17884  }
17885 
17886  case value_t::binary:
17887  {
17888  m_value = *other.m_value.binary;
17889  break;
17890  }
17891 
17892  default:
17893  break;
17894  }
17895 
17896  assert_invariant();
17897  }
17898 
17925  basic_json(basic_json&& other) noexcept
17926  : m_type(std::move(other.m_type)),
17927  m_value(std::move(other.m_value))
17928  {
17929  // check that passed value is valid
17930  other.assert_invariant();
17931 
17932  // invalidate payload
17933  other.m_type = value_t::null;
17934  other.m_value = {};
17935 
17936  assert_invariant();
17937  }
17938 
17962  basic_json& operator=(basic_json other) noexcept (
17963  std::is_nothrow_move_constructible<value_t>::value and
17964  std::is_nothrow_move_assignable<value_t>::value and
17965  std::is_nothrow_move_constructible<json_value>::value and
17966  std::is_nothrow_move_assignable<json_value>::value
17967  )
17968  {
17969  // check that passed value is valid
17970  other.assert_invariant();
17971 
17972  using std::swap;
17973  swap(m_type, other.m_type);
17974  swap(m_value, other.m_value);
17975 
17976  assert_invariant();
17977  return *this;
17978  }
17979 
17995  ~basic_json() noexcept
17996  {
17997  assert_invariant();
17998  m_value.destroy(m_type);
17999  }
18000 
18002 
18003  public:
18005  // object inspection //
18007 
18011 
18058  string_t dump(const int indent = -1,
18059  const char indent_char = ' ',
18060  const bool ensure_ascii = false,
18061  const error_handler_t error_handler = error_handler_t::strict) const
18062  {
18063  string_t result;
18064  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18065 
18066  if (indent >= 0)
18067  {
18068  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18069  }
18070  else
18071  {
18072  s.dump(*this, false, ensure_ascii, 0);
18073  }
18074 
18075  return result;
18076  }
18077 
18111  constexpr value_t type() const noexcept
18112  {
18113  return m_type;
18114  }
18115 
18142  constexpr bool is_primitive() const noexcept
18143  {
18144  return is_null() or is_string() or is_boolean() or is_number() or is_binary();
18145  }
18146 
18169  constexpr bool is_structured() const noexcept
18170  {
18171  return is_array() or is_object();
18172  }
18173 
18191  constexpr bool is_null() const noexcept
18192  {
18193  return m_type == value_t::null;
18194  }
18195 
18213  constexpr bool is_boolean() const noexcept
18214  {
18215  return m_type == value_t::boolean;
18216  }
18217 
18243  constexpr bool is_number() const noexcept
18244  {
18245  return is_number_integer() or is_number_float();
18246  }
18247 
18272  constexpr bool is_number_integer() const noexcept
18273  {
18274  return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
18275  }
18276 
18300  constexpr bool is_number_unsigned() const noexcept
18301  {
18302  return m_type == value_t::number_unsigned;
18303  }
18304 
18328  constexpr bool is_number_float() const noexcept
18329  {
18330  return m_type == value_t::number_float;
18331  }
18332 
18350  constexpr bool is_object() const noexcept
18351  {
18352  return m_type == value_t::object;
18353  }
18354 
18372  constexpr bool is_array() const noexcept
18373  {
18374  return m_type == value_t::array;
18375  }
18376 
18394  constexpr bool is_string() const noexcept
18395  {
18396  return m_type == value_t::string;
18397  }
18398 
18416  constexpr bool is_binary() const noexcept
18417  {
18418  return m_type == value_t::binary;
18419  }
18420 
18443  constexpr bool is_discarded() const noexcept
18444  {
18445  return m_type == value_t::discarded;
18446  }
18447 
18469  constexpr operator value_t() const noexcept
18470  {
18471  return m_type;
18472  }
18473 
18475 
18476  private:
18478  // value access //
18480 
18482  boolean_t get_impl(boolean_t* /*unused*/) const
18483  {
18484  if (JSON_HEDLEY_LIKELY(is_boolean()))
18485  {
18486  return m_value.boolean;
18487  }
18488 
18489  JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
18490  }
18491 
18493  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
18494  {
18495  return is_object() ? m_value.object : nullptr;
18496  }
18497 
18499  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
18500  {
18501  return is_object() ? m_value.object : nullptr;
18502  }
18503 
18505  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
18506  {
18507  return is_array() ? m_value.array : nullptr;
18508  }
18509 
18511  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
18512  {
18513  return is_array() ? m_value.array : nullptr;
18514  }
18515 
18517  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
18518  {
18519  return is_string() ? m_value.string : nullptr;
18520  }
18521 
18523  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
18524  {
18525  return is_string() ? m_value.string : nullptr;
18526  }
18527 
18529  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
18530  {
18531  return is_boolean() ? &m_value.boolean : nullptr;
18532  }
18533 
18535  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
18536  {
18537  return is_boolean() ? &m_value.boolean : nullptr;
18538  }
18539 
18541  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
18542  {
18543  return is_number_integer() ? &m_value.number_integer : nullptr;
18544  }
18545 
18547  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
18548  {
18549  return is_number_integer() ? &m_value.number_integer : nullptr;
18550  }
18551 
18553  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
18554  {
18555  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18556  }
18557 
18559  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
18560  {
18561  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18562  }
18563 
18565  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
18566  {
18567  return is_number_float() ? &m_value.number_float : nullptr;
18568  }
18569 
18571  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
18572  {
18573  return is_number_float() ? &m_value.number_float : nullptr;
18574  }
18575 
18577  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
18578  {
18579  return is_binary() ? m_value.binary : nullptr;
18580  }
18581 
18583  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
18584  {
18585  return is_binary() ? m_value.binary : nullptr;
18586  }
18587 
18599  template<typename ReferenceType, typename ThisType>
18600  static ReferenceType get_ref_impl(ThisType& obj)
18601  {
18602  // delegate the call to get_ptr<>()
18603  auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
18604 
18605  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
18606  {
18607  return *ptr;
18608  }
18609 
18610  JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
18611  }
18612 
18613  public:
18617 
18632  template<typename BasicJsonType, detail::enable_if_t<
18633  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
18634  int> = 0>
18635  basic_json get() const
18636  {
18637  return *this;
18638  }
18639 
18655  template<typename BasicJsonType, detail::enable_if_t<
18656  not std::is_same<BasicJsonType, basic_json>::value and
18657  detail::is_basic_json<BasicJsonType>::value, int> = 0>
18658  BasicJsonType get() const
18659  {
18660  return *this;
18661  }
18662 
18702  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
18703  detail::enable_if_t <
18704  not detail::is_basic_json<ValueType>::value and
18705  detail::has_from_json<basic_json_t, ValueType>::value and
18706  not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18707  int> = 0>
18708  ValueType get() const noexcept(noexcept(
18709  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
18710  {
18711  // we cannot static_assert on ValueTypeCV being non-const, because
18712  // there is support for get<const basic_json_t>(), which is why we
18713  // still need the uncvref
18714  static_assert(not std::is_reference<ValueTypeCV>::value,
18715  "get() cannot be used with reference types, you might want to use get_ref()");
18716  static_assert(std::is_default_constructible<ValueType>::value,
18717  "types must be DefaultConstructible when used with get()");
18718 
18719  ValueType ret;
18720  JSONSerializer<ValueType>::from_json(*this, ret);
18721  return ret;
18722  }
18723 
18755  template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
18756  detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
18757  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
18758  int> = 0>
18759  ValueType get() const noexcept(noexcept(
18760  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
18761  {
18762  static_assert(not std::is_reference<ValueTypeCV>::value,
18763  "get() cannot be used with reference types, you might want to use get_ref()");
18764  return JSONSerializer<ValueType>::from_json(*this);
18765  }
18766 
18800  template<typename ValueType,
18801  detail::enable_if_t <
18802  not detail::is_basic_json<ValueType>::value and
18803  detail::has_from_json<basic_json_t, ValueType>::value,
18804  int> = 0>
18805  ValueType & get_to(ValueType& v) const noexcept(noexcept(
18806  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
18807  {
18808  JSONSerializer<ValueType>::from_json(*this, v);
18809  return v;
18810  }
18811 
18812  template <
18813  typename T, std::size_t N,
18814  typename Array = T (&)[N],
18815  detail::enable_if_t <
18816  detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
18817  Array get_to(T (&v)[N]) const
18818  noexcept(noexcept(JSONSerializer<Array>::from_json(
18819  std::declval<const basic_json_t&>(), v)))
18820  {
18821  JSONSerializer<Array>::from_json(*this, v);
18822  return v;
18823  }
18824 
18825 
18852  template<typename PointerType, typename std::enable_if<
18853  std::is_pointer<PointerType>::value, int>::type = 0>
18854  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18855  {
18856  // delegate the call to get_impl_ptr<>()
18857  return get_impl_ptr(static_cast<PointerType>(nullptr));
18858  }
18859 
18864  template<typename PointerType, typename std::enable_if<
18865  std::is_pointer<PointerType>::value and
18866  std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
18867  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18868  {
18869  // delegate the call to get_impl_ptr<>() const
18870  return get_impl_ptr(static_cast<PointerType>(nullptr));
18871  }
18872 
18900  template<typename PointerType, typename std::enable_if<
18901  std::is_pointer<PointerType>::value, int>::type = 0>
18902  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
18903  {
18904  // delegate the call to get_ptr
18905  return get_ptr<PointerType>();
18906  }
18907 
18912  template<typename PointerType, typename std::enable_if<
18913  std::is_pointer<PointerType>::value, int>::type = 0>
18914  constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
18915  {
18916  // delegate the call to get_ptr
18917  return get_ptr<PointerType>();
18918  }
18919 
18946  template<typename ReferenceType, typename std::enable_if<
18947  std::is_reference<ReferenceType>::value, int>::type = 0>
18948  ReferenceType get_ref()
18949  {
18950  // delegate call to get_ref_impl
18951  return get_ref_impl<ReferenceType>(*this);
18952  }
18953 
18958  template<typename ReferenceType, typename std::enable_if<
18959  std::is_reference<ReferenceType>::value and
18960  std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
18961  ReferenceType get_ref() const
18962  {
18963  // delegate call to get_ref_impl
18964  return get_ref_impl<ReferenceType>(*this);
18965  }
18966 
18996  template < typename ValueType, typename std::enable_if <
18997  not std::is_pointer<ValueType>::value and
18998  not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
18999  not std::is_same<ValueType, typename string_t::value_type>::value and
19000  not detail::is_basic_json<ValueType>::value
19001  and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19002 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
19003  and not std::is_same<ValueType, typename std::string_view>::value
19004 #endif
19005  and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19006  , int >::type = 0 >
19007  operator ValueType() const
19008  {
19009  // delegate the call to get<>() const
19010  return get<ValueType>();
19011  }
19012 
19023  {
19024  if (not is_binary())
19025  {
19026  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19027  }
19028 
19029  return *get_ptr<binary_t*>();
19030  }
19031 
19033  const binary_t& get_binary() const
19034  {
19035  if (not is_binary())
19036  {
19037  JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19038  }
19039 
19040  return *get_ptr<const binary_t*>();
19041  }
19042 
19044 
19045 
19047  // element access //
19049 
19053 
19081  {
19082  // at only works for arrays
19083  if (JSON_HEDLEY_LIKELY(is_array()))
19084  {
19085  JSON_TRY
19086  {
19087  return m_value.array->at(idx);
19088  }
19089  JSON_CATCH (std::out_of_range&)
19090  {
19091  // create better exception explanation
19092  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19093  }
19094  }
19095  else
19096  {
19097  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19098  }
19099  }
19100 
19127  const_reference at(size_type idx) const
19128  {
19129  // at only works for arrays
19130  if (JSON_HEDLEY_LIKELY(is_array()))
19131  {
19132  JSON_TRY
19133  {
19134  return m_value.array->at(idx);
19135  }
19136  JSON_CATCH (std::out_of_range&)
19137  {
19138  // create better exception explanation
19139  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19140  }
19141  }
19142  else
19143  {
19144  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19145  }
19146  }
19147 
19178  reference at(const typename object_t::key_type& key)
19179  {
19180  // at only works for objects
19181  if (JSON_HEDLEY_LIKELY(is_object()))
19182  {
19183  JSON_TRY
19184  {
19185  return m_value.object->at(key);
19186  }
19187  JSON_CATCH (std::out_of_range&)
19188  {
19189  // create better exception explanation
19190  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19191  }
19192  }
19193  else
19194  {
19195  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19196  }
19197  }
19198 
19229  const_reference at(const typename object_t::key_type& key) const
19230  {
19231  // at only works for objects
19232  if (JSON_HEDLEY_LIKELY(is_object()))
19233  {
19234  JSON_TRY
19235  {
19236  return m_value.object->at(key);
19237  }
19238  JSON_CATCH (std::out_of_range&)
19239  {
19240  // create better exception explanation
19241  JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19242  }
19243  }
19244  else
19245  {
19246  JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19247  }
19248  }
19249 
19276  {
19277  // implicitly convert null value to an empty array
19278  if (is_null())
19279  {
19280  m_type = value_t::array;
19281  m_value.array = create<array_t>();
19282  assert_invariant();
19283  }
19284 
19285  // operator[] only works for arrays
19286  if (JSON_HEDLEY_LIKELY(is_array()))
19287  {
19288  // fill up array with null values if given idx is outside range
19289  if (idx >= m_value.array->size())
19290  {
19291  m_value.array->insert(m_value.array->end(),
19292  idx - m_value.array->size() + 1,
19293  basic_json());
19294  }
19295 
19296  return m_value.array->operator[](idx);
19297  }
19298 
19299  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19300  }
19301 
19322  {
19323  // const operator[] only works for arrays
19324  if (JSON_HEDLEY_LIKELY(is_array()))
19325  {
19326  return m_value.array->operator[](idx);
19327  }
19328 
19329  JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19330  }
19359  reference operator[](const typename object_t::key_type& key)
19360  {
19361  // implicitly convert null value to an empty object
19362  if (is_null())
19363  {
19364  m_type = value_t::object;
19365  m_value.object = create<object_t>();
19366  assert_invariant();
19367  }
19368 
19369  // operator[] only works for objects
19370  if (JSON_HEDLEY_LIKELY(is_object()))
19371  {
19372  return m_value.object->operator[](key);
19373  }
19374 
19375  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19376  }
19377 
19408  const_reference operator[](const typename object_t::key_type& key) const
19409  {
19410  // const operator[] only works for objects
19411  if (JSON_HEDLEY_LIKELY(is_object()))
19412  {
19413  assert(m_value.object->find(key) != m_value.object->end());
19414  return m_value.object->find(key)->second;
19415  }
19416 
19417  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19418  }
19419 
19447  template<typename T>
19448  JSON_HEDLEY_NON_NULL(2)
19449  reference operator[](T* key)
19450  {
19451  // implicitly convert null to object
19452  if (is_null())
19453  {
19454  m_type = value_t::object;
19455  m_value = value_t::object;
19456  assert_invariant();
19457  }
19458 
19459  // at only works for objects
19460  if (JSON_HEDLEY_LIKELY(is_object()))
19461  {
19462  return m_value.object->operator[](key);
19463  }
19464 
19465  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19466  }
19467 
19498  template<typename T>
19499  JSON_HEDLEY_NON_NULL(2)
19500  const_reference operator[](T* key) const
19501  {
19502  // at only works for objects
19503  if (JSON_HEDLEY_LIKELY(is_object()))
19504  {
19505  assert(m_value.object->find(key) != m_value.object->end());
19506  return m_value.object->find(key)->second;
19507  }
19508 
19509  JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19510  }
19511 
19562  template<class ValueType, typename std::enable_if<
19563  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
19564  ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
19565  {
19566  // at only works for objects
19567  if (JSON_HEDLEY_LIKELY(is_object()))
19568  {
19569  // if key is found, return value and given default value otherwise
19570  const auto it = find(key);
19571  if (it != end())
19572  {
19573  return *it;
19574  }
19575 
19576  return default_value;
19577  }
19578 
19579  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
19580  }
19581 
19586  string_t value(const typename object_t::key_type& key, const char* default_value) const
19587  {
19588  return value(key, string_t(default_value));
19589  }
19590 
19634  template<class ValueType, typename std::enable_if<
19635  std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
19636  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
19637  {
19638  // at only works for objects
19639  if (JSON_HEDLEY_LIKELY(is_object()))
19640  {
19641  // if pointer resolves a value, return it or use default value
19642  JSON_TRY
19643  {
19644  return ptr.get_checked(this);
19645  }
19646  JSON_INTERNAL_CATCH (out_of_range&)
19647  {
19648  return default_value;
19649  }
19650  }
19651 
19652  JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
19653  }
19654 
19659  JSON_HEDLEY_NON_NULL(3)
19660  string_t value(const json_pointer& ptr, const char* default_value) const
19661  {
19662  return value(ptr, string_t(default_value));
19663  }
19664 
19690  reference front()
19691  {
19692  return *begin();
19693  }
19694 
19698  const_reference front() const
19699  {
19700  return *cbegin();
19701  }
19702 
19734  reference back()
19735  {
19736  auto tmp = end();
19737  --tmp;
19738  return *tmp;
19739  }
19740 
19745  {
19746  auto tmp = cend();
19747  --tmp;
19748  return *tmp;
19749  }
19750 
19797  template<class IteratorType, typename std::enable_if<
19798  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19799  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
19800  = 0>
19801  IteratorType erase(IteratorType pos)
19802  {
19803  // make sure iterator fits the current value
19804  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
19805  {
19806  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
19807  }
19808 
19809  IteratorType result = end();
19810 
19811  switch (m_type)
19812  {
19813  case value_t::boolean:
19814  case value_t::number_float:
19815  case value_t::number_integer:
19816  case value_t::number_unsigned:
19817  case value_t::string:
19818  case value_t::binary:
19819  {
19820  if (JSON_HEDLEY_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
19821  {
19822  JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
19823  }
19824 
19825  if (is_string())
19826  {
19827  AllocatorType<string_t> alloc;
19828  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19829  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19830  m_value.string = nullptr;
19831  }
19832  else if (is_binary())
19833  {
19834  AllocatorType<binary_t> alloc;
19835  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19836  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19837  m_value.binary = nullptr;
19838  }
19839 
19840  m_type = value_t::null;
19841  assert_invariant();
19842  break;
19843  }
19844 
19845  case value_t::object:
19846  {
19847  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
19848  break;
19849  }
19850 
19851  case value_t::array:
19852  {
19853  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
19854  break;
19855  }
19856 
19857  default:
19858  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
19859  }
19860 
19861  return result;
19862  }
19863 
19910  template<class IteratorType, typename std::enable_if<
19911  std::is_same<IteratorType, typename basic_json_t::iterator>::value or
19912  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
19913  = 0>
19914  IteratorType erase(IteratorType first, IteratorType last)
19915  {
19916  // make sure iterator fits the current value
19917  if (JSON_HEDLEY_UNLIKELY(this != first.m_object or this != last.m_object))
19918  {
19919  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
19920  }
19921 
19922  IteratorType result = end();
19923 
19924  switch (m_type)
19925  {
19926  case value_t::boolean:
19927  case value_t::number_float:
19928  case value_t::number_integer:
19929  case value_t::number_unsigned:
19930  case value_t::string:
19931  case value_t::binary:
19932  {
19933  if (JSON_HEDLEY_LIKELY(not first.m_it.primitive_iterator.is_begin()
19934  or not last.m_it.primitive_iterator.is_end()))
19935  {
19936  JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
19937  }
19938 
19939  if (is_string())
19940  {
19941  AllocatorType<string_t> alloc;
19942  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19943  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19944  m_value.string = nullptr;
19945  }
19946  else if (is_binary())
19947  {
19948  AllocatorType<binary_t> alloc;
19949  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19950  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19951  m_value.binary = nullptr;
19952  }
19953 
19954  m_type = value_t::null;
19955  assert_invariant();
19956  break;
19957  }
19958 
19959  case value_t::object:
19960  {
19961  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
19962  last.m_it.object_iterator);
19963  break;
19964  }
19965 
19966  case value_t::array:
19967  {
19968  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
19969  last.m_it.array_iterator);
19970  break;
19971  }
19972 
19973  default:
19974  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
19975  }
19976 
19977  return result;
19978  }
19979 
20009  size_type erase(const typename object_t::key_type& key)
20010  {
20011  // this erase only works for objects
20012  if (JSON_HEDLEY_LIKELY(is_object()))
20013  {
20014  return m_value.object->erase(key);
20015  }
20016 
20017  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20018  }
20044  void erase(const size_type idx)
20045  {
20046  // this erase only works for arrays
20047  if (JSON_HEDLEY_LIKELY(is_array()))
20048  {
20049  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20050  {
20051  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20052  }
20053 
20054  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20055  }
20056  else
20057  {
20058  JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20059  }
20060  }
20061 
20063 
20064 
20066  // lookup //
20068 
20071 
20096  template<typename KeyT>
20097  iterator find(KeyT&& key)
20098  {
20099  auto result = end();
20100 
20101  if (is_object())
20102  {
20103  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20104  }
20105 
20106  return result;
20107  }
20108 
20113  template<typename KeyT>
20114  const_iterator find(KeyT&& key) const
20115  {
20116  auto result = cend();
20117 
20118  if (is_object())
20119  {
20120  result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20121  }
20122 
20123  return result;
20124  }
20125 
20147  template<typename KeyT>
20148  size_type count(KeyT&& key) const
20149  {
20150  // return 0 for all nonobject types
20151  return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20152  }
20153 
20179  template<typename KeyT, typename std::enable_if<
20180  not std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int>::type = 0>
20181  bool contains(KeyT && key) const
20182  {
20183  return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20184  }
20185 
20212  bool contains(const json_pointer& ptr) const
20213  {
20214  return ptr.contains(this);
20215  }
20216 
20218 
20219 
20221  // iterators //
20223 
20226 
20251  iterator begin() noexcept
20252  {
20253  iterator result(this);
20254  result.set_begin();
20255  return result;
20256  }
20257 
20261  const_iterator begin() const noexcept
20262  {
20263  return cbegin();
20264  }
20265 
20291  const_iterator cbegin() const noexcept
20292  {
20293  const_iterator result(this);
20294  result.set_begin();
20295  return result;
20296  }
20297 
20322  iterator end() noexcept
20323  {
20324  iterator result(this);
20325  result.set_end();
20326  return result;
20327  }
20328 
20332  const_iterator end() const noexcept
20333  {
20334  return cend();
20335  }
20336 
20362  const_iterator cend() const noexcept
20363  {
20364  const_iterator result(this);
20365  result.set_end();
20366  return result;
20367  }
20368 
20392  reverse_iterator rbegin() noexcept
20393  {
20394  return reverse_iterator(end());
20395  }
20396 
20400  const_reverse_iterator rbegin() const noexcept
20401  {
20402  return crbegin();
20403  }
20404 
20429  reverse_iterator rend() noexcept
20430  {
20431  return reverse_iterator(begin());
20432  }
20433 
20437  const_reverse_iterator rend() const noexcept
20438  {
20439  return crend();
20440  }
20441 
20466  const_reverse_iterator crbegin() const noexcept
20467  {
20468  return const_reverse_iterator(cend());
20469  }
20470 
20495  const_reverse_iterator crend() const noexcept
20496  {
20497  return const_reverse_iterator(cbegin());
20498  }
20499 
20500  public:
20558  JSON_HEDLEY_DEPRECATED(3.1.0)
20559  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
20560  {
20561  return ref.items();
20562  }
20563 
20567  JSON_HEDLEY_DEPRECATED(3.1.0)
20568  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
20569  {
20570  return ref.items();
20571  }
20572 
20641  iteration_proxy<iterator> items() noexcept
20642  {
20643  return iteration_proxy<iterator>(*this);
20644  }
20645 
20649  iteration_proxy<const_iterator> items() const noexcept
20650  {
20651  return iteration_proxy<const_iterator>(*this);
20652  }
20653 
20655 
20656 
20658  // capacity //
20660 
20663 
20706  bool empty() const noexcept
20707  {
20708  switch (m_type)
20709  {
20710  case value_t::null:
20711  {
20712  // null values are empty
20713  return true;
20714  }
20715 
20716  case value_t::array:
20717  {
20718  // delegate call to array_t::empty()
20719  return m_value.array->empty();
20720  }
20721 
20722  case value_t::object:
20723  {
20724  // delegate call to object_t::empty()
20725  return m_value.object->empty();
20726  }
20727 
20728  default:
20729  {
20730  // all other types are nonempty
20731  return false;
20732  }
20733  }
20734  }
20735 
20779  size_type size() const noexcept
20780  {
20781  switch (m_type)
20782  {
20783  case value_t::null:
20784  {
20785  // null values are empty
20786  return 0;
20787  }
20788 
20789  case value_t::array:
20790  {
20791  // delegate call to array_t::size()
20792  return m_value.array->size();
20793  }
20794 
20795  case value_t::object:
20796  {
20797  // delegate call to object_t::size()
20798  return m_value.object->size();
20799  }
20800 
20801  default:
20802  {
20803  // all other types have size 1
20804  return 1;
20805  }
20806  }
20807  }
20808 
20850  size_type max_size() const noexcept
20851  {
20852  switch (m_type)
20853  {
20854  case value_t::array:
20855  {
20856  // delegate call to array_t::max_size()
20857  return m_value.array->max_size();
20858  }
20859 
20860  case value_t::object:
20861  {
20862  // delegate call to object_t::max_size()
20863  return m_value.object->max_size();
20864  }
20865 
20866  default:
20867  {
20868  // all other types have max_size() == size()
20869  return size();
20870  }
20871  }
20872  }
20873 
20875 
20876 
20878  // modifiers //
20880 
20883 
20921  void clear() noexcept
20922  {
20923  switch (m_type)
20924  {
20925  case value_t::number_integer:
20926  {
20927  m_value.number_integer = 0;
20928  break;
20929  }
20930 
20931  case value_t::number_unsigned:
20932  {
20933  m_value.number_unsigned = 0;
20934  break;
20935  }
20936 
20937  case value_t::number_float:
20938  {
20939  m_value.number_float = 0.0;
20940  break;
20941  }
20942 
20943  case value_t::boolean:
20944  {
20945  m_value.boolean = false;
20946  break;
20947  }
20948 
20949  case value_t::string:
20950  {
20951  m_value.string->clear();
20952  break;
20953  }
20954 
20955  case value_t::binary:
20956  {
20957  m_value.binary->clear();
20958  break;
20959  }
20960 
20961  case value_t::array:
20962  {
20963  m_value.array->clear();
20964  break;
20965  }
20966 
20967  case value_t::object:
20968  {
20969  m_value.object->clear();
20970  break;
20971  }
20972 
20973  default:
20974  break;
20975  }
20976  }
20977 
20998  void push_back(basic_json&& val)
20999  {
21000  // push_back only works for null objects or arrays
21001  if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21002  {
21003  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21004  }
21005 
21006  // transform null object into an array
21007  if (is_null())
21008  {
21009  m_type = value_t::array;
21010  m_value = value_t::array;
21011  assert_invariant();
21012  }
21013 
21014  // add element to array (move semantics)
21015  m_value.array->push_back(std::move(val));
21016  // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21017  }
21018 
21024  {
21025  push_back(std::move(val));
21026  return *this;
21027  }
21028 
21033  void push_back(const basic_json& val)
21034  {
21035  // push_back only works for null objects or arrays
21036  if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21037  {
21038  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21039  }
21040 
21041  // transform null object into an array
21042  if (is_null())
21043  {
21044  m_type = value_t::array;
21045  m_value = value_t::array;
21046  assert_invariant();
21047  }
21048 
21049  // add element to array
21050  m_value.array->push_back(val);
21051  }
21052 
21057  reference operator+=(const basic_json& val)
21058  {
21059  push_back(val);
21060  return *this;
21061  }
21062 
21083  void push_back(const typename object_t::value_type& val)
21084  {
21085  // push_back only works for null objects or objects
21086  if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
21087  {
21088  JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21089  }
21090 
21091  // transform null object into an object
21092  if (is_null())
21093  {
21094  m_type = value_t::object;
21095  m_value = value_t::object;
21096  assert_invariant();
21097  }
21098 
21099  // add element to array
21100  m_value.object->insert(val);
21101  }
21102 
21107  reference operator+=(const typename object_t::value_type& val)
21108  {
21109  push_back(val);
21110  return *this;
21111  }
21112 
21138  void push_back(initializer_list_t init)
21139  {
21140  if (is_object() and init.size() == 2 and (*init.begin())->is_string())
21141  {
21142  basic_json&& key = init.begin()->moved_or_copied();
21143  push_back(typename object_t::value_type(
21144  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21145  }
21146  else
21147  {
21149  }
21150  }
21151 
21157  {
21158  push_back(init);
21159  return *this;
21160  }
21161 
21185  template<class... Args>
21186  reference emplace_back(Args&& ... args)
21187  {
21188  // emplace_back only works for null objects or arrays
21189  if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_array())))
21190  {
21191  JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21192  }
21193 
21194  // transform null object into an array
21195  if (is_null())
21196  {
21197  m_type = value_t::array;
21198  m_value = value_t::array;
21199  assert_invariant();
21200  }
21201 
21202  // add element to array (perfect forwarding)
21203 #ifdef JSON_HAS_CPP_17
21204  return m_value.array->emplace_back(std::forward<Args>(args)...);
21205 #else
21206  m_value.array->emplace_back(std::forward<Args>(args)...);
21207  return m_value.array->back();
21208 #endif
21209  }
21210 
21238  template<class... Args>
21239  std::pair<iterator, bool> emplace(Args&& ... args)
21240  {
21241  // emplace only works for null objects or arrays
21242  if (JSON_HEDLEY_UNLIKELY(not(is_null() or is_object())))
21243  {
21244  JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21245  }
21246 
21247  // transform null object into an object
21248  if (is_null())
21249  {
21250  m_type = value_t::object;
21251  m_value = value_t::object;
21252  assert_invariant();
21253  }
21254 
21255  // add element to array (perfect forwarding)
21256  auto res = m_value.object->emplace(std::forward<Args>(args)...);
21257  // create result iterator and set iterator to the result of emplace
21258  auto it = begin();
21259  it.m_it.object_iterator = res.first;
21260 
21261  // return pair of iterator and boolean
21262  return {it, res.second};
21263  }
21264 
21268  template<typename... Args>
21269  iterator insert_iterator(const_iterator pos, Args&& ... args)
21270  {
21271  iterator result(this);
21272  assert(m_value.array != nullptr);
21273 
21274  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21275  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21276  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21277 
21278  // This could have been written as:
21279  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21280  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21281 
21282  return result;
21283  }
21284 
21307  iterator insert(const_iterator pos, const basic_json& val)
21308  {
21309  // insert only works for arrays
21310  if (JSON_HEDLEY_LIKELY(is_array()))
21311  {
21312  // check if iterator pos fits to this JSON value
21313  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21314  {
21315  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21316  }
21318  // insert to array and return iterator
21319  return insert_iterator(pos, val);
21320  }
21321 
21322  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21323  }
21324 
21330  {
21331  return insert(pos, val);
21332  }
21333 
21358  iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
21359  {
21360  // insert only works for arrays
21361  if (JSON_HEDLEY_LIKELY(is_array()))
21362  {
21363  // check if iterator pos fits to this JSON value
21364  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21365  {
21366  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21367  }
21369  // insert to array and return iterator
21370  return insert_iterator(pos, cnt, val);
21371  }
21372 
21373  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21374  }
21375 
21407  {
21408  // insert only works for arrays
21409  if (JSON_HEDLEY_UNLIKELY(not is_array()))
21410  {
21411  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21412  }
21413 
21414  // check if iterator pos fits to this JSON value
21415  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21416  {
21417  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21418  }
21419 
21420  // check if range iterators belong to the same JSON object
21421  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21422  {
21423  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21424  }
21425 
21426  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21427  {
21428  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
21429  }
21430 
21431  // insert to array and return iterator
21432  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21433  }
21434 
21460  {
21461  // insert only works for arrays
21462  if (JSON_HEDLEY_UNLIKELY(not is_array()))
21463  {
21464  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21465  }
21466 
21467  // check if iterator pos fits to this JSON value
21468  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21469  {
21470  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21471  }
21472 
21473  // insert to array and return iterator
21474  return insert_iterator(pos, ilist.begin(), ilist.end());
21475  }
21476 
21500  void insert(const_iterator first, const_iterator last)
21501  {
21502  // insert only works for objects
21503  if (JSON_HEDLEY_UNLIKELY(not is_object()))
21504  {
21505  JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21506  }
21507 
21508  // check if range iterators belong to the same JSON object
21509  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21510  {
21511  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21512  }
21513 
21514  // passed iterators must belong to objects
21515  if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()))
21516  {
21517  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
21518  }
21519 
21520  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21521  }
21522 
21542  void update(const_reference j)
21543  {
21544  // implicitly convert null value to an empty object
21545  if (is_null())
21546  {
21547  m_type = value_t::object;
21548  m_value.object = create<object_t>();
21549  assert_invariant();
21550  }
21551 
21552  if (JSON_HEDLEY_UNLIKELY(not is_object()))
21553  {
21554  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
21555  }
21556  if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
21557  {
21558  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
21559  }
21560 
21561  for (auto it = j.cbegin(); it != j.cend(); ++it)
21562  {
21563  m_value.object->operator[](it.key()) = it.value();
21564  }
21565  }
21566 
21593  void update(const_iterator first, const_iterator last)
21594  {
21595  // implicitly convert null value to an empty object
21596  if (is_null())
21597  {
21598  m_type = value_t::object;
21599  m_value.object = create<object_t>();
21600  assert_invariant();
21601  }
21602 
21603  if (JSON_HEDLEY_UNLIKELY(not is_object()))
21604  {
21605  JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
21606  }
21607 
21608  // check if range iterators belong to the same JSON object
21609  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21610  {
21611  JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
21612  }
21613 
21614  // passed iterators must belong to objects
21615  if (JSON_HEDLEY_UNLIKELY(not first.m_object->is_object()
21616  or not last.m_object->is_object()))
21617  {
21618  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
21619  }
21620 
21621  for (auto it = first; it != last; ++it)
21622  {
21623  m_value.object->operator[](it.key()) = it.value();
21624  }
21625  }
21626 
21644  void swap(reference other) noexcept (
21645  std::is_nothrow_move_constructible<value_t>::value and
21646  std::is_nothrow_move_assignable<value_t>::value and
21647  std::is_nothrow_move_constructible<json_value>::value and
21648  std::is_nothrow_move_assignable<json_value>::value
21649  )
21650  {
21651  std::swap(m_type, other.m_type);
21652  std::swap(m_value, other.m_value);
21653  assert_invariant();
21654  }
21655 
21676  void swap(array_t& other)
21677  {
21678  // swap only works for arrays
21679  if (JSON_HEDLEY_LIKELY(is_array()))
21680  {
21681  std::swap(*(m_value.array), other);
21682  }
21683  else
21684  {
21685  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21686  }
21687  }
21688 
21709  void swap(object_t& other)
21710  {
21711  // swap only works for objects
21712  if (JSON_HEDLEY_LIKELY(is_object()))
21713  {
21714  std::swap(*(m_value.object), other);
21715  }
21716  else
21717  {
21718  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21719  }
21720  }
21721 
21742  void swap(string_t& other)
21743  {
21744  // swap only works for strings
21745  if (JSON_HEDLEY_LIKELY(is_string()))
21746  {
21747  std::swap(*(m_value.string), other);
21748  }
21749  else
21750  {
21751  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21752  }
21753  }
21754 
21775  void swap(binary_t& other)
21776  {
21777  // swap only works for strings
21778  if (JSON_HEDLEY_LIKELY(is_binary()))
21779  {
21780  std::swap(*(m_value.binary), other);
21781  }
21782  else
21783  {
21784  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21785  }
21786  }
21787 
21789  void swap(typename binary_t::container_type& other)
21790  {
21791  // swap only works for strings
21792  if (JSON_HEDLEY_LIKELY(is_binary()))
21793  {
21794  std::swap(*(m_value.binary), other);
21795  }
21796  else
21797  {
21798  JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
21799  }
21800  }
21801 
21803 
21804  public:
21806  // lexicographical comparison operators //
21808 
21811 
21867  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
21868  {
21869  const auto lhs_type = lhs.type();
21870  const auto rhs_type = rhs.type();
21871 
21872  if (lhs_type == rhs_type)
21873  {
21874  switch (lhs_type)
21875  {
21876  case value_t::array:
21877  return *lhs.m_value.array == *rhs.m_value.array;
21878 
21879  case value_t::object:
21880  return *lhs.m_value.object == *rhs.m_value.object;
21881 
21882  case value_t::null:
21883  return true;
21884 
21885  case value_t::string:
21886  return *lhs.m_value.string == *rhs.m_value.string;
21887 
21888  case value_t::boolean:
21889  return lhs.m_value.boolean == rhs.m_value.boolean;
21890 
21891  case value_t::number_integer:
21892  return lhs.m_value.number_integer == rhs.m_value.number_integer;
21893 
21894  case value_t::number_unsigned:
21895  return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
21896 
21897  case value_t::number_float:
21898  return lhs.m_value.number_float == rhs.m_value.number_float;
21899 
21900  case value_t::binary:
21901  return *lhs.m_value.binary == *rhs.m_value.binary;
21902 
21903  default:
21904  return false;
21905  }
21906  }
21907  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
21908  {
21909  return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
21910  }
21911  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
21912  {
21913  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
21914  }
21915  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
21916  {
21917  return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
21918  }
21919  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
21920  {
21921  return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
21922  }
21923  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
21924  {
21925  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
21926  }
21927  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
21928  {
21929  return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
21930  }
21931 
21932  return false;
21933  }
21934 
21939  template<typename ScalarType, typename std::enable_if<
21940  std::is_scalar<ScalarType>::value, int>::type = 0>
21941  friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
21942  {
21943  return lhs == basic_json(rhs);
21944  }
21945 
21950  template<typename ScalarType, typename std::enable_if<
21951  std::is_scalar<ScalarType>::value, int>::type = 0>
21952  friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
21953  {
21954  return basic_json(lhs) == rhs;
21955  }
21956 
21975  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
21976  {
21977  return not (lhs == rhs);
21978  }
21979 
21984  template<typename ScalarType, typename std::enable_if<
21985  std::is_scalar<ScalarType>::value, int>::type = 0>
21986  friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
21987  {
21988  return lhs != basic_json(rhs);
21989  }
21990 
21995  template<typename ScalarType, typename std::enable_if<
21996  std::is_scalar<ScalarType>::value, int>::type = 0>
21997  friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
21998  {
21999  return basic_json(lhs) != rhs;
22000  }
22001 
22028  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22029  {
22030  const auto lhs_type = lhs.type();
22031  const auto rhs_type = rhs.type();
22032 
22033  if (lhs_type == rhs_type)
22034  {
22035  switch (lhs_type)
22036  {
22037  case value_t::array:
22038  // note parentheses are necessary, see
22039  // https://github.com/nlohmann/json/issues/1530
22040  return (*lhs.m_value.array) < (*rhs.m_value.array);
22041 
22042  case value_t::object:
22043  return (*lhs.m_value.object) < (*rhs.m_value.object);
22044 
22045  case value_t::null:
22046  return false;
22047 
22048  case value_t::string:
22049  return (*lhs.m_value.string) < (*rhs.m_value.string);
22050 
22051  case value_t::boolean:
22052  return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22053 
22054  case value_t::number_integer:
22055  return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22056 
22057  case value_t::number_unsigned:
22058  return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22059 
22060  case value_t::number_float:
22061  return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22062 
22063  case value_t::binary:
22064  return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22065 
22066  default:
22067  return false;
22068  }
22069  }
22070  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
22071  {
22072  return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22073  }
22074  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
22075  {
22076  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22077  }
22078  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
22079  {
22080  return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22081  }
22082  else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
22083  {
22084  return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22085  }
22086  else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
22087  {
22088  return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22089  }
22090  else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
22091  {
22092  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22093  }
22094 
22095  // We only reach this line if we cannot compare values. In that case,
22096  // we compare types. Note we have to call the operator explicitly,
22097  // because MSVC has problems otherwise.
22098  return operator<(lhs_type, rhs_type);
22099  }
22100 
22105  template<typename ScalarType, typename std::enable_if<
22106  std::is_scalar<ScalarType>::value, int>::type = 0>
22107  friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22108  {
22109  return lhs < basic_json(rhs);
22110  }
22111 
22116  template<typename ScalarType, typename std::enable_if<
22117  std::is_scalar<ScalarType>::value, int>::type = 0>
22118  friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22119  {
22120  return basic_json(lhs) < rhs;
22121  }
22122 
22142  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22143  {
22144  return not (rhs < lhs);
22145  }
22146 
22151  template<typename ScalarType, typename std::enable_if<
22152  std::is_scalar<ScalarType>::value, int>::type = 0>
22153  friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22154  {
22155  return lhs <= basic_json(rhs);
22156  }
22157 
22162  template<typename ScalarType, typename std::enable_if<
22163  std::is_scalar<ScalarType>::value, int>::type = 0>
22164  friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22165  {
22166  return basic_json(lhs) <= rhs;
22167  }
22168 
22188  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22189  {
22190  return not (lhs <= rhs);
22191  }
22192 
22197  template<typename ScalarType, typename std::enable_if<
22198  std::is_scalar<ScalarType>::value, int>::type = 0>
22199  friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22200  {
22201  return lhs > basic_json(rhs);
22202  }
22203 
22208  template<typename ScalarType, typename std::enable_if<
22209  std::is_scalar<ScalarType>::value, int>::type = 0>
22210  friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22211  {
22212  return basic_json(lhs) > rhs;
22213  }
22214 
22234  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22235  {
22236  return not (lhs < rhs);
22237  }
22238 
22243  template<typename ScalarType, typename std::enable_if<
22244  std::is_scalar<ScalarType>::value, int>::type = 0>
22245  friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22246  {
22247  return lhs >= basic_json(rhs);
22248  }
22249 
22254  template<typename ScalarType, typename std::enable_if<
22255  std::is_scalar<ScalarType>::value, int>::type = 0>
22256  friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
22257  {
22258  return basic_json(lhs) >= rhs;
22259  }
22260 
22262 
22264  // serialization //
22269 
22301  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22302  {
22303  // read width member and use it as indentation parameter if nonzero
22304  const bool pretty_print = o.width() > 0;
22305  const auto indentation = pretty_print ? o.width() : 0;
22306 
22307  // reset width to 0 for subsequent calls to this stream
22308  o.width(0);
22309 
22310  // do the actual serialization
22311  serializer s(detail::output_adapter<char>(o), o.fill());
22312  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22313  return o;
22314  }
22315 
22324  JSON_HEDLEY_DEPRECATED(3.0.0)
22325  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22326  {
22327  return o << j;
22328  }
22329 
22331 
22332 
22334  // deserialization //
22336 
22339 
22403  template<typename InputType>
22404 
22405  static basic_json parse(InputType&& i,
22406  const parser_callback_t cb = nullptr,
22407  const bool allow_exceptions = true)
22408  {
22409  basic_json result;
22410  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions).parse(true, result);
22411  return result;
22412  }
22413 
22414 
22416 
22417  static basic_json parse(detail::span_input_adapter&& i,
22418  const parser_callback_t cb = nullptr,
22419  const bool allow_exceptions = true)
22420  {
22421  basic_json result;
22422  parser(i.get(), cb, allow_exceptions).parse(true, result);
22423  return result;
22424  }
22425 
22426  template<typename InputType>
22427  static bool accept(InputType&& i)
22428  {
22429  return parser(detail::input_adapter(std::forward<InputType>(i))).accept(true);
22430  }
22431 
22432  static bool accept(detail::span_input_adapter&& i)
22433  {
22434  return parser(i.get()).accept(true);
22435  }
22489  template <typename SAX, typename InputType>
22490  JSON_HEDLEY_NON_NULL(2)
22491  static bool sax_parse(InputType&& i, SAX* sax,
22493  const bool strict = true)
22494  {
22495  auto ia = detail::input_adapter(std::forward<InputType>(i));
22496  return format == input_format_t::json
22497  ? parser(std::move(ia)).sax_parse(sax, strict)
22498  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22499  }
22500 
22501  template <typename SAX>
22502  JSON_HEDLEY_NON_NULL(2)
22503  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22504  input_format_t format = input_format_t::json,
22505  const bool strict = true)
22506  {
22507  auto ia = i.get();
22508  return format == input_format_t::json
22509  ? parser(std::move(ia)).sax_parse(sax, strict)
22510  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
22511  }
22512 
22563  template<class IteratorType, typename std::enable_if<
22564  std::is_base_of<
22565  std::random_access_iterator_tag,
22566  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
22567  static basic_json parse(IteratorType first, IteratorType last,
22568  const parser_callback_t cb = nullptr,
22569  const bool allow_exceptions = true)
22570  {
22571  basic_json result;
22572  parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
22573  return result;
22574  }
22575 
22576  template<class IteratorType, typename std::enable_if<
22577  std::is_base_of<
22578  std::random_access_iterator_tag,
22579  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
22580  static bool accept(IteratorType first, IteratorType last)
22581  {
22582  return parser(detail::input_adapter(first, last)).accept(true);
22583  }
22584 
22585  template<class IteratorType, class SAX, typename std::enable_if<
22586  std::is_base_of<
22587  std::random_access_iterator_tag,
22588  typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
22589  JSON_HEDLEY_NON_NULL(3)
22590  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
22591  {
22592  return parser(detail::input_adapter(first, last)).sax_parse(sax);
22593  }
22594 
22603  JSON_HEDLEY_DEPRECATED(3.0.0)
22604  friend std::istream& operator<<(basic_json& j, std::istream& i)
22605  {
22606  return operator>>(i, j);
22607  }
22608 
22634  friend std::istream& operator>>(std::istream& i, basic_json& j)
22635  {
22636  parser(detail::input_adapter(i)).parse(false, j);
22637  return i;
22638  }
22639 
22641 
22643  // convenience functions //
22645 
22677 
22678  const char* type_name() const noexcept
22679  {
22680  {
22681  switch (m_type)
22682  {
22683  case value_t::null:
22684  return "null";
22685  case value_t::object:
22686  return "object";
22687  case value_t::array:
22688  return "array";
22689  case value_t::string:
22690  return "string";
22691  case value_t::boolean:
22692  return "boolean";
22693  case value_t::binary:
22694  return "binary";
22695  case value_t::discarded:
22696  return "discarded";
22697  default:
22698  return "number";
22699  }
22700  }
22701  }
22702 
22703 
22704  private:
22706  // member variables //
22708 
22710  value_t m_type = value_t::null;
22711 
22713  json_value m_value = {};
22714 
22716  // binary serialization/deserialization //
22718 
22721 
22722  public:
22818  static std::vector<uint8_t> to_cbor(const basic_json& j)
22819  {
22820  std::vector<uint8_t> result;
22821  to_cbor(j, result);
22822  return result;
22823  }
22824 
22825  static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
22826  {
22827  binary_writer<uint8_t>(o).write_cbor(j);
22828  }
22829 
22830  static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
22831  {
22832  binary_writer<char>(o).write_cbor(j);
22833  }
22834 
22915  static std::vector<uint8_t> to_msgpack(const basic_json& j)
22916  {
22917  std::vector<uint8_t> result;
22918  to_msgpack(j, result);
22919  return result;
22920  }
22921 
22922  static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
22923  {
22924  binary_writer<uint8_t>(o).write_msgpack(j);
22925  }
22926 
22927  static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
22928  {
22929  binary_writer<char>(o).write_msgpack(j);
22930  }
22931 
23018  static std::vector<uint8_t> to_ubjson(const basic_json& j,
23019  const bool use_size = false,
23020  const bool use_type = false)
23021  {
23022  std::vector<uint8_t> result;
23023  to_ubjson(j, result, use_size, use_type);
23024  return result;
23025  }
23026 
23027  static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23028  const bool use_size = false, const bool use_type = false)
23029  {
23030  binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23031  }
23032 
23033  static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23034  const bool use_size = false, const bool use_type = false)
23035  {
23036  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23037  }
23038 
23039 
23096  static std::vector<uint8_t> to_bson(const basic_json& j)
23097  {
23098  std::vector<uint8_t> result;
23099  to_bson(j, result);
23100  return result;
23101  }
23102 
23111  static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23112  {
23113  binary_writer<uint8_t>(o).write_bson(j);
23114  }
23115 
23119  static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23120  {
23121  binary_writer<char>(o).write_bson(j);
23122  }
23123 
23124 
23227  template<typename InputType>
23228 
23229  static basic_json from_cbor(InputType&& i,
23230  const bool strict = true,
23231  const bool allow_exceptions = true)
23232  {
23233  basic_json result;
23234  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23235  auto ia = detail::input_adapter(std::forward<InputType>(i));
23236  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict);
23237  return res ? result : basic_json(value_t::discarded);
23238  }
23243  template<typename A1, typename A2,
23244  detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23245 
23246  static basic_json from_cbor(A1 && a1, A2 && a2,
23247  const bool strict = true,
23248  const bool allow_exceptions = true)
23249  {
23250  basic_json result;
23251  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23252  const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::cbor, &sdp, strict);
23253  return res ? result : basic_json(value_t::discarded);
23254  }
23255 
23257  static basic_json from_cbor(detail::span_input_adapter&& i,
23258  const bool strict = true,
23259  const bool allow_exceptions = true)
23260  {
23261  basic_json result;
23262  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23263  const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::cbor, &sdp, strict);
23264  return res ? result : basic_json(value_t::discarded);
23265  }
23266 
23353  template<typename InputType>
23354 
23355  static basic_json from_msgpack(InputType&& i,
23356  const bool strict = true,
23357  const bool allow_exceptions = true)
23358  {
23359  basic_json result;
23360  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23361  auto ia = detail::input_adapter(std::forward<InputType>(i));
23362  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
23363  return res ? result : basic_json(value_t::discarded);
23364  }
23369  template<typename A1, typename A2,
23370  detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23371 
23372  static basic_json from_msgpack(A1 && a1, A2 && a2,
23373  const bool strict = true,
23374  const bool allow_exceptions = true)
23375  {
23376  basic_json result;
23377  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23378  const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::msgpack, &sdp, strict);
23379  return res ? result : basic_json(value_t::discarded);
23380  }
23381 
23383 
23384  static basic_json from_msgpack(detail::span_input_adapter&& i,
23385  const bool strict = true,
23386  const bool allow_exceptions = true)
23387  {
23388  basic_json result;
23389  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23390  const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::msgpack, &sdp, strict);
23391  return res ? result : basic_json(value_t::discarded);
23392  }
23393 
23456  template<typename InputType>
23457 
23458  static basic_json from_ubjson(InputType&& i,
23459  const bool strict = true,
23460  const bool allow_exceptions = true)
23461  {
23462  basic_json result;
23463  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23464  auto ia = detail::input_adapter(std::forward<InputType>(i));
23465  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
23466  return res ? result : basic_json(value_t::discarded);
23467  }
23472  template<typename A1, typename A2,
23473  detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23474 
23475  static basic_json from_ubjson(A1 && a1, A2 && a2,
23476  const bool strict = true,
23477  const bool allow_exceptions = true)
23478  {
23479  basic_json result;
23480  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23481  const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::ubjson, &sdp, strict);
23482  return res ? result : basic_json(value_t::discarded);
23483  }
23484 
23486  static basic_json from_ubjson(detail::span_input_adapter&& i,
23487  const bool strict = true,
23488  const bool allow_exceptions = true)
23489  {
23490  basic_json result;
23491  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23492  const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::ubjson, &sdp, strict);
23493  return res ? result : basic_json(value_t::discarded);
23494  }
23495 
23557  template<typename InputType>
23558 
23559  static basic_json from_bson(InputType&& i,
23560  const bool strict = true,
23561  const bool allow_exceptions = true)
23562  {
23563  basic_json result;
23564  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23565  auto ia = detail::input_adapter(std::forward<InputType>(i));
23566  const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
23567  return res ? result : basic_json(value_t::discarded);
23568  }
23573  template<typename A1, typename A2,
23574  detail::enable_if_t<std::is_constructible<detail::span_input_adapter, A1, A2>::value, int> = 0>
23575 
23576  static basic_json from_bson(A1 && a1, A2 && a2,
23577  const bool strict = true,
23578  const bool allow_exceptions = true)
23579  {
23580  basic_json result;
23581  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23582  const bool res = binary_reader<detail::input_buffer_adapter>(detail::span_input_adapter(std::forward<A1>(a1), std::forward<A2>(a2)).get()).sax_parse(input_format_t::bson, &sdp, strict);
23583  return res ? result : basic_json(value_t::discarded);
23584  }
23585 
23587  static basic_json from_bson(detail::span_input_adapter&& i,
23588  const bool strict = true,
23589  const bool allow_exceptions = true)
23590  {
23591  basic_json result;
23592  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23593  const bool res = binary_reader<detail::input_buffer_adapter>(i.get()).sax_parse(input_format_t::bson, &sdp, strict);
23594  return res ? result : basic_json(value_t::discarded);
23595  }
23599  // JSON Pointer support //
23601 
23604 
23638  reference operator[](const json_pointer& ptr)
23639  {
23640  return ptr.get_unchecked(this);
23641  }
23642 
23666  const_reference operator[](const json_pointer& ptr) const
23667  {
23668  return ptr.get_unchecked(this);
23669  }
23670 
23709  reference at(const json_pointer& ptr)
23710  {
23711  return ptr.get_checked(this);
23712  }
23713 
23752  const_reference at(const json_pointer& ptr) const
23753  {
23754  return ptr.get_checked(this);
23755  }
23756 
23779  basic_json flatten() const
23780  {
23781  basic_json result(value_t::object);
23782  json_pointer::flatten("", *this, result);
23783  return result;
23784  }
23785 
23816  basic_json unflatten() const
23817  {
23818  return json_pointer::unflatten(*this);
23819  }
23820 
23822 
23824  // JSON Patch functions //
23829 
23877  basic_json patch(const basic_json& json_patch) const
23878  {
23879  // make a working copy to apply the patch to
23880  basic_json result = *this;
23881 
23882  // the valid JSON Patch operations
23883  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23884 
23885  const auto get_op = [](const std::string & op)
23886  {
23887  if (op == "add")
23888  {
23889  return patch_operations::add;
23890  }
23891  if (op == "remove")
23892  {
23893  return patch_operations::remove;
23894  }
23895  if (op == "replace")
23896  {
23897  return patch_operations::replace;
23898  }
23899  if (op == "move")
23900  {
23901  return patch_operations::move;
23902  }
23903  if (op == "copy")
23904  {
23905  return patch_operations::copy;
23906  }
23907  if (op == "test")
23908  {
23909  return patch_operations::test;
23910  }
23911 
23912  return patch_operations::invalid;
23913  };
23914 
23915  // wrapper for "add" operation; add value at ptr
23916  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23917  {
23918  // adding to the root of the target document means replacing it
23919  if (ptr.empty())
23920  {
23921  result = val;
23922  return;
23923  }
23924 
23925  // make sure the top element of the pointer exists
23926  json_pointer top_pointer = ptr.top();
23927  if (top_pointer != ptr)
23928  {
23929  result.at(top_pointer);
23930  }
23931 
23932  // get reference to parent of JSON pointer ptr
23933  const auto last_path = ptr.back();
23934  ptr.pop_back();
23935  basic_json& parent = result[ptr];
23936 
23937  switch (parent.m_type)
23938  {
23939  case value_t::null:
23940  case value_t::object:
23941  {
23942  // use operator[] to add value
23943  parent[last_path] = val;
23944  break;
23945  }
23946 
23947  case value_t::array:
23948  {
23949  if (last_path == "-")
23950  {
23951  // special case: append to back
23952  parent.push_back(val);
23953  }
23954  else
23955  {
23956  const auto idx = json_pointer::array_index(last_path);
23957  if (JSON_HEDLEY_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
23958  {
23959  // avoid undefined behavior
23960  JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
23961  }
23962 
23963  // default case: insert add offset
23964  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23965  }
23966  break;
23967  }
23968 
23969  // if there exists a parent it cannot be primitive
23970  default: // LCOV_EXCL_LINE
23971  assert(false); // LCOV_EXCL_LINE
23972  }
23973  };
23974 
23975  // wrapper for "remove" operation; remove value at ptr
23976  const auto operation_remove = [&result](json_pointer & ptr)
23977  {
23978  // get reference to parent of JSON pointer ptr
23979  const auto last_path = ptr.back();
23980  ptr.pop_back();
23981  basic_json& parent = result.at(ptr);
23982 
23983  // remove child
23984  if (parent.is_object())
23985  {
23986  // perform range check
23987  auto it = parent.find(last_path);
23988  if (JSON_HEDLEY_LIKELY(it != parent.end()))
23989  {
23990  parent.erase(it);
23991  }
23992  else
23993  {
23994  JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
23995  }
23996  }
23997  else if (parent.is_array())
23998  {
23999  // note erase performs range check
24000  parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
24001  }
24002  };
24003 
24004  // type check: top level value must be an array
24005  if (JSON_HEDLEY_UNLIKELY(not json_patch.is_array()))
24006  {
24007  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24008  }
24009 
24010  // iterate and apply the operations
24011  for (const auto& val : json_patch)
24012  {
24013  // wrapper to get a value for an operation
24014  const auto get_value = [&val](const std::string & op,
24015  const std::string & member,
24016  bool string_type) -> basic_json &
24017  {
24018  // find value
24019  auto it = val.m_value.object->find(member);
24020 
24021  // context-sensitive error message
24022  const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24023 
24024  // check if desired value is present
24025  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24026  {
24027  JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24028  }
24029 
24030  // check if result is of type string
24031  if (JSON_HEDLEY_UNLIKELY(string_type and not it->second.is_string()))
24032  {
24033  JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24034  }
24035 
24036  // no error: return value
24037  return it->second;
24038  };
24039 
24040  // type check: every element of the array must be an object
24041  if (JSON_HEDLEY_UNLIKELY(not val.is_object()))
24042  {
24043  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24044  }
24045 
24046  // collect mandatory members
24047  const std::string op = get_value("op", "op", true);
24048  const std::string path = get_value(op, "path", true);
24049  json_pointer ptr(path);
24050 
24051  switch (get_op(op))
24052  {
24053  case patch_operations::add:
24054  {
24055  operation_add(ptr, get_value("add", "value", false));
24056  break;
24057  }
24058 
24059  case patch_operations::remove:
24060  {
24061  operation_remove(ptr);
24062  break;
24063  }
24064 
24065  case patch_operations::replace:
24066  {
24067  // the "path" location must exist - use at()
24068  result.at(ptr) = get_value("replace", "value", false);
24069  break;
24070  }
24071 
24072  case patch_operations::move:
24073  {
24074  const std::string from_path = get_value("move", "from", true);
24075  json_pointer from_ptr(from_path);
24076 
24077  // the "from" location must exist - use at()
24078  basic_json v = result.at(from_ptr);
24079 
24080  // The move operation is functionally identical to a
24081  // "remove" operation on the "from" location, followed
24082  // immediately by an "add" operation at the target
24083  // location with the value that was just removed.
24084  operation_remove(from_ptr);
24085  operation_add(ptr, v);
24086  break;
24087  }
24088 
24089  case patch_operations::copy:
24090  {
24091  const std::string from_path = get_value("copy", "from", true);
24092  const json_pointer from_ptr(from_path);
24093 
24094  // the "from" location must exist - use at()
24095  basic_json v = result.at(from_ptr);
24096 
24097  // The copy is functionally identical to an "add"
24098  // operation at the target location using the value
24099  // specified in the "from" member.
24100  operation_add(ptr, v);
24101  break;
24102  }
24103 
24104  case patch_operations::test:
24105  {
24106  bool success = false;
24107  JSON_TRY
24108  {
24109  // check if "value" matches the one at "path"
24110  // the "path" location must exist - use at()
24111  success = (result.at(ptr) == get_value("test", "value", false));
24112  }
24113  JSON_INTERNAL_CATCH (out_of_range&)
24114  {
24115  // ignore out of range errors: success remains false
24116  }
24117 
24118  // throw an exception if test fails
24119  if (JSON_HEDLEY_UNLIKELY(not success))
24120  {
24121  JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24122  }
24123 
24124  break;
24125  }
24126 
24127  default:
24128  {
24129  // op must be "add", "remove", "replace", "move", "copy", or
24130  // "test"
24131  JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24132  }
24133  }
24134  }
24135 
24136  return result;
24137  }
24138 
24172 
24173  static basic_json diff(const basic_json& source, const basic_json& target,
24174  const std::string& path = "")
24175  {
24176  // the patch
24177  basic_json result(value_t::array);
24178 
24179  // if the values are the same, return empty patch
24180  if (source == target)
24181  {
24182  return result;
24183  }
24184 
24185  if (source.type() != target.type())
24186  {
24187  // different types: replace value
24188  result.push_back(
24189  {
24190  {"op", "replace"}, {"path", path}, {"value", target}
24191  });
24192  return result;
24193  }
24194 
24195  switch (source.type())
24196  {
24197  case value_t::array:
24198  {
24199  // first pass: traverse common elements
24200  std::size_t i = 0;
24201  while (i < source.size() and i < target.size())
24202  {
24203  // recursive call to compare array values at index i
24204  auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24205  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24206  ++i;
24207  }
24208 
24209  // i now reached the end of at least one array
24210  // in a second pass, traverse the remaining elements
24211 
24212  // remove my remaining elements
24213  const auto end_index = static_cast<difference_type>(result.size());
24214  while (i < source.size())
24215  {
24216  // add operations in reverse order to avoid invalid
24217  // indices
24218  result.insert(result.begin() + end_index, object(
24219  {
24220  {"op", "remove"},
24221  {"path", path + "/" + std::to_string(i)}
24222  }));
24223  ++i;
24224  }
24225 
24226  // add other remaining elements
24227  while (i < target.size())
24228  {
24229  result.push_back(
24230  {
24231  {"op", "add"},
24232  {"path", path + "/-"},
24233  {"value", target[i]}
24234  });
24235  ++i;
24236  }
24237 
24238  break;
24239  }
24240 
24241  case value_t::object:
24242  {
24243  // first pass: traverse this object's elements
24244  for (auto it = source.cbegin(); it != source.cend(); ++it)
24245  {
24246  // escape the key name to be used in a JSON patch
24247  const auto key = json_pointer::escape(it.key());
24248 
24249  if (target.find(it.key()) != target.end())
24250  {
24251  // recursive call to compare object values at key it
24252  auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
24253  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24254  }
24255  else
24256  {
24257  // found a key that is not in o -> remove it
24258  result.push_back(object(
24259  {
24260  {"op", "remove"}, {"path", path + "/" + key}
24261  }));
24262  }
24263  }
24264 
24265  // second pass: traverse other object's elements
24266  for (auto it = target.cbegin(); it != target.cend(); ++it)
24267  {
24268  if (source.find(it.key()) == source.end())
24269  {
24270  // found a key that is not in this -> add it
24271  const auto key = json_pointer::escape(it.key());
24272  result.push_back(
24273  {
24274  {"op", "add"}, {"path", path + "/" + key},
24275  {"value", it.value()}
24276  });
24277  }
24278  }
24279 
24280  break;
24281  }
24282 
24283  default:
24284  {
24285  // both primitive type: replace value
24286  result.push_back(
24287  {
24288  {"op", "replace"}, {"path", path}, {"value", target}
24289  });
24290  break;
24291  }
24292  }
24293 
24294  return result;
24295  }
24296 
24298 
24300  // JSON Merge Patch functions //
24302 
24305 
24348  void merge_patch(const basic_json& apply_patch)
24349  {
24350  if (apply_patch.is_object())
24351  {
24352  if (not is_object())
24353  {
24354  *this = object();
24355  }
24356  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
24357  {
24358  if (it.value().is_null())
24359  {
24360  erase(it.key());
24361  }
24362  else
24363  {
24364  operator[](it.key()).merge_patch(it.value());
24365  }
24366  }
24367  }
24368  else
24369  {
24370  *this = apply_patch;
24371  }
24372  }
24373 
24375 };
24376 
24386 NLOHMANN_BASIC_JSON_TPL_DECLARATION
24387 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
24388 {
24389  return j.dump();
24390 }
24391 } // namespace nlohmann
24392 
24394 // nonmember support //
24396 
24397 // specialization of std::swap, and std::hash
24398 namespace std
24399 {
24400 
24402 template<>
24403 struct hash<nlohmann::json>
24404 {
24410  std::size_t operator()(const nlohmann::json& j) const
24411  {
24412  // a naive hashing via the string representation
24413  const auto& h = hash<nlohmann::json::string_t>();
24414  return h(j.dump());
24415  }
24416 };
24417 
24421 template<>
24422 struct less<::nlohmann::detail::value_t>
24423 {
24428  bool operator()(nlohmann::detail::value_t lhs,
24429  nlohmann::detail::value_t rhs) const noexcept
24430  {
24431  return nlohmann::detail::operator<(lhs, rhs);
24432  }
24433 };
24434 
24440 template<>
24441 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
24442  is_nothrow_move_constructible<nlohmann::json>::value and
24443  is_nothrow_move_assignable<nlohmann::json>::value
24444 )
24445 {
24446  j1.swap(j2);
24447 }
24448 
24449 } // namespace std
24450 
24464 JSON_HEDLEY_NON_NULL(1)
24465 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
24466 {
24467  return nlohmann::json::parse(s, s + n);
24468 }
24469 
24483 JSON_HEDLEY_NON_NULL(1)
24484 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
24485 {
24486  return nlohmann::json::json_pointer(std::string(s, n));
24487 }
24488 
24489 // #include <nlohmann/detail/macro_unscope.hpp>
24490 
24491 
24492 // restore GCC/clang diagnostic settings
24493 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
24494  #pragma GCC diagnostic pop
24495 #endif
24496 #if defined(__clang__)
24497  #pragma GCC diagnostic pop
24498 #endif
24499 
24500 // clean up
24501 #undef JSON_INTERNAL_CATCH
24502 #undef JSON_CATCH
24503 #undef JSON_THROW
24504 #undef JSON_TRY
24505 #undef JSON_HAS_CPP_14
24506 #undef JSON_HAS_CPP_17
24507 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
24508 #undef NLOHMANN_BASIC_JSON_TPL
24509 
24510 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
24511 #undef JSON_HEDLEY_ALWAYS_INLINE
24512 #undef JSON_HEDLEY_ARM_VERSION
24513 #undef JSON_HEDLEY_ARM_VERSION_CHECK
24514 #undef JSON_HEDLEY_ARRAY_PARAM
24515 #undef JSON_HEDLEY_ASSUME
24516 #undef JSON_HEDLEY_BEGIN_C_DECLS
24517 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
24518 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
24519 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
24520 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
24521 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
24522 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
24523 #undef JSON_HEDLEY_CLANG_HAS_WARNING
24524 #undef JSON_HEDLEY_COMPCERT_VERSION
24525 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
24526 #undef JSON_HEDLEY_CONCAT
24527 #undef JSON_HEDLEY_CONCAT3
24528 #undef JSON_HEDLEY_CONCAT3_EX
24529 #undef JSON_HEDLEY_CONCAT_EX
24530 #undef JSON_HEDLEY_CONST
24531 #undef JSON_HEDLEY_CONSTEXPR
24532 #undef JSON_HEDLEY_CONST_CAST
24533 #undef JSON_HEDLEY_CPP_CAST
24534 #undef JSON_HEDLEY_CRAY_VERSION
24535 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
24536 #undef JSON_HEDLEY_C_DECL
24537 #undef JSON_HEDLEY_DEPRECATED
24538 #undef JSON_HEDLEY_DEPRECATED_FOR
24539 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
24540 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
24541 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
24542 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
24543 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
24544 #undef JSON_HEDLEY_DIAGNOSTIC_POP
24545 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
24546 #undef JSON_HEDLEY_DMC_VERSION
24547 #undef JSON_HEDLEY_DMC_VERSION_CHECK
24548 #undef JSON_HEDLEY_EMPTY_BASES
24549 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
24550 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
24551 #undef JSON_HEDLEY_END_C_DECLS
24552 #undef JSON_HEDLEY_FLAGS
24553 #undef JSON_HEDLEY_FLAGS_CAST
24554 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
24555 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
24556 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
24557 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
24558 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
24559 #undef JSON_HEDLEY_GCC_HAS_FEATURE
24560 #undef JSON_HEDLEY_GCC_HAS_WARNING
24561 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
24562 #undef JSON_HEDLEY_GCC_VERSION
24563 #undef JSON_HEDLEY_GCC_VERSION_CHECK
24564 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
24565 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
24566 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
24567 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
24568 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
24569 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
24570 #undef JSON_HEDLEY_GNUC_HAS_WARNING
24571 #undef JSON_HEDLEY_GNUC_VERSION
24572 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
24573 #undef JSON_HEDLEY_HAS_ATTRIBUTE
24574 #undef JSON_HEDLEY_HAS_BUILTIN
24575 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
24576 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
24577 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
24578 #undef JSON_HEDLEY_HAS_EXTENSION
24579 #undef JSON_HEDLEY_HAS_FEATURE
24580 #undef JSON_HEDLEY_HAS_WARNING
24581 #undef JSON_HEDLEY_IAR_VERSION
24582 #undef JSON_HEDLEY_IAR_VERSION_CHECK
24583 #undef JSON_HEDLEY_IBM_VERSION
24584 #undef JSON_HEDLEY_IBM_VERSION_CHECK
24585 #undef JSON_HEDLEY_IMPORT
24586 #undef JSON_HEDLEY_INLINE
24587 #undef JSON_HEDLEY_INTEL_VERSION
24588 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
24589 #undef JSON_HEDLEY_IS_CONSTANT
24590 #undef JSON_HEDLEY_IS_CONSTEXPR_
24591 #undef JSON_HEDLEY_LIKELY
24592 #undef JSON_HEDLEY_MALLOC
24593 #undef JSON_HEDLEY_MESSAGE
24594 #undef JSON_HEDLEY_MSVC_VERSION
24595 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
24596 #undef JSON_HEDLEY_NEVER_INLINE
24597 #undef JSON_HEDLEY_NON_NULL
24598 #undef JSON_HEDLEY_NO_ESCAPE
24599 #undef JSON_HEDLEY_NO_RETURN
24600 #undef JSON_HEDLEY_NO_THROW
24601 #undef JSON_HEDLEY_NULL
24602 #undef JSON_HEDLEY_PELLES_VERSION
24603 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
24604 #undef JSON_HEDLEY_PGI_VERSION
24605 #undef JSON_HEDLEY_PGI_VERSION_CHECK
24606 #undef JSON_HEDLEY_PREDICT
24607 #undef JSON_HEDLEY_PRINTF_FORMAT
24608 #undef JSON_HEDLEY_PRIVATE
24609 #undef JSON_HEDLEY_PUBLIC
24610 #undef JSON_HEDLEY_PURE
24611 #undef JSON_HEDLEY_REINTERPRET_CAST
24612 #undef JSON_HEDLEY_REQUIRE
24613 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
24614 #undef JSON_HEDLEY_REQUIRE_MSG
24615 #undef JSON_HEDLEY_RESTRICT
24616 #undef
24617 #undef JSON_HEDLEY_SENTINEL
24618 #undef JSON_HEDLEY_STATIC_ASSERT
24619 #undef JSON_HEDLEY_STATIC_CAST
24620 #undef JSON_HEDLEY_STRINGIFY
24621 #undef JSON_HEDLEY_STRINGIFY_EX
24622 #undef JSON_HEDLEY_SUNPRO_VERSION
24623 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
24624 #undef JSON_HEDLEY_TINYC_VERSION
24625 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
24626 #undef JSON_HEDLEY_TI_ARMCL_VERSION
24627 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
24628 #undef JSON_HEDLEY_TI_CL2000_VERSION
24629 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
24630 #undef JSON_HEDLEY_TI_CL430_VERSION
24631 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
24632 #undef JSON_HEDLEY_TI_CL6X_VERSION
24633 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
24634 #undef JSON_HEDLEY_TI_CL7X_VERSION
24635 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
24636 #undef JSON_HEDLEY_TI_CLPRU_VERSION
24637 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
24638 #undef JSON_HEDLEY_TI_VERSION
24639 #undef JSON_HEDLEY_TI_VERSION_CHECK
24640 #undef JSON_HEDLEY_UNAVAILABLE
24641 #undef JSON_HEDLEY_UNLIKELY
24642 #undef JSON_HEDLEY_UNPREDICTABLE
24643 #undef JSON_HEDLEY_UNREACHABLE
24644 #undef JSON_HEDLEY_UNREACHABLE_RETURN
24645 #undef JSON_HEDLEY_VERSION
24646 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
24647 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
24648 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
24649 #undef JSON_HEDLEY_VERSION_ENCODE
24650 #undef JSON_HEDLEY_WARNING
24651 #undef
24652 #undef _MSG
24653 #undef JSON_HEDLEY_FALL_THROUGH
24654 
24655 
24656 
24657 #endif // INCLUDE_NLOHMANN_JSON_HPP_
nlohmann::basic_json::to_msgpack
static std::vector< uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:22925
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:19811
nlohmann::basic_json::value_t
detail::value_t value_t
Definition: json.hpp:16016
nlohmann::json_sax::boolean
virtual bool boolean(bool val)=0
a boolean value was read
nlohmann::basic_json::begin
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:20261
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:4280
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:18058
nlohmann::basic_json::contains
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:20191
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:17641
nlohmann::basic_json::const_iterator
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:16087
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:23365
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:18759
nlohmann::basic_json::meta
static basic_json meta()
returns version information on the library
Definition: json.hpp:16131
nlohmann::basic_json::number_unsigned_t
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:16559
nlohmann::basic_json::unflatten
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:23826
nlohmann::basic_json::operator>>
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:22335
nlohmann::byte_container_with_subtype::set_subtype
void set_subtype(std::uint8_t subtype) noexcept
sets the binary subtype
Definition: json.hpp:4309
nlohmann::basic_json::other_error
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:16049
nlohmann::basic_json::number_integer_t
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:16488
nlohmann::basic_json::allocator_type
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:16077
nlohmann::basic_json::object
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:17614
nlohmann::basic_json::array_t
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:16337
nlohmann::basic_json::basic_json
basic_json(const JsonRef &ref)
Definition: json.hpp:17809
nlohmann::basic_json::operator>
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:22198
nlohmann::basic_json::size
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:20789
nlohmann::basic_json::basic_json
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:17264
nlohmann::json_sax::binary_t
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:4935
nlohmann::basic_json::invalid_iterator
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:16043
nlohmann::json_pointer::back
const std::string & back() const
return last reference token
Definition: json.hpp:11313
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:11107
nlohmann::basic_json::operator==
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:21877
nlohmann::basic_json::difference_type
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:16072
nlohmann::basic_json::at
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:19080
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:18805
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:16291
nlohmann::basic_json::type_name
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:22688
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:23028
nlohmann::basic_json::input_format_t
detail::input_format_t input_format_t
Definition: json.hpp:16026
nlohmann::basic_json::parse
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true)
deserialize from a compatible input
Definition: json.hpp:22415
nlohmann::basic_json::is_primitive
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:18142
nlohmann::basic_json::rend
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:20439
nlohmann::basic_json::crbegin
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:20476
nlohmann::basic_json::accept
static bool accept(InputType &&i)
Definition: json.hpp:22437
nlohmann
namespace for Niels Lohmann
Definition: json.hpp:93
nlohmann::basic_json::find
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:20107
nlohmann::byte_container_with_subtype::has_subtype
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:4357
nlohmann::basic_json::basic_json
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:17836
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:19574
nlohmann::basic_json::get_allocator
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:16099
nlohmann::json_sax::parse_error
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
nlohmann::basic_json::is_number_integer
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:18272
nlohmann::json_pointer
JSON Pointer.
Definition: json.hpp:11062
nlohmann::basic_json::size_type
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:16074
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)
generate SAX events
Definition: json.hpp:22501
nlohmann::byte_container_with_subtype::operator!=
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:4286
nlohmann::basic_json::operator!=
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:21985
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:17387
nlohmann::json_pointer::empty
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:11360
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:18914
nlohmann::basic_json::type_error
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:16045
nlohmann::anonymous_namespace{json.hpp}::from_json
constexpr const auto & from_json
Definition: json.hpp:3618
nlohmann::basic_json::swap
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:21654
nlohmann::basic_json::is_boolean
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:18213
nlohmann::basic_json::object_comparator_t
std::less< StringType > object_comparator_t
Definition: json.hpp:16201
nlohmann::basic_json::crend
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:20505
nlohmann::basic_json::rbegin
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:20402
nlohmann::basic_json::is_discarded
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:18443
nlohmann::basic_json::get_binary
binary_t & get_binary()
Definition: json.hpp:19022
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:17524
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:11988
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:16024
nlohmann::basic_json::is_number_float
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:18328
nlohmann::basic_json::boolean_t
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:16416
nlohmann::basic_json::external_constructor
friend struct detail::external_constructor
Definition: json.hpp:15964
nlohmann::basic_json::binary_t
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:16698
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:23569
nlohmann::basic_json::back
reference back()
access the last element
Definition: json.hpp:19744
nlohmann::basic_json::const_reference
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:16069
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:4274
nlohmann::adl_serializer
default JSONSerializer template argument
Definition: json.hpp:4188
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:24397
nlohmann::basic_json::cbegin
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:20301
nlohmann::basic_json::array
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:17570
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:4199
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:21249
nlohmann::basic_json::json_pointer
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:16018
nlohmann::basic_json::get
BasicJsonType get() const
get special-case overload
Definition: json.hpp:18658
nlohmann::basic_json::operator>=
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:22244
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:4931
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:16089
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:20158
nlohmann::basic_json::parser_callback_t
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:17089
nlohmann::basic_json::is_null
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:18191
nlohmann::basic_json::operator<=
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:22152
nlohmann::basic_json::cend
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:20372
nlohmann::basic_json::flatten
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:23789
nlohmann::basic_json::empty
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:20716
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:24183
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:11205
nlohmann::basic_json::basic_json
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:17154
nlohmann::basic_json::operator+=
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:21033
nlohmann::basic_json::get_ref
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:18961
nlohmann::json_sax::number_float_t
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:4933
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:16082
nlohmann::basic_json::is_string
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:18394
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:18902
nlohmann::basic_json::is_array
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:18372
nlohmann::basic_json::operator<<
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:22311
nlohmann::json_sax::number_unsigned_t
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.hpp:4932
nlohmann::basic_json::out_of_range
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:16047
nlohmann::basic_json::front
reference front()
access the first element
Definition: json.hpp:19700
nlohmann::json_sax::start_array
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
nlohmann::basic_json::pointer
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:16080
nlohmann::basic_json::string_t
StringType string_t
a type for a string
Definition: json.hpp:16390
nlohmann::json_sax::~json_sax
virtual ~json_sax()=default
nlohmann::basic_json::type
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:18111
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:17467
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:4264
nlohmann::basic_json::insert
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:21317
nlohmann::basic_json::get_ref
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:18948
nlohmann::basic_json::is_number
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:18243
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:11335
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:11185
nlohmann::basic_json::clear
void clear() noexcept
clears the contents
Definition: json.hpp:20931
nlohmann::basic_json::basic_json
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:17706
nlohmann::basic_json::number_float_t
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:16627
nlohmann::basic_json::items
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:20651
nlohmann::basic_json::is_structured
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:18169
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:11139
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:11341
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:23106
nlohmann::basic_json::update
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:21552
nlohmann::basic_json::basic_json
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:17925
nlohmann::json_sax::string_t
typename BasicJsonType::string_t string_t
Definition: json.hpp:4934
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:15962
nlohmann::json_sax::end_object
virtual bool end_object()=0
the end of an object was read
nlohmann::basic_json::operator[]
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:19285
nlohmann::byte_container_with_subtype::clear_subtype
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:4381
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:17227
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:11246
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:12005
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::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:21008
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:18708
nlohmann::byte_container_with_subtype::subtype
constexpr std::uint8_t subtype() const noexcept
return the binary subtype
Definition: json.hpp:4336
nlohmann::basic_json::end
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:20332
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:24358
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:18854
nlohmann::basic_json::parse_error
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:16041
nlohmann::basic_json::insert_iterator
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:21279
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:18867
nlohmann::anonymous_namespace{json.hpp}::to_json
constexpr const auto & to_json
Definition: json.hpp:4178
nlohmann::byte_container_with_subtype::byte_container_with_subtype
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:4256
nlohmann::basic_json::exception
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:16039
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:4260
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:18817
nlohmann::json_pointer::json_pointer
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:11089
nlohmann::json_pointer::pop_back
void pop_back()
remove last reference token
Definition: json.hpp:11289
nlohmann::basic_json::reference
value_type & reference
the type of an element reference
Definition: json.hpp:16067
nlohmann::basic_json::operator=
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value and std::is_nothrow_move_assignable< value_t >::value and std::is_nothrow_move_constructible< json_value >::value and std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:17962
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:11163
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:20569
nlohmann::basic_json::json_serializer
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:16020
nlohmann::basic_json::iterator
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:16085
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:16091
nlohmann::basic_json::from_cbor
static basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in CBOR format
Definition: json.hpp:23239
nlohmann::json_pointer::parent_pointer
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:11264
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:11226
nlohmann::basic_json::max_size
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:20860
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:17504
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:2774
nlohmann::json_sax
SAX interface.
Definition: json.hpp:4930
nlohmann::basic_json::is_number_unsigned
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:18300
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:4268
nlohmann::basic_json::get
basic_json get() const
get special-case overload
Definition: json.hpp:18635
nlohmann::basic_json::push_back
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:21148
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:23468
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:4216
nlohmann::byte_container_with_subtype
an internal type for a backed binary type
Definition: json.hpp:4251
nlohmann::basic_json::operator<
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:22038
nlohmann::basic_json::get_binary
const binary_t & get_binary() const
Definition: json.hpp:19033
nlohmann::basic_json::basic_json
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:17130
nlohmann::basic_json::emplace_back
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:21196
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:22828
nlohmann::basic_json::is_binary
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:18416
nlohmann::basic_json::~basic_json
~basic_json() noexcept
destructor
Definition: json.hpp:17995
nlohmann::basic_json::binary
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:17514
nlohmann::basic_json::patch
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:23887
nlohmann::basic_json::is_object
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:18350
nlohmann::byte_container_with_subtype::container_type
BinaryType container_type
the type of the underlying container
Definition: json.hpp:4254