1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++
4 |  |  |__   |  |  | | | |  version 3.9.0
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 0
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48 
49 // #include <nlohmann/adl_serializer.hpp>
50 
51 
52 #include <utility>
53 
54 // #include <nlohmann/detail/conversions/from_json.hpp>
55 
56 
57 #include <algorithm> // transform
58 #include <array> // array
59 #include <forward_list> // forward_list
60 #include <iterator> // inserter, front_inserter, end
61 #include <map> // map
62 #include <string> // string
63 #include <tuple> // tuple, make_tuple
64 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65 #include <unordered_map> // unordered_map
66 #include <utility> // pair, declval
67 #include <valarray> // valarray
68 
69 // #include <nlohmann/detail/exceptions.hpp>
70 
71 
72 #include <exception> // exception
73 #include <stdexcept> // runtime_error
74 #include <string> // to_string
75 
76 // #include <nlohmann/detail/input/position_t.hpp>
77 
78 
79 #include <cstddef> // size_t
80 
81 namespace nlohmann
82 {
83 namespace detail
84 {
85 /// struct to capture the start position of the current token
86 struct position_t
87 {
88     /// the total number of characters read
89     std::size_t chars_read_total = 0;
90     /// the number of characters read in the current line
91     std::size_t chars_read_current_line = 0;
92     /// the number of lines read
93     std::size_t lines_read = 0;
94 
95     /// conversion to size_t to preserve SAX interface
operator size_tnlohmann::detail::position_t96     constexpr operator size_t() const
97     {
98         return chars_read_total;
99     }
100 };
101 
102 } // namespace detail
103 } // namespace nlohmann
104 
105 // #include <nlohmann/detail/macro_scope.hpp>
106 
107 
108 #include <utility> // pair
109 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
110 /* Hedley - https://nemequ.github.io/hedley
111  * Created by Evan Nemerson <evan@nemerson.com>
112  *
113  * To the extent possible under law, the author(s) have dedicated all
114  * copyright and related and neighboring rights to this software to
115  * the public domain worldwide. This software is distributed without
116  * any warranty.
117  *
118  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
119  * SPDX-License-Identifier: CC0-1.0
120  */
121 
122 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 13)
123 #if defined(JSON_HEDLEY_VERSION)
124     #undef JSON_HEDLEY_VERSION
125 #endif
126 #define JSON_HEDLEY_VERSION 13
127 
128 #if defined(JSON_HEDLEY_STRINGIFY_EX)
129     #undef JSON_HEDLEY_STRINGIFY_EX
130 #endif
131 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
132 
133 #if defined(JSON_HEDLEY_STRINGIFY)
134     #undef JSON_HEDLEY_STRINGIFY
135 #endif
136 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
137 
138 #if defined(JSON_HEDLEY_CONCAT_EX)
139     #undef JSON_HEDLEY_CONCAT_EX
140 #endif
141 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
142 
143 #if defined(JSON_HEDLEY_CONCAT)
144     #undef JSON_HEDLEY_CONCAT
145 #endif
146 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
147 
148 #if defined(JSON_HEDLEY_CONCAT3_EX)
149     #undef JSON_HEDLEY_CONCAT3_EX
150 #endif
151 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
152 
153 #if defined(JSON_HEDLEY_CONCAT3)
154     #undef JSON_HEDLEY_CONCAT3
155 #endif
156 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
157 
158 #if defined(JSON_HEDLEY_VERSION_ENCODE)
159     #undef JSON_HEDLEY_VERSION_ENCODE
160 #endif
161 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
162 
163 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
164     #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
165 #endif
166 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
167 
168 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
169     #undef JSON_HEDLEY_VERSION_DECODE_MINOR
170 #endif
171 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
172 
173 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
174     #undef JSON_HEDLEY_VERSION_DECODE_REVISION
175 #endif
176 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
177 
178 #if defined(JSON_HEDLEY_GNUC_VERSION)
179     #undef JSON_HEDLEY_GNUC_VERSION
180 #endif
181 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
182     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
183 #elif defined(__GNUC__)
184     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
185 #endif
186 
187 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
188     #undef JSON_HEDLEY_GNUC_VERSION_CHECK
189 #endif
190 #if defined(JSON_HEDLEY_GNUC_VERSION)
191     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
192 #else
193     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
194 #endif
195 
196 #if defined(JSON_HEDLEY_MSVC_VERSION)
197     #undef JSON_HEDLEY_MSVC_VERSION
198 #endif
199 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000)
200     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
201 #elif defined(_MSC_FULL_VER)
202     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
203 #elif defined(_MSC_VER)
204     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
205 #endif
206 
207 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
208     #undef JSON_HEDLEY_MSVC_VERSION_CHECK
209 #endif
210 #if !defined(_MSC_VER)
211     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
212 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
213     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
214 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
215     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
216 #else
217     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
218 #endif
219 
220 #if defined(JSON_HEDLEY_INTEL_VERSION)
221     #undef JSON_HEDLEY_INTEL_VERSION
222 #endif
223 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE)
224     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
225 #elif defined(__INTEL_COMPILER)
226     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
227 #endif
228 
229 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
230     #undef JSON_HEDLEY_INTEL_VERSION_CHECK
231 #endif
232 #if defined(JSON_HEDLEY_INTEL_VERSION)
233     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
234 #else
235     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
236 #endif
237 
238 #if defined(JSON_HEDLEY_PGI_VERSION)
239     #undef JSON_HEDLEY_PGI_VERSION
240 #endif
241 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
242     #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
243 #endif
244 
245 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
246     #undef JSON_HEDLEY_PGI_VERSION_CHECK
247 #endif
248 #if defined(JSON_HEDLEY_PGI_VERSION)
249     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
250 #else
251     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
252 #endif
253 
254 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
255     #undef JSON_HEDLEY_SUNPRO_VERSION
256 #endif
257 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
258     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
259 #elif defined(__SUNPRO_C)
260     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
261 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
262     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
263 #elif defined(__SUNPRO_CC)
264     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
265 #endif
266 
267 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
268     #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
269 #endif
270 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
271     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
272 #else
273     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
274 #endif
275 
276 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
277     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
278 #endif
279 #if defined(__EMSCRIPTEN__)
280     #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
281 #endif
282 
283 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
284     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
285 #endif
286 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
287     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
288 #else
289     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
290 #endif
291 
292 #if defined(JSON_HEDLEY_ARM_VERSION)
293     #undef JSON_HEDLEY_ARM_VERSION
294 #endif
295 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
296     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
297 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
298     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
299 #endif
300 
301 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
302     #undef JSON_HEDLEY_ARM_VERSION_CHECK
303 #endif
304 #if defined(JSON_HEDLEY_ARM_VERSION)
305     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
306 #else
307     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
308 #endif
309 
310 #if defined(JSON_HEDLEY_IBM_VERSION)
311     #undef JSON_HEDLEY_IBM_VERSION
312 #endif
313 #if defined(__ibmxl__)
314     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
315 #elif defined(__xlC__) && defined(__xlC_ver__)
316     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
317 #elif defined(__xlC__)
318     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
319 #endif
320 
321 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
322     #undef JSON_HEDLEY_IBM_VERSION_CHECK
323 #endif
324 #if defined(JSON_HEDLEY_IBM_VERSION)
325     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
326 #else
327     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
328 #endif
329 
330 #if defined(JSON_HEDLEY_TI_VERSION)
331     #undef JSON_HEDLEY_TI_VERSION
332 #endif
333 #if \
334     defined(__TI_COMPILER_VERSION__) && \
335     ( \
336       defined(__TMS470__) || defined(__TI_ARM__) || \
337       defined(__MSP430__) || \
338       defined(__TMS320C2000__) \
339     )
340 #if (__TI_COMPILER_VERSION__ >= 16000000)
341     #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
342 #endif
343 #endif
344 
345 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
346     #undef JSON_HEDLEY_TI_VERSION_CHECK
347 #endif
348 #if defined(JSON_HEDLEY_TI_VERSION)
349     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
350 #else
351     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
352 #endif
353 
354 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
355     #undef JSON_HEDLEY_TI_CL2000_VERSION
356 #endif
357 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
358     #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
359 #endif
360 
361 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
362     #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
363 #endif
364 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
365     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366 #else
367     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
368 #endif
369 
370 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
371     #undef JSON_HEDLEY_TI_CL430_VERSION
372 #endif
373 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
374     #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
375 #endif
376 
377 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
378     #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
379 #endif
380 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
381     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
382 #else
383     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
384 #endif
385 
386 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
387     #undef JSON_HEDLEY_TI_ARMCL_VERSION
388 #endif
389 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
390     #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
391 #endif
392 
393 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
394     #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
395 #endif
396 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
397     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
398 #else
399     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
400 #endif
401 
402 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
403     #undef JSON_HEDLEY_TI_CL6X_VERSION
404 #endif
405 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
406     #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
407 #endif
408 
409 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
410     #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
411 #endif
412 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
413     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
414 #else
415     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
416 #endif
417 
418 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
419     #undef JSON_HEDLEY_TI_CL7X_VERSION
420 #endif
421 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
422     #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
423 #endif
424 
425 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
426     #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
427 #endif
428 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
429     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430 #else
431     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
432 #endif
433 
434 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
435     #undef JSON_HEDLEY_TI_CLPRU_VERSION
436 #endif
437 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
438     #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439 #endif
440 
441 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
442     #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
445     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_CRAY_VERSION)
451     #undef JSON_HEDLEY_CRAY_VERSION
452 #endif
453 #if defined(_CRAYC)
454     #if defined(_RELEASE_PATCHLEVEL)
455         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
456     #else
457         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
458     #endif
459 #endif
460 
461 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
462     #undef JSON_HEDLEY_CRAY_VERSION_CHECK
463 #endif
464 #if defined(JSON_HEDLEY_CRAY_VERSION)
465     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
466 #else
467     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
468 #endif
469 
470 #if defined(JSON_HEDLEY_IAR_VERSION)
471     #undef JSON_HEDLEY_IAR_VERSION
472 #endif
473 #if defined(__IAR_SYSTEMS_ICC__)
474     #if __VER__ > 1000
475         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
476     #else
477         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
478     #endif
479 #endif
480 
481 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
482     #undef JSON_HEDLEY_IAR_VERSION_CHECK
483 #endif
484 #if defined(JSON_HEDLEY_IAR_VERSION)
485     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
486 #else
487     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
488 #endif
489 
490 #if defined(JSON_HEDLEY_TINYC_VERSION)
491     #undef JSON_HEDLEY_TINYC_VERSION
492 #endif
493 #if defined(__TINYC__)
494     #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
495 #endif
496 
497 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
498     #undef JSON_HEDLEY_TINYC_VERSION_CHECK
499 #endif
500 #if defined(JSON_HEDLEY_TINYC_VERSION)
501     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
502 #else
503     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
504 #endif
505 
506 #if defined(JSON_HEDLEY_DMC_VERSION)
507     #undef JSON_HEDLEY_DMC_VERSION
508 #endif
509 #if defined(__DMC__)
510     #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
511 #endif
512 
513 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
514     #undef JSON_HEDLEY_DMC_VERSION_CHECK
515 #endif
516 #if defined(JSON_HEDLEY_DMC_VERSION)
517     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
518 #else
519     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
520 #endif
521 
522 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
523     #undef JSON_HEDLEY_COMPCERT_VERSION
524 #endif
525 #if defined(__COMPCERT_VERSION__)
526     #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
527 #endif
528 
529 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
530     #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
533     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537 
538 #if defined(JSON_HEDLEY_PELLES_VERSION)
539     #undef JSON_HEDLEY_PELLES_VERSION
540 #endif
541 #if defined(__POCC__)
542     #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
543 #endif
544 
545 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
546     #undef JSON_HEDLEY_PELLES_VERSION_CHECK
547 #endif
548 #if defined(JSON_HEDLEY_PELLES_VERSION)
549     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
550 #else
551     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
552 #endif
553 
554 #if defined(JSON_HEDLEY_GCC_VERSION)
555     #undef JSON_HEDLEY_GCC_VERSION
556 #endif
557 #if \
558     defined(JSON_HEDLEY_GNUC_VERSION) && \
559     !defined(__clang__) && \
560     !defined(JSON_HEDLEY_INTEL_VERSION) && \
561     !defined(JSON_HEDLEY_PGI_VERSION) && \
562     !defined(JSON_HEDLEY_ARM_VERSION) && \
563     !defined(JSON_HEDLEY_TI_VERSION) && \
564     !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
565     !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
566     !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
567     !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
568     !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
569     !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
570     !defined(__COMPCERT__)
571     #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
572 #endif
573 
574 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
575     #undef JSON_HEDLEY_GCC_VERSION_CHECK
576 #endif
577 #if defined(JSON_HEDLEY_GCC_VERSION)
578     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
579 #else
580     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
581 #endif
582 
583 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
584     #undef JSON_HEDLEY_HAS_ATTRIBUTE
585 #endif
586 #if defined(__has_attribute)
587     #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
588 #else
589     #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
590 #endif
591 
592 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
593     #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
594 #endif
595 #if defined(__has_attribute)
596     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
597 #else
598     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
599 #endif
600 
601 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
602     #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
603 #endif
604 #if defined(__has_attribute)
605     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
606 #else
607     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
608 #endif
609 
610 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
611     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
612 #endif
613 #if \
614     defined(__has_cpp_attribute) && \
615     defined(__cplusplus) && \
616     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
617     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
618 #else
619     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
620 #endif
621 
622 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
623     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
624 #endif
625 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
626     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
627 #elif \
628     !defined(JSON_HEDLEY_PGI_VERSION) && \
629     !defined(JSON_HEDLEY_IAR_VERSION) && \
630     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
631     (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
632     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
633 #else
634     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
635 #endif
636 
637 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
638     #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
639 #endif
640 #if defined(__has_cpp_attribute) && defined(__cplusplus)
641     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
642 #else
643     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
644 #endif
645 
646 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
647     #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
648 #endif
649 #if defined(__has_cpp_attribute) && defined(__cplusplus)
650     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
651 #else
652     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
653 #endif
654 
655 #if defined(JSON_HEDLEY_HAS_BUILTIN)
656     #undef JSON_HEDLEY_HAS_BUILTIN
657 #endif
658 #if defined(__has_builtin)
659     #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
660 #else
661     #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
662 #endif
663 
664 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
665     #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
666 #endif
667 #if defined(__has_builtin)
668     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
669 #else
670     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
671 #endif
672 
673 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
674     #undef JSON_HEDLEY_GCC_HAS_BUILTIN
675 #endif
676 #if defined(__has_builtin)
677     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
678 #else
679     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
680 #endif
681 
682 #if defined(JSON_HEDLEY_HAS_FEATURE)
683     #undef JSON_HEDLEY_HAS_FEATURE
684 #endif
685 #if defined(__has_feature)
686     #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
687 #else
688     #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
689 #endif
690 
691 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
692     #undef JSON_HEDLEY_GNUC_HAS_FEATURE
693 #endif
694 #if defined(__has_feature)
695     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
696 #else
697     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
698 #endif
699 
700 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
701     #undef JSON_HEDLEY_GCC_HAS_FEATURE
702 #endif
703 #if defined(__has_feature)
704     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
705 #else
706     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
707 #endif
708 
709 #if defined(JSON_HEDLEY_HAS_EXTENSION)
710     #undef JSON_HEDLEY_HAS_EXTENSION
711 #endif
712 #if defined(__has_extension)
713     #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
714 #else
715     #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
716 #endif
717 
718 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
719     #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
720 #endif
721 #if defined(__has_extension)
722     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
723 #else
724     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
725 #endif
726 
727 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
728     #undef JSON_HEDLEY_GCC_HAS_EXTENSION
729 #endif
730 #if defined(__has_extension)
731     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
732 #else
733     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
734 #endif
735 
736 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
737     #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
738 #endif
739 #if defined(__has_declspec_attribute)
740     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
741 #else
742     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
743 #endif
744 
745 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
746     #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
747 #endif
748 #if defined(__has_declspec_attribute)
749     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
750 #else
751     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
752 #endif
753 
754 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
755     #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
756 #endif
757 #if defined(__has_declspec_attribute)
758     #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
759 #else
760     #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
761 #endif
762 
763 #if defined(JSON_HEDLEY_HAS_WARNING)
764     #undef JSON_HEDLEY_HAS_WARNING
765 #endif
766 #if defined(__has_warning)
767     #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
768 #else
769     #define JSON_HEDLEY_HAS_WARNING(warning) (0)
770 #endif
771 
772 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
773     #undef JSON_HEDLEY_GNUC_HAS_WARNING
774 #endif
775 #if defined(__has_warning)
776     #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
777 #else
778     #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
779 #endif
780 
781 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
782     #undef JSON_HEDLEY_GCC_HAS_WARNING
783 #endif
784 #if defined(__has_warning)
785     #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
786 #else
787     #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
788 #endif
789 
790 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
791    HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
792 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
793     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
794 #endif
795 #if defined(__cplusplus)
796 #  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
797 #    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
798 #      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
799     JSON_HEDLEY_DIAGNOSTIC_PUSH \
800     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
801     _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
802     xpr \
803     JSON_HEDLEY_DIAGNOSTIC_POP
804 #    else
805 #      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
806     JSON_HEDLEY_DIAGNOSTIC_PUSH \
807     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
808     xpr \
809     JSON_HEDLEY_DIAGNOSTIC_POP
810 #    endif
811 #  endif
812 #endif
813 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
814     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
815 #endif
816 
817 #if defined(JSON_HEDLEY_CONST_CAST)
818     #undef JSON_HEDLEY_CONST_CAST
819 #endif
820 #if defined(__cplusplus)
821 #  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
822 #elif \
823   JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
824   JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
825   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
826 #  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
827         JSON_HEDLEY_DIAGNOSTIC_PUSH \
828         JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
829         ((T) (expr)); \
830         JSON_HEDLEY_DIAGNOSTIC_POP \
831     }))
832 #else
833 #  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
834 #endif
835 
836 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
837     #undef JSON_HEDLEY_REINTERPRET_CAST
838 #endif
839 #if defined(__cplusplus)
840     #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
841 #else
842     #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
843 #endif
844 
845 #if defined(JSON_HEDLEY_STATIC_CAST)
846     #undef JSON_HEDLEY_STATIC_CAST
847 #endif
848 #if defined(__cplusplus)
849     #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
850 #else
851     #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
852 #endif
853 
854 #if defined(JSON_HEDLEY_CPP_CAST)
855     #undef JSON_HEDLEY_CPP_CAST
856 #endif
857 #if defined(__cplusplus)
858 #  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
859 #    define JSON_HEDLEY_CPP_CAST(T, expr) \
860     JSON_HEDLEY_DIAGNOSTIC_PUSH \
861     _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
862     ((T) (expr)) \
863     JSON_HEDLEY_DIAGNOSTIC_POP
864 #  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
865 #    define JSON_HEDLEY_CPP_CAST(T, expr) \
866     JSON_HEDLEY_DIAGNOSTIC_PUSH \
867     _Pragma("diag_suppress=Pe137") \
868     JSON_HEDLEY_DIAGNOSTIC_POP \
869 #  else
870 #    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
871 #  endif
872 #else
873 #  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
874 #endif
875 
876 #if \
877     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
878     defined(__clang__) || \
879     JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
880     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
881     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
882     JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
883     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
884     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
885     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
886     JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
887     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
888     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
889     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
890     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
891     JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
892     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
893     JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
894     (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
895     #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
896 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
897     #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
898 #else
899     #define JSON_HEDLEY_PRAGMA(value)
900 #endif
901 
902 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
903     #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
904 #endif
905 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
906     #undef JSON_HEDLEY_DIAGNOSTIC_POP
907 #endif
908 #if defined(__clang__)
909     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
910     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
911 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
912     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
913     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
914 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
915     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
916     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
917 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
918     #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
919     #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
920 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
921     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
922     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
923 #elif \
924     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
925     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
926     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
927     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
928     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
929     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
930     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
931     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
932 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
933     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
934     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
935 #else
936     #define JSON_HEDLEY_DIAGNOSTIC_PUSH
937     #define JSON_HEDLEY_DIAGNOSTIC_POP
938 #endif
939 
940 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
941     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
942 #endif
943 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
944     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
945 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
946     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
947 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
948     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
949 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
950     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
951 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
952     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
953 #elif \
954     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
955     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
956     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
957     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
958     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
959     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
960     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
961     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
962     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
963     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
964     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
965     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
966 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
967     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
968 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
969     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
970 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
971     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
972 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
973     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
974 #else
975     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
976 #endif
977 
978 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
979     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
980 #endif
981 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
982     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
983 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
984     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
985 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
986     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
987 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
988     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
989 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
990     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
991 #elif \
992     JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
993     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
994     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
995     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
996     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
997 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
998     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
999 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1000     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1001 #else
1002     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1003 #endif
1004 
1005 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1006     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1007 #endif
1008 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1009     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1010 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1011     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1012 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1013     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1014 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1015     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1016 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1017     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1018 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1019     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1020 #elif \
1021     JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1022     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1023     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1024     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1025 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1026     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1027 #else
1028     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1029 #endif
1030 
1031 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1032     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1033 #endif
1034 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1035     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1036 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1037     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1038 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1039     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1040 #else
1041     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1042 #endif
1043 
1044 #if defined(JSON_HEDLEY_DEPRECATED)
1045     #undef JSON_HEDLEY_DEPRECATED
1046 #endif
1047 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1048     #undef JSON_HEDLEY_DEPRECATED_FOR
1049 #endif
1050 #if JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0)
1051     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1052     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1053 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1054     #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1055     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1056 #elif \
1057     JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1058     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1059     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1060     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1061     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1062     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1063     JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1064     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1065     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1066     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1067     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1068     #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1069     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1070 #elif \
1071     JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1072     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1073     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1074     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085     #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1086     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1087 #elif \
1088     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1089     JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0)
1090     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1091     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1092 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1093     #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1094     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1095 #else
1096     #define JSON_HEDLEY_DEPRECATED(since)
1097     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1098 #endif
1099 
1100 #if defined(JSON_HEDLEY_UNAVAILABLE)
1101     #undef JSON_HEDLEY_UNAVAILABLE
1102 #endif
1103 #if \
1104     JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1105     JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1106     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1107     #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1108 #else
1109     #define JSON_HEDLEY_UNAVAILABLE(available_since)
1110 #endif
1111 
1112 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1113     #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1114 #endif
1115 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1116     #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1117 #endif
1118 #if (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1119     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1120     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1121 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1122     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1123     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1124 #elif \
1125     JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1126     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1127     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1128     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1129     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1130     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1131     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1132     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1133     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1134     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1135     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1136     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1137     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1138     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1139     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1140     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1141     #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1142     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1143 #elif defined(_Check_return_) /* SAL */
1144     #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1145     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1146 #else
1147     #define JSON_HEDLEY_WARN_UNUSED_RESULT
1148     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1149 #endif
1150 
1151 #if defined(JSON_HEDLEY_SENTINEL)
1152     #undef JSON_HEDLEY_SENTINEL
1153 #endif
1154 #if \
1155     JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1156     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1157     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1158     JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1159     #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1160 #else
1161     #define JSON_HEDLEY_SENTINEL(position)
1162 #endif
1163 
1164 #if defined(JSON_HEDLEY_NO_RETURN)
1165     #undef JSON_HEDLEY_NO_RETURN
1166 #endif
1167 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1168     #define JSON_HEDLEY_NO_RETURN __noreturn
1169 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1170     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1171 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1172     #define JSON_HEDLEY_NO_RETURN _Noreturn
1173 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1174     #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1175 #elif \
1176     JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1177     JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1178     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1179     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1180     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1181     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1182     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1183     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1184     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1185     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1186     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1187     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1188     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1189     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1190     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1191     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1192     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1193 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1194     #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1195 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1196     #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1197 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1198     #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1199 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1200     #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1201 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1202     #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1203 #else
1204     #define JSON_HEDLEY_NO_RETURN
1205 #endif
1206 
1207 #if defined(JSON_HEDLEY_NO_ESCAPE)
1208     #undef JSON_HEDLEY_NO_ESCAPE
1209 #endif
1210 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1211     #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1212 #else
1213     #define JSON_HEDLEY_NO_ESCAPE
1214 #endif
1215 
1216 #if defined(JSON_HEDLEY_UNREACHABLE)
1217     #undef JSON_HEDLEY_UNREACHABLE
1218 #endif
1219 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1220     #undef JSON_HEDLEY_UNREACHABLE_RETURN
1221 #endif
1222 #if defined(JSON_HEDLEY_ASSUME)
1223     #undef JSON_HEDLEY_ASSUME
1224 #endif
1225 #if \
1226     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1227     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1228     #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1229 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1230     #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1231 #elif \
1232     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1233     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1234     #if defined(__cplusplus)
1235         #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1236     #else
1237         #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1238     #endif
1239 #endif
1240 #if \
1241     (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1242     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1243     JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1244     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1245     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1246     #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1247 #elif defined(JSON_HEDLEY_ASSUME)
1248     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1249 #endif
1250 #if !defined(JSON_HEDLEY_ASSUME)
1251     #if defined(JSON_HEDLEY_UNREACHABLE)
1252         #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1253     #else
1254         #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1255     #endif
1256 #endif
1257 #if defined(JSON_HEDLEY_UNREACHABLE)
1258     #if  \
1259         JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1260         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1261         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1262     #else
1263         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1264     #endif
1265 #else
1266     #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1267 #endif
1268 #if !defined(JSON_HEDLEY_UNREACHABLE)
1269     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1270 #endif
1271 
1272 JSON_HEDLEY_DIAGNOSTIC_PUSH
1273 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1274     #pragma clang diagnostic ignored "-Wpedantic"
1275 #endif
1276 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1277     #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1278 #endif
1279 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1280     #if defined(__clang__)
1281         #pragma clang diagnostic ignored "-Wvariadic-macros"
1282     #elif defined(JSON_HEDLEY_GCC_VERSION)
1283         #pragma GCC diagnostic ignored "-Wvariadic-macros"
1284     #endif
1285 #endif
1286 #if defined(JSON_HEDLEY_NON_NULL)
1287     #undef JSON_HEDLEY_NON_NULL
1288 #endif
1289 #if \
1290     JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1291     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1292     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1293     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1294     #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1295 #else
1296     #define JSON_HEDLEY_NON_NULL(...)
1297 #endif
1298 JSON_HEDLEY_DIAGNOSTIC_POP
1299 
1300 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1301     #undef JSON_HEDLEY_PRINTF_FORMAT
1302 #endif
1303 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1304     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1305 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1306     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1307 #elif \
1308     JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1309     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1310     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1312     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1313     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1314     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1315     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1316     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1317     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1318     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1319     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1320     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1321     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1322     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1323     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1324     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1325 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1326     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1327 #else
1328     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1329 #endif
1330 
1331 #if defined(JSON_HEDLEY_CONSTEXPR)
1332     #undef JSON_HEDLEY_CONSTEXPR
1333 #endif
1334 #if defined(__cplusplus)
1335     #if __cplusplus >= 201103L
1336         #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1337     #endif
1338 #endif
1339 #if !defined(JSON_HEDLEY_CONSTEXPR)
1340     #define JSON_HEDLEY_CONSTEXPR
1341 #endif
1342 
1343 #if defined(JSON_HEDLEY_PREDICT)
1344     #undef JSON_HEDLEY_PREDICT
1345 #endif
1346 #if defined(JSON_HEDLEY_LIKELY)
1347     #undef JSON_HEDLEY_LIKELY
1348 #endif
1349 #if defined(JSON_HEDLEY_UNLIKELY)
1350     #undef JSON_HEDLEY_UNLIKELY
1351 #endif
1352 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1353     #undef JSON_HEDLEY_UNPREDICTABLE
1354 #endif
1355 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1356     #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1357 #endif
1358 #if \
1359   JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \
1360   JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1361 #  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
1362 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
1363 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
1364 #  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
1365 #  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
1366 #elif \
1367   JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) || \
1368   JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1369   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1370   (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1371   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1372   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1373   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1374   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1375   JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1376   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1377   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1378   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1379   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1380   JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1381   JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1382 #  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1383     (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1384 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1385     (__extension__ ({ \
1386         double hedley_probability_ = (probability); \
1387         ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1388     }))
1389 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1390     (__extension__ ({ \
1391         double hedley_probability_ = (probability); \
1392         ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1393     }))
1394 #  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
1395 #  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1396 #else
1397 #  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1398 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1399 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1400 #  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1401 #  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1402 #endif
1403 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1404     #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1405 #endif
1406 
1407 #if defined(JSON_HEDLEY_MALLOC)
1408     #undef JSON_HEDLEY_MALLOC
1409 #endif
1410 #if \
1411     JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1412     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1413     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1415     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1416     JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1417     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1418     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1419     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1420     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1421     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1422     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1423     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1424     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1425     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1426     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1427     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1428     #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1429 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1430     #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1431 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(14, 0, 0)
1432     #define JSON_HEDLEY_MALLOC __declspec(restrict)
1433 #else
1434     #define JSON_HEDLEY_MALLOC
1435 #endif
1436 
1437 #if defined(JSON_HEDLEY_PURE)
1438     #undef JSON_HEDLEY_PURE
1439 #endif
1440 #if \
1441   JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1442   JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1443   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1444   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1445   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1446   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1447   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1448   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1449   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1450   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1451   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1452   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1453   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1454   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1455   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1456   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1457   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1458   JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1459 #  define JSON_HEDLEY_PURE __attribute__((__pure__))
1460 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1461 #  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1462 #elif defined(__cplusplus) && \
1463     ( \
1464       JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1465       JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1466       JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1467     )
1468 #  define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1469 #else
1470 #  define JSON_HEDLEY_PURE
1471 #endif
1472 
1473 #if defined(JSON_HEDLEY_CONST)
1474     #undef JSON_HEDLEY_CONST
1475 #endif
1476 #if \
1477     JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1478     JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1479     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1480     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1481     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1482     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1483     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1484     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1485     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1486     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1487     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1488     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1489     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1490     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1491     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1492     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1493     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1494     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1495     #define JSON_HEDLEY_CONST __attribute__((__const__))
1496 #elif \
1497     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1498     #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1499 #else
1500     #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1501 #endif
1502 
1503 #if defined(JSON_HEDLEY_RESTRICT)
1504     #undef JSON_HEDLEY_RESTRICT
1505 #endif
1506 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1507     #define JSON_HEDLEY_RESTRICT restrict
1508 #elif \
1509     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1510     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1511     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1512     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1513     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1514     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1515     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1516     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1517     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1518     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1519     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1520     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1521     defined(__clang__)
1522     #define JSON_HEDLEY_RESTRICT __restrict
1523 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1524     #define JSON_HEDLEY_RESTRICT _Restrict
1525 #else
1526     #define JSON_HEDLEY_RESTRICT
1527 #endif
1528 
1529 #if defined(JSON_HEDLEY_INLINE)
1530     #undef JSON_HEDLEY_INLINE
1531 #endif
1532 #if \
1533     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1534     (defined(__cplusplus) && (__cplusplus >= 199711L))
1535     #define JSON_HEDLEY_INLINE inline
1536 #elif \
1537     defined(JSON_HEDLEY_GCC_VERSION) || \
1538     JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1539     #define JSON_HEDLEY_INLINE __inline__
1540 #elif \
1541     JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1542     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1543     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1544     JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1545     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1546     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1547     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1548     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1549     #define JSON_HEDLEY_INLINE __inline
1550 #else
1551     #define JSON_HEDLEY_INLINE
1552 #endif
1553 
1554 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1555     #undef JSON_HEDLEY_ALWAYS_INLINE
1556 #endif
1557 #if \
1558   JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1559   JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1560   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1561   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1562   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1563   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1564   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1565   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1566   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1567   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1568   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1569   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1570   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1571   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1572   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1573   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1574   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1575 #  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1576 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0)
1577 #  define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1578 #elif defined(__cplusplus) && \
1579     ( \
1580       JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1581       JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1582       JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1583       JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1584       JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1585       JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1586     )
1587 #  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1588 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1589 #  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1590 #else
1591 #  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1592 #endif
1593 
1594 #if defined(JSON_HEDLEY_NEVER_INLINE)
1595     #undef JSON_HEDLEY_NEVER_INLINE
1596 #endif
1597 #if \
1598     JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1599     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1600     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1601     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1602     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1603     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1604     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1605     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1606     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1607     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1608     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1609     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1610     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1611     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1612     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1613     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1614     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1615     #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1616 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0)
1617     #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1618 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1619     #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1620 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1621     #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1622 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1623     #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1624 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1625     #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1626 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1627     #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1628 #else
1629     #define JSON_HEDLEY_NEVER_INLINE
1630 #endif
1631 
1632 #if defined(JSON_HEDLEY_PRIVATE)
1633     #undef JSON_HEDLEY_PRIVATE
1634 #endif
1635 #if defined(JSON_HEDLEY_PUBLIC)
1636     #undef JSON_HEDLEY_PUBLIC
1637 #endif
1638 #if defined(JSON_HEDLEY_IMPORT)
1639     #undef JSON_HEDLEY_IMPORT
1640 #endif
1641 #if defined(_WIN32) || defined(__CYGWIN__)
1642 #  define JSON_HEDLEY_PRIVATE
1643 #  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
1644 #  define JSON_HEDLEY_IMPORT   __declspec(dllimport)
1645 #else
1646 #  if \
1647     JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1648     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1649     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1651     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1652     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1653     ( \
1654       defined(__TI_EABI__) && \
1655       ( \
1656         (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1657         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1658       ) \
1659     )
1660 #    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1661 #    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
1662 #  else
1663 #    define JSON_HEDLEY_PRIVATE
1664 #    define JSON_HEDLEY_PUBLIC
1665 #  endif
1666 #  define JSON_HEDLEY_IMPORT    extern
1667 #endif
1668 
1669 #if defined(JSON_HEDLEY_NO_THROW)
1670     #undef JSON_HEDLEY_NO_THROW
1671 #endif
1672 #if \
1673     JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1674     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1675     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1676     #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1677 #elif \
1678     JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1679     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1680     #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1681 #else
1682     #define JSON_HEDLEY_NO_THROW
1683 #endif
1684 
1685 #if defined(JSON_HEDLEY_FALL_THROUGH)
1686     #undef JSON_HEDLEY_FALL_THROUGH
1687 #endif
1688 #if \
1689     JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1690     JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1691     #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1692 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1693     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1694 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1695     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1696 #elif defined(__fallthrough) /* SAL */
1697     #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1698 #else
1699     #define JSON_HEDLEY_FALL_THROUGH
1700 #endif
1701 
1702 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1703     #undef JSON_HEDLEY_RETURNS_NON_NULL
1704 #endif
1705 #if \
1706     JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1707     JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1708     #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1709 #elif defined(_Ret_notnull_) /* SAL */
1710     #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1711 #else
1712     #define JSON_HEDLEY_RETURNS_NON_NULL
1713 #endif
1714 
1715 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1716     #undef JSON_HEDLEY_ARRAY_PARAM
1717 #endif
1718 #if \
1719     defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1720     !defined(__STDC_NO_VLA__) && \
1721     !defined(__cplusplus) && \
1722     !defined(JSON_HEDLEY_PGI_VERSION) && \
1723     !defined(JSON_HEDLEY_TINYC_VERSION)
1724     #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1725 #else
1726     #define JSON_HEDLEY_ARRAY_PARAM(name)
1727 #endif
1728 
1729 #if defined(JSON_HEDLEY_IS_CONSTANT)
1730     #undef JSON_HEDLEY_IS_CONSTANT
1731 #endif
1732 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1733     #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1734 #endif
1735 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1736    HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
1737 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1738     #undef JSON_HEDLEY_IS_CONSTEXPR_
1739 #endif
1740 #if \
1741     JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1742     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1743     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1744     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1745     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1746     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1747     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1748     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1749     JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1750     #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1751 #endif
1752 #if !defined(__cplusplus)
1753 #  if \
1754        JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1755        JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1756        JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1757        JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1758        JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1759        JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1760        JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1761 #if defined(__INTPTR_TYPE__)
1762     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1763 #else
1764     #include <stdint.h>
1765     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1766 #endif
1767 #  elif \
1768        ( \
1769           defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1770           !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1771           !defined(JSON_HEDLEY_PGI_VERSION) && \
1772           !defined(JSON_HEDLEY_IAR_VERSION)) || \
1773        JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1774        JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1775        JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1776        JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1777        JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1778 #if defined(__INTPTR_TYPE__)
1779     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1780 #else
1781     #include <stdint.h>
1782     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1783 #endif
1784 #  elif \
1785        defined(JSON_HEDLEY_GCC_VERSION) || \
1786        defined(JSON_HEDLEY_INTEL_VERSION) || \
1787        defined(JSON_HEDLEY_TINYC_VERSION) || \
1788        defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1789        JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1790        defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1791        defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1792        defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1793        defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1794        defined(__clang__)
1795 #    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1796         sizeof(void) != \
1797         sizeof(*( \
1798                   1 ? \
1799                   ((void*) ((expr) * 0L) ) : \
1800 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1801                 ) \
1802               ) \
1803                                             )
1804 #  endif
1805 #endif
1806 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1807     #if !defined(JSON_HEDLEY_IS_CONSTANT)
1808         #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1809     #endif
1810     #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1811 #else
1812     #if !defined(JSON_HEDLEY_IS_CONSTANT)
1813         #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1814     #endif
1815     #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1816 #endif
1817 
1818 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1819     #undef JSON_HEDLEY_BEGIN_C_DECLS
1820 #endif
1821 #if defined(JSON_HEDLEY_END_C_DECLS)
1822     #undef JSON_HEDLEY_END_C_DECLS
1823 #endif
1824 #if defined(JSON_HEDLEY_C_DECL)
1825     #undef JSON_HEDLEY_C_DECL
1826 #endif
1827 #if defined(__cplusplus)
1828     #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1829     #define JSON_HEDLEY_END_C_DECLS }
1830     #define JSON_HEDLEY_C_DECL extern "C"
1831 #else
1832     #define JSON_HEDLEY_BEGIN_C_DECLS
1833     #define JSON_HEDLEY_END_C_DECLS
1834     #define JSON_HEDLEY_C_DECL
1835 #endif
1836 
1837 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1838     #undef JSON_HEDLEY_STATIC_ASSERT
1839 #endif
1840 #if \
1841   !defined(__cplusplus) && ( \
1842       (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1843       JSON_HEDLEY_HAS_FEATURE(c_static_assert) || \
1844       JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1845       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1846       defined(_Static_assert) \
1847     )
1848 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1849 #elif \
1850   (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1851   JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0)
1852 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1853 #else
1854 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1855 #endif
1856 
1857 #if defined(JSON_HEDLEY_NULL)
1858     #undef JSON_HEDLEY_NULL
1859 #endif
1860 #if defined(__cplusplus)
1861     #if __cplusplus >= 201103L
1862         #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1863     #elif defined(NULL)
1864         #define JSON_HEDLEY_NULL NULL
1865     #else
1866         #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1867     #endif
1868 #elif defined(NULL)
1869     #define JSON_HEDLEY_NULL NULL
1870 #else
1871     #define JSON_HEDLEY_NULL ((void*) 0)
1872 #endif
1873 
1874 #if defined(JSON_HEDLEY_MESSAGE)
1875     #undef JSON_HEDLEY_MESSAGE
1876 #endif
1877 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1878 #  define JSON_HEDLEY_MESSAGE(msg) \
1879     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1880     JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1881     JSON_HEDLEY_PRAGMA(message msg) \
1882     JSON_HEDLEY_DIAGNOSTIC_POP
1883 #elif \
1884   JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1885   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1886 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1887 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1888 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1889 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1890 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1891 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1892 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1893 #else
1894 #  define JSON_HEDLEY_MESSAGE(msg)
1895 #endif
1896 
1897 #if defined(JSON_HEDLEY_WARNING)
1898     #undef JSON_HEDLEY_WARNING
1899 #endif
1900 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1901 #  define JSON_HEDLEY_WARNING(msg) \
1902     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1903     JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1904     JSON_HEDLEY_PRAGMA(clang warning msg) \
1905     JSON_HEDLEY_DIAGNOSTIC_POP
1906 #elif \
1907   JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1908   JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1909   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1910 #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1911 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1912 #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1913 #else
1914 #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1915 #endif
1916 
1917 #if defined(JSON_HEDLEY_REQUIRE)
1918     #undef JSON_HEDLEY_REQUIRE
1919 #endif
1920 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1921     #undef JSON_HEDLEY_REQUIRE_MSG
1922 #endif
1923 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1924 #  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1925 #    define JSON_HEDLEY_REQUIRE(expr) \
1926     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1927     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1928     __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1929     JSON_HEDLEY_DIAGNOSTIC_POP
1930 #    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1931     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1932     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1933     __attribute__((diagnose_if(!(expr), msg, "error"))) \
1934     JSON_HEDLEY_DIAGNOSTIC_POP
1935 #  else
1936 #    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1937 #    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1938 #  endif
1939 #else
1940 #  define JSON_HEDLEY_REQUIRE(expr)
1941 #  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1942 #endif
1943 
1944 #if defined(JSON_HEDLEY_FLAGS)
1945     #undef JSON_HEDLEY_FLAGS
1946 #endif
1947 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
1948     #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
1949 #endif
1950 
1951 #if defined(JSON_HEDLEY_FLAGS_CAST)
1952     #undef JSON_HEDLEY_FLAGS_CAST
1953 #endif
1954 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
1955 #  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
1956         JSON_HEDLEY_DIAGNOSTIC_PUSH \
1957         _Pragma("warning(disable:188)") \
1958         ((T) (expr)); \
1959         JSON_HEDLEY_DIAGNOSTIC_POP \
1960     }))
1961 #else
1962 #  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
1963 #endif
1964 
1965 #if defined(JSON_HEDLEY_EMPTY_BASES)
1966     #undef JSON_HEDLEY_EMPTY_BASES
1967 #endif
1968 #if JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)
1969     #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
1970 #else
1971     #define JSON_HEDLEY_EMPTY_BASES
1972 #endif
1973 
1974 /* Remaining macros are deprecated. */
1975 
1976 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
1977     #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
1978 #endif
1979 #if defined(__clang__)
1980     #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
1981 #else
1982     #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
1983 #endif
1984 
1985 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
1986     #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
1987 #endif
1988 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
1989 
1990 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
1991     #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
1992 #endif
1993 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
1994 
1995 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
1996     #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
1997 #endif
1998 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
1999 
2000 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2001     #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2002 #endif
2003 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2004 
2005 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2006     #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2007 #endif
2008 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2009 
2010 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2011     #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2012 #endif
2013 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2014 
2015 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2016     #undef JSON_HEDLEY_CLANG_HAS_WARNING
2017 #endif
2018 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2019 
2020 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2021 
2022 
2023 // This file contains all internal macro definitions
2024 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2025 
2026 // exclude unsupported compilers
2027 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2028     #if defined(__clang__)
2029         #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2030             #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2031         #endif
2032     #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2033         #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2034             #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2035         #endif
2036     #endif
2037 #endif
2038 
2039 // C++ language standard detection
2040 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2041     #define JSON_HAS_CPP_20
2042     #define JSON_HAS_CPP_17
2043     #define JSON_HAS_CPP_14
2044 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2045     #define JSON_HAS_CPP_17
2046     #define JSON_HAS_CPP_14
2047 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2048     #define JSON_HAS_CPP_14
2049 #endif
2050 
2051 // disable float-equal warnings on GCC/clang
2052 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2053     #pragma GCC diagnostic push
2054     #pragma GCC diagnostic ignored "-Wfloat-equal"
2055 #endif
2056 
2057 // disable documentation warnings on clang
2058 #if defined(__clang__)
2059     #pragma GCC diagnostic push
2060     #pragma GCC diagnostic ignored "-Wdocumentation"
2061 #endif
2062 
2063 // allow to disable exceptions
2064 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2065     #define JSON_THROW(exception) throw exception
2066     #define JSON_TRY try
2067     #define JSON_CATCH(exception) catch(exception)
2068     #define JSON_INTERNAL_CATCH(exception) catch(exception)
2069 #else
2070     #include <cstdlib>
2071     #define JSON_THROW(exception) std::abort()
2072     #define JSON_TRY if(true)
2073     #define JSON_CATCH(exception) if(false)
2074     #define JSON_INTERNAL_CATCH(exception) if(false)
2075 #endif
2076 
2077 // override exception macros
2078 #if defined(JSON_THROW_USER)
2079     #undef JSON_THROW
2080     #define JSON_THROW JSON_THROW_USER
2081 #endif
2082 #if defined(JSON_TRY_USER)
2083     #undef JSON_TRY
2084     #define JSON_TRY JSON_TRY_USER
2085 #endif
2086 #if defined(JSON_CATCH_USER)
2087     #undef JSON_CATCH
2088     #define JSON_CATCH JSON_CATCH_USER
2089     #undef JSON_INTERNAL_CATCH
2090     #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2091 #endif
2092 #if defined(JSON_INTERNAL_CATCH_USER)
2093     #undef JSON_INTERNAL_CATCH
2094     #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2095 #endif
2096 
2097 // allow to override assert
2098 #if !defined(JSON_ASSERT)
2099     #include <cassert> // assert
2100     #define JSON_ASSERT(x) assert(x)
2101 #endif
2102 
2103 /*!
2104 @brief macro to briefly define a mapping between an enum and JSON
2105 @def NLOHMANN_JSON_SERIALIZE_ENUM
2106 @since version 3.4.0
2107 */
2108 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
2109     template<typename BasicJsonType>                                                            \
2110     inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
2111     {                                                                                           \
2112         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2113         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2114         auto it = std::find_if(std::begin(m), std::end(m),                                      \
2115                                [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
2116         {                                                                                       \
2117             return ej_pair.first == e;                                                          \
2118         });                                                                                     \
2119         j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
2120     }                                                                                           \
2121     template<typename BasicJsonType>                                                            \
2122     inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
2123     {                                                                                           \
2124         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2125         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2126         auto it = std::find_if(std::begin(m), std::end(m),                                      \
2127                                [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2128         {                                                                                       \
2129             return ej_pair.second == j;                                                         \
2130         });                                                                                     \
2131         e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
2132     }
2133 
2134 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2135 // may be removed in the future once the class is split.
2136 
2137 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
2138     template<template<typename, typename, typename...> class ObjectType,   \
2139              template<typename, typename...> class ArrayType,              \
2140              class StringType, class BooleanType, class NumberIntegerType, \
2141              class NumberUnsignedType, class NumberFloatType,              \
2142              template<typename> class AllocatorType,                       \
2143              template<typename, typename = void> class JSONSerializer,     \
2144              class BinaryType>
2145 
2146 #define NLOHMANN_BASIC_JSON_TPL                                            \
2147     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
2148     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
2149     AllocatorType, JSONSerializer, BinaryType>
2150 
2151 // Macros to simplify conversion from/to types
2152 
2153 #define NLOHMANN_JSON_EXPAND( x ) x
2154 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2155 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2156         NLOHMANN_JSON_PASTE64, \
2157         NLOHMANN_JSON_PASTE63, \
2158         NLOHMANN_JSON_PASTE62, \
2159         NLOHMANN_JSON_PASTE61, \
2160         NLOHMANN_JSON_PASTE60, \
2161         NLOHMANN_JSON_PASTE59, \
2162         NLOHMANN_JSON_PASTE58, \
2163         NLOHMANN_JSON_PASTE57, \
2164         NLOHMANN_JSON_PASTE56, \
2165         NLOHMANN_JSON_PASTE55, \
2166         NLOHMANN_JSON_PASTE54, \
2167         NLOHMANN_JSON_PASTE53, \
2168         NLOHMANN_JSON_PASTE52, \
2169         NLOHMANN_JSON_PASTE51, \
2170         NLOHMANN_JSON_PASTE50, \
2171         NLOHMANN_JSON_PASTE49, \
2172         NLOHMANN_JSON_PASTE48, \
2173         NLOHMANN_JSON_PASTE47, \
2174         NLOHMANN_JSON_PASTE46, \
2175         NLOHMANN_JSON_PASTE45, \
2176         NLOHMANN_JSON_PASTE44, \
2177         NLOHMANN_JSON_PASTE43, \
2178         NLOHMANN_JSON_PASTE42, \
2179         NLOHMANN_JSON_PASTE41, \
2180         NLOHMANN_JSON_PASTE40, \
2181         NLOHMANN_JSON_PASTE39, \
2182         NLOHMANN_JSON_PASTE38, \
2183         NLOHMANN_JSON_PASTE37, \
2184         NLOHMANN_JSON_PASTE36, \
2185         NLOHMANN_JSON_PASTE35, \
2186         NLOHMANN_JSON_PASTE34, \
2187         NLOHMANN_JSON_PASTE33, \
2188         NLOHMANN_JSON_PASTE32, \
2189         NLOHMANN_JSON_PASTE31, \
2190         NLOHMANN_JSON_PASTE30, \
2191         NLOHMANN_JSON_PASTE29, \
2192         NLOHMANN_JSON_PASTE28, \
2193         NLOHMANN_JSON_PASTE27, \
2194         NLOHMANN_JSON_PASTE26, \
2195         NLOHMANN_JSON_PASTE25, \
2196         NLOHMANN_JSON_PASTE24, \
2197         NLOHMANN_JSON_PASTE23, \
2198         NLOHMANN_JSON_PASTE22, \
2199         NLOHMANN_JSON_PASTE21, \
2200         NLOHMANN_JSON_PASTE20, \
2201         NLOHMANN_JSON_PASTE19, \
2202         NLOHMANN_JSON_PASTE18, \
2203         NLOHMANN_JSON_PASTE17, \
2204         NLOHMANN_JSON_PASTE16, \
2205         NLOHMANN_JSON_PASTE15, \
2206         NLOHMANN_JSON_PASTE14, \
2207         NLOHMANN_JSON_PASTE13, \
2208         NLOHMANN_JSON_PASTE12, \
2209         NLOHMANN_JSON_PASTE11, \
2210         NLOHMANN_JSON_PASTE10, \
2211         NLOHMANN_JSON_PASTE9, \
2212         NLOHMANN_JSON_PASTE8, \
2213         NLOHMANN_JSON_PASTE7, \
2214         NLOHMANN_JSON_PASTE6, \
2215         NLOHMANN_JSON_PASTE5, \
2216         NLOHMANN_JSON_PASTE4, \
2217         NLOHMANN_JSON_PASTE3, \
2218         NLOHMANN_JSON_PASTE2, \
2219         NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2220 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2221 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2222 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2223 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2224 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2225 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2226 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2227 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2228 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2229 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2230 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2231 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2232 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2233 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2234 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2235 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2236 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2237 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2238 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2239 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2240 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2241 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2242 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2243 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2244 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2245 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2246 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2247 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2248 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2249 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2250 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2251 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2252 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2253 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2254 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2255 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2256 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2257 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2258 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2259 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2260 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2261 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2262 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2263 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2264 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2265 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2266 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2267 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2268 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2269 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2270 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2271 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2272 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2273 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2274 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2275 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2276 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2277 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2278 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2279 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2280 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2281 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2282 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2283 
2284 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2285 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2286 
2287 /*!
2288 @brief macro
2289 @def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2290 @since version 3.9.0
2291 */
2292 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
2293     friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2294     friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2295 
2296 /*!
2297 @brief macro
2298 @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2299 @since version 3.9.0
2300 */
2301 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
2302     inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2303     inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2304 
2305 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2306     #define JSON_USE_IMPLICIT_CONVERSIONS 1
2307 #endif
2308 
2309 #if JSON_USE_IMPLICIT_CONVERSIONS
2310     #define JSON_EXPLICIT
2311 #else
2312     #define JSON_EXPLICIT explicit
2313 #endif
2314 
2315 
2316 namespace nlohmann
2317 {
2318 namespace detail
2319 {
2320 ////////////////
2321 // exceptions //
2322 ////////////////
2323 
2324 /*!
2325 @brief general exception of the @ref basic_json class
2326 
2327 This class is an extension of `std::exception` objects with a member @a id for
2328 exception ids. It is used as the base class for all exceptions thrown by the
2329 @ref basic_json class. This class can hence be used as "wildcard" to catch
2330 exceptions.
2331 
2332 Subclasses:
2333 - @ref parse_error for exceptions indicating a parse error
2334 - @ref invalid_iterator for exceptions indicating errors with iterators
2335 - @ref type_error for exceptions indicating executing a member function with
2336                   a wrong type
2337 - @ref out_of_range for exceptions indicating access out of the defined range
2338 - @ref other_error for exceptions indicating other library errors
2339 
2340 @internal
2341 @note To have nothrow-copy-constructible exceptions, we internally use
2342       `std::runtime_error` which can cope with arbitrary-length error messages.
2343       Intermediate strings are built with static functions and then passed to
2344       the actual constructor.
2345 @endinternal
2346 
2347 @liveexample{The following code shows how arbitrary library exceptions can be
2348 caught.,exception}
2349 
2350 @since version 3.0.0
2351 */
2352 class exception : public std::exception
2353 {
2354   public:
2355     /// returns the explanatory string
2356     JSON_HEDLEY_RETURNS_NON_NULL
what() const2357     const char* what() const noexcept override
2358     {
2359         return m.what();
2360     }
2361 
2362     /// the id of the exception
2363     const int id;
2364 
2365   protected:
2366     JSON_HEDLEY_NON_NULL(3)
exception(int id_,const char * what_arg)2367     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2368 
name(const std::string & ename,int id_)2369     static std::string name(const std::string& ename, int id_)
2370     {
2371         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2372     }
2373 
2374   private:
2375     /// an exception object as storage for error messages
2376     std::runtime_error m;
2377 };
2378 
2379 /*!
2380 @brief exception indicating a parse error
2381 
2382 This exception is thrown by the library when a parse error occurs. Parse errors
2383 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2384 as when using JSON Patch.
2385 
2386 Member @a byte holds the byte index of the last read character in the input
2387 file.
2388 
2389 Exceptions have ids 1xx.
2390 
2391 name / id                      | example message | description
2392 ------------------------------ | --------------- | -------------------------
2393 json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
2394 json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
2395 json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
2396 json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
2397 json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
2398 json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
2399 json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
2400 json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
2401 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2402 json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
2403 json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
2404 json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
2405 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2406 json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed.
2407 
2408 @note For an input with n bytes, 1 is the index of the first character and n+1
2409       is the index of the terminating null byte or the end of file. This also
2410       holds true when reading a byte vector (CBOR or MessagePack).
2411 
2412 @liveexample{The following code shows how a `parse_error` exception can be
2413 caught.,parse_error}
2414 
2415 @sa - @ref exception for the base class of the library exceptions
2416 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2417 @sa - @ref type_error for exceptions indicating executing a member function with
2418                     a wrong type
2419 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2420 @sa - @ref other_error for exceptions indicating other library errors
2421 
2422 @since version 3.0.0
2423 */
2424 class parse_error : public exception
2425 {
2426   public:
2427     /*!
2428     @brief create a parse error exception
2429     @param[in] id_       the id of the exception
2430     @param[in] pos       the position where the error occurred (or with
2431                          chars_read_total=0 if the position cannot be
2432                          determined)
2433     @param[in] what_arg  the explanatory string
2434     @return parse_error object
2435     */
create(int id_,const position_t & pos,const std::string & what_arg)2436     static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2437     {
2438         std::string w = exception::name("parse_error", id_) + "parse error" +
2439                         position_string(pos) + ": " + what_arg;
2440         return parse_error(id_, pos.chars_read_total, w.c_str());
2441     }
2442 
create(int id_,std::size_t byte_,const std::string & what_arg)2443     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2444     {
2445         std::string w = exception::name("parse_error", id_) + "parse error" +
2446                         (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2447                         ": " + what_arg;
2448         return parse_error(id_, byte_, w.c_str());
2449     }
2450 
2451     /*!
2452     @brief byte index of the parse error
2453 
2454     The byte index of the last read character in the input file.
2455 
2456     @note For an input with n bytes, 1 is the index of the first character and
2457           n+1 is the index of the terminating null byte or the end of file.
2458           This also holds true when reading a byte vector (CBOR or MessagePack).
2459     */
2460     const std::size_t byte;
2461 
2462   private:
parse_error(int id_,std::size_t byte_,const char * what_arg)2463     parse_error(int id_, std::size_t byte_, const char* what_arg)
2464         : exception(id_, what_arg), byte(byte_) {}
2465 
position_string(const position_t & pos)2466     static std::string position_string(const position_t& pos)
2467     {
2468         return " at line " + std::to_string(pos.lines_read + 1) +
2469                ", column " + std::to_string(pos.chars_read_current_line);
2470     }
2471 };
2472 
2473 /*!
2474 @brief exception indicating errors with iterators
2475 
2476 This exception is thrown if iterators passed to a library function do not match
2477 the expected semantics.
2478 
2479 Exceptions have ids 2xx.
2480 
2481 name / id                           | example message | description
2482 ----------------------------------- | --------------- | -------------------------
2483 json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2484 json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
2485 json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
2486 json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
2487 json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
2488 json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
2489 json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
2490 json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2491 json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2492 json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2493 json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
2494 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2495 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2496 json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
2497 
2498 @liveexample{The following code shows how an `invalid_iterator` exception can be
2499 caught.,invalid_iterator}
2500 
2501 @sa - @ref exception for the base class of the library exceptions
2502 @sa - @ref parse_error for exceptions indicating a parse error
2503 @sa - @ref type_error for exceptions indicating executing a member function with
2504                     a wrong type
2505 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2506 @sa - @ref other_error for exceptions indicating other library errors
2507 
2508 @since version 3.0.0
2509 */
2510 class invalid_iterator : public exception
2511 {
2512   public:
create(int id_,const std::string & what_arg)2513     static invalid_iterator create(int id_, const std::string& what_arg)
2514     {
2515         std::string w = exception::name("invalid_iterator", id_) + what_arg;
2516         return invalid_iterator(id_, w.c_str());
2517     }
2518 
2519   private:
2520     JSON_HEDLEY_NON_NULL(3)
invalid_iterator(int id_,const char * what_arg)2521     invalid_iterator(int id_, const char* what_arg)
2522         : exception(id_, what_arg) {}
2523 };
2524 
2525 /*!
2526 @brief exception indicating executing a member function with a wrong type
2527 
2528 This exception is thrown in case of a type error; that is, a library function is
2529 executed on a JSON value whose type does not match the expected semantics.
2530 
2531 Exceptions have ids 3xx.
2532 
2533 name / id                     | example message | description
2534 ----------------------------- | --------------- | -------------------------
2535 json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
2536 json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
2537 json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
2538 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2539 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2540 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2541 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2542 json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
2543 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2544 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2545 json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
2546 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2547 json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
2548 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2549 json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
2550 json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
2551 json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
2552 
2553 @liveexample{The following code shows how a `type_error` exception can be
2554 caught.,type_error}
2555 
2556 @sa - @ref exception for the base class of the library exceptions
2557 @sa - @ref parse_error for exceptions indicating a parse error
2558 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2559 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2560 @sa - @ref other_error for exceptions indicating other library errors
2561 
2562 @since version 3.0.0
2563 */
2564 class type_error : public exception
2565 {
2566   public:
create(int id_,const std::string & what_arg)2567     static type_error create(int id_, const std::string& what_arg)
2568     {
2569         std::string w = exception::name("type_error", id_) + what_arg;
2570         return type_error(id_, w.c_str());
2571     }
2572 
2573   private:
2574     JSON_HEDLEY_NON_NULL(3)
type_error(int id_,const char * what_arg)2575     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2576 };
2577 
2578 /*!
2579 @brief exception indicating access out of the defined range
2580 
2581 This exception is thrown in case a library function is called on an input
2582 parameter that exceeds the expected range, for instance in case of array
2583 indices or nonexisting object keys.
2584 
2585 Exceptions have ids 4xx.
2586 
2587 name / id                       | example message | description
2588 ------------------------------- | --------------- | -------------------------
2589 json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
2590 json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
2591 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2592 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2593 json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
2594 json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
2595 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) |
2596 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2597 json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
2598 
2599 @liveexample{The following code shows how an `out_of_range` exception can be
2600 caught.,out_of_range}
2601 
2602 @sa - @ref exception for the base class of the library exceptions
2603 @sa - @ref parse_error for exceptions indicating a parse error
2604 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2605 @sa - @ref type_error for exceptions indicating executing a member function with
2606                     a wrong type
2607 @sa - @ref other_error for exceptions indicating other library errors
2608 
2609 @since version 3.0.0
2610 */
2611 class out_of_range : public exception
2612 {
2613   public:
create(int id_,const std::string & what_arg)2614     static out_of_range create(int id_, const std::string& what_arg)
2615     {
2616         std::string w = exception::name("out_of_range", id_) + what_arg;
2617         return out_of_range(id_, w.c_str());
2618     }
2619 
2620   private:
2621     JSON_HEDLEY_NON_NULL(3)
out_of_range(int id_,const char * what_arg)2622     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2623 };
2624 
2625 /*!
2626 @brief exception indicating other library errors
2627 
2628 This exception is thrown in case of errors that cannot be classified with the
2629 other exception types.
2630 
2631 Exceptions have ids 5xx.
2632 
2633 name / id                      | example message | description
2634 ------------------------------ | --------------- | -------------------------
2635 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
2636 
2637 @sa - @ref exception for the base class of the library exceptions
2638 @sa - @ref parse_error for exceptions indicating a parse error
2639 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2640 @sa - @ref type_error for exceptions indicating executing a member function with
2641                     a wrong type
2642 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2643 
2644 @liveexample{The following code shows how an `other_error` exception can be
2645 caught.,other_error}
2646 
2647 @since version 3.0.0
2648 */
2649 class other_error : public exception
2650 {
2651   public:
create(int id_,const std::string & what_arg)2652     static other_error create(int id_, const std::string& what_arg)
2653     {
2654         std::string w = exception::name("other_error", id_) + what_arg;
2655         return other_error(id_, w.c_str());
2656     }
2657 
2658   private:
2659     JSON_HEDLEY_NON_NULL(3)
other_error(int id_,const char * what_arg)2660     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2661 };
2662 }  // namespace detail
2663 }  // namespace nlohmann
2664 
2665 // #include <nlohmann/detail/macro_scope.hpp>
2666 
2667 // #include <nlohmann/detail/meta/cpp_future.hpp>
2668 
2669 
2670 #include <cstddef> // size_t
2671 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2672 
2673 namespace nlohmann
2674 {
2675 namespace detail
2676 {
2677 // alias templates to reduce boilerplate
2678 template<bool B, typename T = void>
2679 using enable_if_t = typename std::enable_if<B, T>::type;
2680 
2681 template<typename T>
2682 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2683 
2684 // implementation of C++14 index_sequence and affiliates
2685 // source: https://stackoverflow.com/a/32223343
2686 template<std::size_t... Ints>
2687 struct index_sequence
2688 {
2689     using type = index_sequence;
2690     using value_type = std::size_t;
sizenlohmann::detail::index_sequence2691     static constexpr std::size_t size() noexcept
2692     {
2693         return sizeof...(Ints);
2694     }
2695 };
2696 
2697 template<class Sequence1, class Sequence2>
2698 struct merge_and_renumber;
2699 
2700 template<std::size_t... I1, std::size_t... I2>
2701 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2702         : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2703 
2704 template<std::size_t N>
2705 struct make_index_sequence
2706     : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2707       typename make_index_sequence < N - N / 2 >::type > {};
2708 
2709 template<> struct make_index_sequence<0> : index_sequence<> {};
2710 template<> struct make_index_sequence<1> : index_sequence<0> {};
2711 
2712 template<typename... Ts>
2713 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2714 
2715 // dispatch utility (taken from ranges-v3)
2716 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2717 template<> struct priority_tag<0> {};
2718 
2719 // taken from ranges-v3
2720 template<typename T>
2721 struct static_const
2722 {
2723     static constexpr T value{};
2724 };
2725 
2726 template<typename T>
2727 constexpr T static_const<T>::value;
2728 }  // namespace detail
2729 }  // namespace nlohmann
2730 
2731 // #include <nlohmann/detail/meta/type_traits.hpp>
2732 
2733 
2734 #include <limits> // numeric_limits
2735 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2736 #include <utility> // declval
2737 
2738 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2739 
2740 
2741 #include <iterator> // random_access_iterator_tag
2742 
2743 // #include <nlohmann/detail/meta/void_t.hpp>
2744 
2745 
2746 namespace nlohmann
2747 {
2748 namespace detail
2749 {
2750 template<typename ...Ts> struct make_void
2751 {
2752     using type = void;
2753 };
2754 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2755 } // namespace detail
2756 }  // namespace nlohmann
2757 
2758 // #include <nlohmann/detail/meta/cpp_future.hpp>
2759 
2760 
2761 namespace nlohmann
2762 {
2763 namespace detail
2764 {
2765 template<typename It, typename = void>
2766 struct iterator_types {};
2767 
2768 template<typename It>
2769 struct iterator_types <
2770     It,
2771     void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2772     typename It::reference, typename It::iterator_category >>
2773 {
2774     using difference_type = typename It::difference_type;
2775     using value_type = typename It::value_type;
2776     using pointer = typename It::pointer;
2777     using reference = typename It::reference;
2778     using iterator_category = typename It::iterator_category;
2779 };
2780 
2781 // This is required as some compilers implement std::iterator_traits in a way that
2782 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2783 template<typename T, typename = void>
2784 struct iterator_traits
2785 {
2786 };
2787 
2788 template<typename T>
2789 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2790             : iterator_types<T>
2791 {
2792 };
2793 
2794 template<typename T>
2795 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2796 {
2797     using iterator_category = std::random_access_iterator_tag;
2798     using value_type = T;
2799     using difference_type = ptrdiff_t;
2800     using pointer = T*;
2801     using reference = T&;
2802 };
2803 } // namespace detail
2804 } // namespace nlohmann
2805 
2806 // #include <nlohmann/detail/macro_scope.hpp>
2807 
2808 // #include <nlohmann/detail/meta/cpp_future.hpp>
2809 
2810 // #include <nlohmann/detail/meta/detected.hpp>
2811 
2812 
2813 #include <type_traits>
2814 
2815 // #include <nlohmann/detail/meta/void_t.hpp>
2816 
2817 
2818 // https://en.cppreference.com/w/cpp/experimental/is_detected
2819 namespace nlohmann
2820 {
2821 namespace detail
2822 {
2823 struct nonesuch
2824 {
2825     nonesuch() = delete;
2826     ~nonesuch() = delete;
2827     nonesuch(nonesuch const&) = delete;
2828     nonesuch(nonesuch const&&) = delete;
2829     void operator=(nonesuch const&) = delete;
2830     void operator=(nonesuch&&) = delete;
2831 };
2832 
2833 template<class Default,
2834          class AlwaysVoid,
2835          template<class...> class Op,
2836          class... Args>
2837 struct detector
2838 {
2839     using value_t = std::false_type;
2840     using type = Default;
2841 };
2842 
2843 template<class Default, template<class...> class Op, class... Args>
2844 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2845 {
2846     using value_t = std::true_type;
2847     using type = Op<Args...>;
2848 };
2849 
2850 template<template<class...> class Op, class... Args>
2851 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2852 
2853 template<template<class...> class Op, class... Args>
2854 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2855 
2856 template<class Default, template<class...> class Op, class... Args>
2857 using detected_or = detector<Default, void, Op, Args...>;
2858 
2859 template<class Default, template<class...> class Op, class... Args>
2860 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2861 
2862 template<class Expected, template<class...> class Op, class... Args>
2863 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2864 
2865 template<class To, template<class...> class Op, class... Args>
2866 using is_detected_convertible =
2867     std::is_convertible<detected_t<Op, Args...>, To>;
2868 }  // namespace detail
2869 }  // namespace nlohmann
2870 
2871 // #include <nlohmann/json_fwd.hpp>
2872 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2873 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2874 
2875 #include <cstdint> // int64_t, uint64_t
2876 #include <map> // map
2877 #include <memory> // allocator
2878 #include <string> // string
2879 #include <vector> // vector
2880 
2881 /*!
2882 @brief namespace for Niels Lohmann
2883 @see https://github.com/nlohmann
2884 @since version 1.0.0
2885 */
2886 namespace nlohmann
2887 {
2888 /*!
2889 @brief default JSONSerializer template argument
2890 
2891 This serializer ignores the template arguments and uses ADL
2892 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
2893 for serialization.
2894 */
2895 template<typename T = void, typename SFINAE = void>
2896 struct adl_serializer;
2897 
2898 template<template<typename U, typename V, typename... Args> class ObjectType =
2899          std::map,
2900          template<typename U, typename... Args> class ArrayType = std::vector,
2901          class StringType = std::string, class BooleanType = bool,
2902          class NumberIntegerType = std::int64_t,
2903          class NumberUnsignedType = std::uint64_t,
2904          class NumberFloatType = double,
2905          template<typename U> class AllocatorType = std::allocator,
2906          template<typename T, typename SFINAE = void> class JSONSerializer =
2907          adl_serializer,
2908          class BinaryType = std::vector<std::uint8_t>>
2909 class basic_json;
2910 
2911 /*!
2912 @brief JSON Pointer
2913 
2914 A JSON pointer defines a string syntax for identifying a specific value
2915 within a JSON document. It can be used with functions `at` and
2916 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
2917 
2918 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
2919 
2920 @since version 2.0.0
2921 */
2922 template<typename BasicJsonType>
2923 class json_pointer;
2924 
2925 /*!
2926 @brief default JSON class
2927 
2928 This type is the default specialization of the @ref basic_json class which
2929 uses the standard template types.
2930 
2931 @since version 1.0.0
2932 */
2933 using json = basic_json<>;
2934 
2935 template<class Key, class T, class IgnoredLess, class Allocator>
2936 struct ordered_map;
2937 
2938 /*!
2939 @brief ordered JSON class
2940 
2941 This type preserves the insertion order of object keys.
2942 
2943 @since version 3.9.0
2944 */
2945 using ordered_json = basic_json<nlohmann::ordered_map>;
2946 
2947 }  // namespace nlohmann
2948 
2949 #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
2950 
2951 
2952 namespace nlohmann
2953 {
2954 /*!
2955 @brief detail namespace with internal helper functions
2956 
2957 This namespace collects functions that should not be exposed,
2958 implementations of some @ref basic_json methods, and meta-programming helpers.
2959 
2960 @since version 2.1.0
2961 */
2962 namespace detail
2963 {
2964 /////////////
2965 // helpers //
2966 /////////////
2967 
2968 // Note to maintainers:
2969 //
2970 // Every trait in this file expects a non CV-qualified type.
2971 // The only exceptions are in the 'aliases for detected' section
2972 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
2973 //
2974 // In this case, T has to be properly CV-qualified to constraint the function arguments
2975 // (e.g. to_json(BasicJsonType&, const T&))
2976 
2977 template<typename> struct is_basic_json : std::false_type {};
2978 
2979 NLOHMANN_BASIC_JSON_TPL_DECLARATION
2980 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
2981 
2982 //////////////////////
2983 // json_ref helpers //
2984 //////////////////////
2985 
2986 template<typename>
2987 class json_ref;
2988 
2989 template<typename>
2990 struct is_json_ref : std::false_type {};
2991 
2992 template<typename T>
2993 struct is_json_ref<json_ref<T>> : std::true_type {};
2994 
2995 //////////////////////////
2996 // aliases for detected //
2997 //////////////////////////
2998 
2999 template<typename T>
3000 using mapped_type_t = typename T::mapped_type;
3001 
3002 template<typename T>
3003 using key_type_t = typename T::key_type;
3004 
3005 template<typename T>
3006 using value_type_t = typename T::value_type;
3007 
3008 template<typename T>
3009 using difference_type_t = typename T::difference_type;
3010 
3011 template<typename T>
3012 using pointer_t = typename T::pointer;
3013 
3014 template<typename T>
3015 using reference_t = typename T::reference;
3016 
3017 template<typename T>
3018 using iterator_category_t = typename T::iterator_category;
3019 
3020 template<typename T>
3021 using iterator_t = typename T::iterator;
3022 
3023 template<typename T, typename... Args>
3024 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3025 
3026 template<typename T, typename... Args>
3027 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3028 
3029 template<typename T, typename U>
3030 using get_template_function = decltype(std::declval<T>().template get<U>());
3031 
3032 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3033 template<typename BasicJsonType, typename T, typename = void>
3034 struct has_from_json : std::false_type {};
3035 
3036 // trait checking if j.get<T> is valid
3037 // use this trait instead of std::is_constructible or std::is_convertible,
3038 // both rely on, or make use of implicit conversions, and thus fail when T
3039 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3040 template <typename BasicJsonType, typename T>
3041 struct is_getable
3042 {
3043     static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3044 };
3045 
3046 template<typename BasicJsonType, typename T>
3047 struct has_from_json < BasicJsonType, T,
3048            enable_if_t < !is_basic_json<T>::value >>
3049 {
3050     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3051 
3052     static constexpr bool value =
3053         is_detected_exact<void, from_json_function, serializer,
3054         const BasicJsonType&, T&>::value;
3055 };
3056 
3057 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3058 // this overload is used for non-default-constructible user-defined-types
3059 template<typename BasicJsonType, typename T, typename = void>
3060 struct has_non_default_from_json : std::false_type {};
3061 
3062 template<typename BasicJsonType, typename T>
3063 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3064 {
3065     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3066 
3067     static constexpr bool value =
3068         is_detected_exact<T, from_json_function, serializer,
3069         const BasicJsonType&>::value;
3070 };
3071 
3072 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3073 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3074 template<typename BasicJsonType, typename T, typename = void>
3075 struct has_to_json : std::false_type {};
3076 
3077 template<typename BasicJsonType, typename T>
3078 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3079 {
3080     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3081 
3082     static constexpr bool value =
3083         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3084         T>::value;
3085 };
3086 
3087 
3088 ///////////////////
3089 // is_ functions //
3090 ///////////////////
3091 
3092 template<typename T, typename = void>
3093 struct is_iterator_traits : std::false_type {};
3094 
3095 template<typename T>
3096 struct is_iterator_traits<iterator_traits<T>>
3097 {
3098   private:
3099     using traits = iterator_traits<T>;
3100 
3101   public:
3102     static constexpr auto value =
3103         is_detected<value_type_t, traits>::value &&
3104         is_detected<difference_type_t, traits>::value &&
3105         is_detected<pointer_t, traits>::value &&
3106         is_detected<iterator_category_t, traits>::value &&
3107         is_detected<reference_t, traits>::value;
3108 };
3109 
3110 // source: https://stackoverflow.com/a/37193089/4116453
3111 
3112 template<typename T, typename = void>
3113 struct is_complete_type : std::false_type {};
3114 
3115 template<typename T>
3116 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3117 
3118 template<typename BasicJsonType, typename CompatibleObjectType,
3119          typename = void>
3120 struct is_compatible_object_type_impl : std::false_type {};
3121 
3122 template<typename BasicJsonType, typename CompatibleObjectType>
3123 struct is_compatible_object_type_impl <
3124     BasicJsonType, CompatibleObjectType,
3125     enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3126     is_detected<key_type_t, CompatibleObjectType>::value >>
3127 {
3128 
3129     using object_t = typename BasicJsonType::object_t;
3130 
3131     // macOS's is_constructible does not play well with nonesuch...
3132     static constexpr bool value =
3133         std::is_constructible<typename object_t::key_type,
3134         typename CompatibleObjectType::key_type>::value &&
3135         std::is_constructible<typename object_t::mapped_type,
3136         typename CompatibleObjectType::mapped_type>::value;
3137 };
3138 
3139 template<typename BasicJsonType, typename CompatibleObjectType>
3140 struct is_compatible_object_type
3141     : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3142 
3143 template<typename BasicJsonType, typename ConstructibleObjectType,
3144          typename = void>
3145 struct is_constructible_object_type_impl : std::false_type {};
3146 
3147 template<typename BasicJsonType, typename ConstructibleObjectType>
3148 struct is_constructible_object_type_impl <
3149     BasicJsonType, ConstructibleObjectType,
3150     enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3151     is_detected<key_type_t, ConstructibleObjectType>::value >>
3152 {
3153     using object_t = typename BasicJsonType::object_t;
3154 
3155     static constexpr bool value =
3156         (std::is_default_constructible<ConstructibleObjectType>::value &&
3157          (std::is_move_assignable<ConstructibleObjectType>::value ||
3158           std::is_copy_assignable<ConstructibleObjectType>::value) &&
3159          (std::is_constructible<typename ConstructibleObjectType::key_type,
3160           typename object_t::key_type>::value &&
3161           std::is_same <
3162           typename object_t::mapped_type,
3163           typename ConstructibleObjectType::mapped_type >::value)) ||
3164         (has_from_json<BasicJsonType,
3165          typename ConstructibleObjectType::mapped_type>::value ||
3166          has_non_default_from_json <
3167          BasicJsonType,
3168          typename ConstructibleObjectType::mapped_type >::value);
3169 };
3170 
3171 template<typename BasicJsonType, typename ConstructibleObjectType>
3172 struct is_constructible_object_type
3173     : is_constructible_object_type_impl<BasicJsonType,
3174       ConstructibleObjectType> {};
3175 
3176 template<typename BasicJsonType, typename CompatibleStringType,
3177          typename = void>
3178 struct is_compatible_string_type_impl : std::false_type {};
3179 
3180 template<typename BasicJsonType, typename CompatibleStringType>
3181 struct is_compatible_string_type_impl <
3182     BasicJsonType, CompatibleStringType,
3183     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3184     value_type_t, CompatibleStringType>::value >>
3185 {
3186     static constexpr auto value =
3187         std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3188 };
3189 
3190 template<typename BasicJsonType, typename ConstructibleStringType>
3191 struct is_compatible_string_type
3192     : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3193 
3194 template<typename BasicJsonType, typename ConstructibleStringType,
3195          typename = void>
3196 struct is_constructible_string_type_impl : std::false_type {};
3197 
3198 template<typename BasicJsonType, typename ConstructibleStringType>
3199 struct is_constructible_string_type_impl <
3200     BasicJsonType, ConstructibleStringType,
3201     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3202     value_type_t, ConstructibleStringType>::value >>
3203 {
3204     static constexpr auto value =
3205         std::is_constructible<ConstructibleStringType,
3206         typename BasicJsonType::string_t>::value;
3207 };
3208 
3209 template<typename BasicJsonType, typename ConstructibleStringType>
3210 struct is_constructible_string_type
3211     : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3212 
3213 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3214 struct is_compatible_array_type_impl : std::false_type {};
3215 
3216 template<typename BasicJsonType, typename CompatibleArrayType>
3217 struct is_compatible_array_type_impl <
3218     BasicJsonType, CompatibleArrayType,
3219     enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3220     is_detected<iterator_t, CompatibleArrayType>::value&&
3221 // This is needed because json_reverse_iterator has a ::iterator type...
3222 // Therefore it is detected as a CompatibleArrayType.
3223 // The real fix would be to have an Iterable concept.
3224     !is_iterator_traits <
3225     iterator_traits<CompatibleArrayType >>::value >>
3226 {
3227     static constexpr bool value =
3228         std::is_constructible<BasicJsonType,
3229         typename CompatibleArrayType::value_type>::value;
3230 };
3231 
3232 template<typename BasicJsonType, typename CompatibleArrayType>
3233 struct is_compatible_array_type
3234     : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3235 
3236 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3237 struct is_constructible_array_type_impl : std::false_type {};
3238 
3239 template<typename BasicJsonType, typename ConstructibleArrayType>
3240 struct is_constructible_array_type_impl <
3241     BasicJsonType, ConstructibleArrayType,
3242     enable_if_t<std::is_same<ConstructibleArrayType,
3243     typename BasicJsonType::value_type>::value >>
3244             : std::true_type {};
3245 
3246 template<typename BasicJsonType, typename ConstructibleArrayType>
3247 struct is_constructible_array_type_impl <
3248     BasicJsonType, ConstructibleArrayType,
3249     enable_if_t < !std::is_same<ConstructibleArrayType,
3250     typename BasicJsonType::value_type>::value&&
3251     std::is_default_constructible<ConstructibleArrayType>::value&&
3252 (std::is_move_assignable<ConstructibleArrayType>::value ||
3253  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3254 is_detected<value_type_t, ConstructibleArrayType>::value&&
3255 is_detected<iterator_t, ConstructibleArrayType>::value&&
3256 is_complete_type <
3257 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3258 {
3259     static constexpr bool value =
3260         // This is needed because json_reverse_iterator has a ::iterator type,
3261         // furthermore, std::back_insert_iterator (and other iterators) have a
3262         // base class `iterator`... Therefore it is detected as a
3263         // ConstructibleArrayType. The real fix would be to have an Iterable
3264         // concept.
3265         !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3266 
3267         (std::is_same<typename ConstructibleArrayType::value_type,
3268          typename BasicJsonType::array_t::value_type>::value ||
3269          has_from_json<BasicJsonType,
3270          typename ConstructibleArrayType::value_type>::value ||
3271          has_non_default_from_json <
3272          BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3273 };
3274 
3275 template<typename BasicJsonType, typename ConstructibleArrayType>
3276 struct is_constructible_array_type
3277     : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3278 
3279 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3280          typename = void>
3281 struct is_compatible_integer_type_impl : std::false_type {};
3282 
3283 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3284 struct is_compatible_integer_type_impl <
3285     RealIntegerType, CompatibleNumberIntegerType,
3286     enable_if_t < std::is_integral<RealIntegerType>::value&&
3287     std::is_integral<CompatibleNumberIntegerType>::value&&
3288     !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3289 {
3290     // is there an assert somewhere on overflows?
3291     using RealLimits = std::numeric_limits<RealIntegerType>;
3292     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3293 
3294     static constexpr auto value =
3295         std::is_constructible<RealIntegerType,
3296         CompatibleNumberIntegerType>::value &&
3297         CompatibleLimits::is_integer &&
3298         RealLimits::is_signed == CompatibleLimits::is_signed;
3299 };
3300 
3301 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3302 struct is_compatible_integer_type
3303     : is_compatible_integer_type_impl<RealIntegerType,
3304       CompatibleNumberIntegerType> {};
3305 
3306 template<typename BasicJsonType, typename CompatibleType, typename = void>
3307 struct is_compatible_type_impl: std::false_type {};
3308 
3309 template<typename BasicJsonType, typename CompatibleType>
3310 struct is_compatible_type_impl <
3311     BasicJsonType, CompatibleType,
3312     enable_if_t<is_complete_type<CompatibleType>::value >>
3313 {
3314     static constexpr bool value =
3315         has_to_json<BasicJsonType, CompatibleType>::value;
3316 };
3317 
3318 template<typename BasicJsonType, typename CompatibleType>
3319 struct is_compatible_type
3320     : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3321 
3322 // https://en.cppreference.com/w/cpp/types/conjunction
3323 template<class...> struct conjunction : std::true_type { };
3324 template<class B1> struct conjunction<B1> : B1 { };
3325 template<class B1, class... Bn>
3326 struct conjunction<B1, Bn...>
3327 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3328 
3329 template<typename T1, typename T2>
3330 struct is_constructible_tuple : std::false_type {};
3331 
3332 template<typename T1, typename... Args>
3333 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3334 }  // namespace detail
3335 }  // namespace nlohmann
3336 
3337 // #include <nlohmann/detail/value_t.hpp>
3338 
3339 
3340 #include <array> // array
3341 #include <cstddef> // size_t
3342 #include <cstdint> // uint8_t
3343 #include <string> // string
3344 
3345 namespace nlohmann
3346 {
3347 namespace detail
3348 {
3349 ///////////////////////////
3350 // JSON type enumeration //
3351 ///////////////////////////
3352 
3353 /*!
3354 @brief the JSON type enumeration
3355 
3356 This enumeration collects the different JSON types. It is internally used to
3357 distinguish the stored values, and the functions @ref basic_json::is_null(),
3358 @ref basic_json::is_object(), @ref basic_json::is_array(),
3359 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
3360 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
3361 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
3362 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
3363 @ref basic_json::is_structured() rely on it.
3364 
3365 @note There are three enumeration entries (number_integer, number_unsigned, and
3366 number_float), because the library distinguishes these three types for numbers:
3367 @ref basic_json::number_unsigned_t is used for unsigned integers,
3368 @ref basic_json::number_integer_t is used for signed integers, and
3369 @ref basic_json::number_float_t is used for floating-point numbers or to
3370 approximate integers which do not fit in the limits of their respective type.
3371 
3372 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
3373 value with the default value for a given type
3374 
3375 @since version 1.0.0
3376 */
3377 enum class value_t : std::uint8_t
3378 {
3379     null,             ///< null value
3380     object,           ///< object (unordered set of name/value pairs)
3381     array,            ///< array (ordered collection of values)
3382     string,           ///< string value
3383     boolean,          ///< boolean value
3384     number_integer,   ///< number value (signed integer)
3385     number_unsigned,  ///< number value (unsigned integer)
3386     number_float,     ///< number value (floating-point)
3387     binary,           ///< binary array (ordered collection of bytes)
3388     discarded         ///< discarded by the parser callback function
3389 };
3390 
3391 /*!
3392 @brief comparison operator for JSON types
3393 
3394 Returns an ordering that is similar to Python:
3395 - order: null < boolean < number < object < array < string < binary
3396 - furthermore, each type is not smaller than itself
3397 - discarded values are not comparable
3398 - binary is represented as a b"" string in python and directly comparable to a
3399   string; however, making a binary array directly comparable with a string would
3400   be surprising behavior in a JSON file.
3401 
3402 @since version 1.0.0
3403 */
operator <(const value_t lhs,const value_t rhs)3404 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3405 {
3406     static constexpr std::array<std::uint8_t, 9> order = {{
3407             0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3408             1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3409             6 /* binary */
3410         }
3411     };
3412 
3413     const auto l_index = static_cast<std::size_t>(lhs);
3414     const auto r_index = static_cast<std::size_t>(rhs);
3415     return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3416 }
3417 }  // namespace detail
3418 }  // namespace nlohmann
3419 
3420 
3421 namespace nlohmann
3422 {
3423 namespace detail
3424 {
3425 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)3426 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3427 {
3428     if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3429     {
3430         JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3431     }
3432     n = nullptr;
3433 }
3434 
3435 // overloads for basic_json template parameters
3436 template < typename BasicJsonType, typename ArithmeticType,
3437            enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3438                          !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3439                          int > = 0 >
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)3440 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3441 {
3442     switch (static_cast<value_t>(j))
3443     {
3444         case value_t::number_unsigned:
3445         {
3446             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3447             break;
3448         }
3449         case value_t::number_integer:
3450         {
3451             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3452             break;
3453         }
3454         case value_t::number_float:
3455         {
3456             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3457             break;
3458         }
3459 
3460         default:
3461             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3462     }
3463 }
3464 
3465 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)3466 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3467 {
3468     if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3469     {
3470         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3471     }
3472     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3473 }
3474 
3475 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)3476 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3477 {
3478     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3479     {
3480         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3481     }
3482     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3483 }
3484 
3485 template <
3486     typename BasicJsonType, typename ConstructibleStringType,
3487     enable_if_t <
3488         is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3489         !std::is_same<typename BasicJsonType::string_t,
3490                       ConstructibleStringType>::value,
3491         int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)3492 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3493 {
3494     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3495     {
3496         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3497     }
3498 
3499     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3500 }
3501 
3502 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)3503 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3504 {
3505     get_arithmetic_value(j, val);
3506 }
3507 
3508 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)3509 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3510 {
3511     get_arithmetic_value(j, val);
3512 }
3513 
3514 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)3515 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3516 {
3517     get_arithmetic_value(j, val);
3518 }
3519 
3520 template<typename BasicJsonType, typename EnumType,
3521          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)3522 void from_json(const BasicJsonType& j, EnumType& e)
3523 {
3524     typename std::underlying_type<EnumType>::type val;
3525     get_arithmetic_value(j, val);
3526     e = static_cast<EnumType>(val);
3527 }
3528 
3529 // forward_list doesn't have an insert method
3530 template<typename BasicJsonType, typename T, typename Allocator,
3531          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)3532 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3533 {
3534     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3535     {
3536         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3537     }
3538     l.clear();
3539     std::transform(j.rbegin(), j.rend(),
3540                    std::front_inserter(l), [](const BasicJsonType & i)
3541     {
3542         return i.template get<T>();
3543     });
3544 }
3545 
3546 // valarray doesn't have an insert method
3547 template<typename BasicJsonType, typename T,
3548          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)3549 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3550 {
3551     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3552     {
3553         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3554     }
3555     l.resize(j.size());
3556     std::transform(j.begin(), j.end(), std::begin(l),
3557                    [](const BasicJsonType & elem)
3558     {
3559         return elem.template get<T>();
3560     });
3561 }
3562 
3563 template<typename BasicJsonType, typename T, std::size_t N>
from_json(const BasicJsonType & j,T (& arr)[N])3564 auto from_json(const BasicJsonType& j, T (&arr)[N])
3565 -> decltype(j.template get<T>(), void())
3566 {
3567     for (std::size_t i = 0; i < N; ++i)
3568     {
3569         arr[i] = j.at(i).template get<T>();
3570     }
3571 }
3572 
3573 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)3574 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3575 {
3576     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3577 }
3578 
3579 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)3580 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3581                           priority_tag<2> /*unused*/)
3582 -> decltype(j.template get<T>(), void())
3583 {
3584     for (std::size_t i = 0; i < N; ++i)
3585     {
3586         arr[i] = j.at(i).template get<T>();
3587     }
3588 }
3589 
3590 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)3591 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3592 -> decltype(
3593     arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3594     j.template get<typename ConstructibleArrayType::value_type>(),
3595     void())
3596 {
3597     using std::end;
3598 
3599     ConstructibleArrayType ret;
3600     ret.reserve(j.size());
3601     std::transform(j.begin(), j.end(),
3602                    std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3603     {
3604         // get<BasicJsonType>() returns *this, this won't call a from_json
3605         // method when value_type is BasicJsonType
3606         return i.template get<typename ConstructibleArrayType::value_type>();
3607     });
3608     arr = std::move(ret);
3609 }
3610 
3611 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)3612 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3613                           priority_tag<0> /*unused*/)
3614 {
3615     using std::end;
3616 
3617     ConstructibleArrayType ret;
3618     std::transform(
3619         j.begin(), j.end(), std::inserter(ret, end(ret)),
3620         [](const BasicJsonType & i)
3621     {
3622         // get<BasicJsonType>() returns *this, this won't call a from_json
3623         // method when value_type is BasicJsonType
3624         return i.template get<typename ConstructibleArrayType::value_type>();
3625     });
3626     arr = std::move(ret);
3627 }
3628 
3629 template < typename BasicJsonType, typename ConstructibleArrayType,
3630            enable_if_t <
3631                is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3632                !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3633                !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3634                !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3635                !is_basic_json<ConstructibleArrayType>::value,
3636                int > = 0 >
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)3637 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3638 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3639 j.template get<typename ConstructibleArrayType::value_type>(),
3640 void())
3641 {
3642     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3643     {
3644         JSON_THROW(type_error::create(302, "type must be array, but is " +
3645                                       std::string(j.type_name())));
3646     }
3647 
3648     from_json_array_impl(j, arr, priority_tag<3> {});
3649 }
3650 
3651 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::binary_t & bin)3652 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3653 {
3654     if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3655     {
3656         JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3657     }
3658 
3659     bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3660 }
3661 
3662 template<typename BasicJsonType, typename ConstructibleObjectType,
3663          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)3664 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3665 {
3666     if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3667     {
3668         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3669     }
3670 
3671     ConstructibleObjectType ret;
3672     auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3673     using value_type = typename ConstructibleObjectType::value_type;
3674     std::transform(
3675         inner_object->begin(), inner_object->end(),
3676         std::inserter(ret, ret.begin()),
3677         [](typename BasicJsonType::object_t::value_type const & p)
3678     {
3679         return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3680     });
3681     obj = std::move(ret);
3682 }
3683 
3684 // overload for arithmetic types, not chosen for basic_json template arguments
3685 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3686 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3687 // an arithmetic type?
3688 template < typename BasicJsonType, typename ArithmeticType,
3689            enable_if_t <
3690                std::is_arithmetic<ArithmeticType>::value&&
3691                !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3692                !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3693                !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3694                !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3695                int > = 0 >
from_json(const BasicJsonType & j,ArithmeticType & val)3696 void from_json(const BasicJsonType& j, ArithmeticType& val)
3697 {
3698     switch (static_cast<value_t>(j))
3699     {
3700         case value_t::number_unsigned:
3701         {
3702             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3703             break;
3704         }
3705         case value_t::number_integer:
3706         {
3707             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3708             break;
3709         }
3710         case value_t::number_float:
3711         {
3712             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3713             break;
3714         }
3715         case value_t::boolean:
3716         {
3717             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3718             break;
3719         }
3720 
3721         default:
3722             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3723     }
3724 }
3725 
3726 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)3727 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3728 {
3729     p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3730 }
3731 
3732 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)3733 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3734 {
3735     t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3736 }
3737 
3738 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)3739 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3740 {
3741     from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3742 }
3743 
3744 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3745            typename = enable_if_t < !std::is_constructible <
3746                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)3747 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3748 {
3749     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3750     {
3751         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3752     }
3753     m.clear();
3754     for (const auto& p : j)
3755     {
3756         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3757         {
3758             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3759         }
3760         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3761     }
3762 }
3763 
3764 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3765            typename = enable_if_t < !std::is_constructible <
3766                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)3767 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3768 {
3769     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3770     {
3771         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3772     }
3773     m.clear();
3774     for (const auto& p : j)
3775     {
3776         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3777         {
3778             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3779         }
3780         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3781     }
3782 }
3783 
3784 struct from_json_fn
3785 {
3786     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn3787     auto operator()(const BasicJsonType& j, T& val) const
3788     noexcept(noexcept(from_json(j, val)))
3789     -> decltype(from_json(j, val), void())
3790     {
3791         return from_json(j, val);
3792     }
3793 };
3794 }  // namespace detail
3795 
3796 /// namespace to hold default `from_json` function
3797 /// to see why this is required:
3798 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
3799 namespace
3800 {
3801 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3802 } // namespace
3803 } // namespace nlohmann
3804 
3805 // #include <nlohmann/detail/conversions/to_json.hpp>
3806 
3807 
3808 #include <algorithm> // copy
3809 #include <iterator> // begin, end
3810 #include <string> // string
3811 #include <tuple> // tuple, get
3812 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3813 #include <utility> // move, forward, declval, pair
3814 #include <valarray> // valarray
3815 #include <vector> // vector
3816 
3817 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3818 
3819 
3820 #include <cstddef> // size_t
3821 #include <iterator> // input_iterator_tag
3822 #include <string> // string, to_string
3823 #include <tuple> // tuple_size, get, tuple_element
3824 
3825 // #include <nlohmann/detail/meta/type_traits.hpp>
3826 
3827 // #include <nlohmann/detail/value_t.hpp>
3828 
3829 
3830 namespace nlohmann
3831 {
3832 namespace detail
3833 {
3834 template<typename string_type>
int_to_string(string_type & target,std::size_t value)3835 void int_to_string( string_type& target, std::size_t value )
3836 {
3837     // For ADL
3838     using std::to_string;
3839     target = to_string(value);
3840 }
3841 template<typename IteratorType> class iteration_proxy_value
3842 {
3843   public:
3844     using difference_type = std::ptrdiff_t;
3845     using value_type = iteration_proxy_value;
3846     using pointer = value_type * ;
3847     using reference = value_type & ;
3848     using iterator_category = std::input_iterator_tag;
3849     using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3850 
3851   private:
3852     /// the iterator
3853     IteratorType anchor;
3854     /// an index for arrays (used to create key names)
3855     std::size_t array_index = 0;
3856     /// last stringified array index
3857     mutable std::size_t array_index_last = 0;
3858     /// a string representation of the array index
3859     mutable string_type array_index_str = "0";
3860     /// an empty string (to return a reference for primitive values)
3861     const string_type empty_str = "";
3862 
3863   public:
iteration_proxy_value(IteratorType it)3864     explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3865 
3866     /// dereference operator (needed for range-based for)
operator *()3867     iteration_proxy_value& operator*()
3868     {
3869         return *this;
3870     }
3871 
3872     /// increment operator (needed for range-based for)
operator ++()3873     iteration_proxy_value& operator++()
3874     {
3875         ++anchor;
3876         ++array_index;
3877 
3878         return *this;
3879     }
3880 
3881     /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const3882     bool operator==(const iteration_proxy_value& o) const
3883     {
3884         return anchor == o.anchor;
3885     }
3886 
3887     /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const3888     bool operator!=(const iteration_proxy_value& o) const
3889     {
3890         return anchor != o.anchor;
3891     }
3892 
3893     /// return key of the iterator
key() const3894     const string_type& key() const
3895     {
3896         JSON_ASSERT(anchor.m_object != nullptr);
3897 
3898         switch (anchor.m_object->type())
3899         {
3900             // use integer array index as key
3901             case value_t::array:
3902             {
3903                 if (array_index != array_index_last)
3904                 {
3905                     int_to_string( array_index_str, array_index );
3906                     array_index_last = array_index;
3907                 }
3908                 return array_index_str;
3909             }
3910 
3911             // use key from the object
3912             case value_t::object:
3913                 return anchor.key();
3914 
3915             // use an empty key for all primitive types
3916             default:
3917                 return empty_str;
3918         }
3919     }
3920 
3921     /// return value of the iterator
value() const3922     typename IteratorType::reference value() const
3923     {
3924         return anchor.value();
3925     }
3926 };
3927 
3928 /// proxy class for the items() function
3929 template<typename IteratorType> class iteration_proxy
3930 {
3931   private:
3932     /// the container to iterate
3933     typename IteratorType::reference container;
3934 
3935   public:
3936     /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)3937     explicit iteration_proxy(typename IteratorType::reference cont) noexcept
3938         : container(cont) {}
3939 
3940     /// return iterator begin (needed for range-based for)
begin()3941     iteration_proxy_value<IteratorType> begin() noexcept
3942     {
3943         return iteration_proxy_value<IteratorType>(container.begin());
3944     }
3945 
3946     /// return iterator end (needed for range-based for)
end()3947     iteration_proxy_value<IteratorType> end() noexcept
3948     {
3949         return iteration_proxy_value<IteratorType>(container.end());
3950     }
3951 };
3952 // Structured Bindings Support
3953 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3954 // And see https://github.com/nlohmann/json/pull/1391
3955 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)3956 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
3957 {
3958     return i.key();
3959 }
3960 // Structured Bindings Support
3961 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3962 // And see https://github.com/nlohmann/json/pull/1391
3963 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)3964 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
3965 {
3966     return i.value();
3967 }
3968 }  // namespace detail
3969 }  // namespace nlohmann
3970 
3971 // The Addition to the STD Namespace is required to add
3972 // Structured Bindings Support to the iteration_proxy_value class
3973 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
3974 // And see https://github.com/nlohmann/json/pull/1391
3975 namespace std
3976 {
3977 #if defined(__clang__)
3978     // Fix: https://github.com/nlohmann/json/issues/1401
3979     #pragma clang diagnostic push
3980     #pragma clang diagnostic ignored "-Wmismatched-tags"
3981 #endif
3982 template<typename IteratorType>
3983 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
3984             : public std::integral_constant<std::size_t, 2> {};
3985 
3986 template<std::size_t N, typename IteratorType>
3987 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
3988 {
3989   public:
3990     using type = decltype(
3991                      get<N>(std::declval <
3992                             ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
3993 };
3994 #if defined(__clang__)
3995     #pragma clang diagnostic pop
3996 #endif
3997 } // namespace std
3998 
3999 // #include <nlohmann/detail/meta/cpp_future.hpp>
4000 
4001 // #include <nlohmann/detail/meta/type_traits.hpp>
4002 
4003 // #include <nlohmann/detail/value_t.hpp>
4004 
4005 
4006 namespace nlohmann
4007 {
4008 namespace detail
4009 {
4010 //////////////////
4011 // constructors //
4012 //////////////////
4013 
4014 template<value_t> struct external_constructor;
4015 
4016 template<>
4017 struct external_constructor<value_t::boolean>
4018 {
4019     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4020     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4021     {
4022         j.m_type = value_t::boolean;
4023         j.m_value = b;
4024         j.assert_invariant();
4025     }
4026 };
4027 
4028 template<>
4029 struct external_constructor<value_t::string>
4030 {
4031     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4032     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4033     {
4034         j.m_type = value_t::string;
4035         j.m_value = s;
4036         j.assert_invariant();
4037     }
4038 
4039     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4040     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4041     {
4042         j.m_type = value_t::string;
4043         j.m_value = std::move(s);
4044         j.assert_invariant();
4045     }
4046 
4047     template < typename BasicJsonType, typename CompatibleStringType,
4048                enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4049                              int > = 0 >
constructnlohmann::detail::external_constructor4050     static void construct(BasicJsonType& j, const CompatibleStringType& str)
4051     {
4052         j.m_type = value_t::string;
4053         j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4054         j.assert_invariant();
4055     }
4056 };
4057 
4058 template<>
4059 struct external_constructor<value_t::binary>
4060 {
4061     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4062     static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4063     {
4064         j.m_type = value_t::binary;
4065         typename BasicJsonType::binary_t value{b};
4066         j.m_value = value;
4067         j.assert_invariant();
4068     }
4069 
4070     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4071     static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4072     {
4073         j.m_type = value_t::binary;
4074         typename BasicJsonType::binary_t value{std::move(b)};
4075         j.m_value = value;
4076         j.assert_invariant();
4077     }
4078 };
4079 
4080 template<>
4081 struct external_constructor<value_t::number_float>
4082 {
4083     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4084     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4085     {
4086         j.m_type = value_t::number_float;
4087         j.m_value = val;
4088         j.assert_invariant();
4089     }
4090 };
4091 
4092 template<>
4093 struct external_constructor<value_t::number_unsigned>
4094 {
4095     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4096     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4097     {
4098         j.m_type = value_t::number_unsigned;
4099         j.m_value = val;
4100         j.assert_invariant();
4101     }
4102 };
4103 
4104 template<>
4105 struct external_constructor<value_t::number_integer>
4106 {
4107     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4108     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4109     {
4110         j.m_type = value_t::number_integer;
4111         j.m_value = val;
4112         j.assert_invariant();
4113     }
4114 };
4115 
4116 template<>
4117 struct external_constructor<value_t::array>
4118 {
4119     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4120     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4121     {
4122         j.m_type = value_t::array;
4123         j.m_value = arr;
4124         j.assert_invariant();
4125     }
4126 
4127     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4128     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4129     {
4130         j.m_type = value_t::array;
4131         j.m_value = std::move(arr);
4132         j.assert_invariant();
4133     }
4134 
4135     template < typename BasicJsonType, typename CompatibleArrayType,
4136                enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4137                              int > = 0 >
constructnlohmann::detail::external_constructor4138     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4139     {
4140         using std::begin;
4141         using std::end;
4142         j.m_type = value_t::array;
4143         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4144         j.assert_invariant();
4145     }
4146 
4147     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4148     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4149     {
4150         j.m_type = value_t::array;
4151         j.m_value = value_t::array;
4152         j.m_value.array->reserve(arr.size());
4153         for (const bool x : arr)
4154         {
4155             j.m_value.array->push_back(x);
4156         }
4157         j.assert_invariant();
4158     }
4159 
4160     template<typename BasicJsonType, typename T,
4161              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor4162     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4163     {
4164         j.m_type = value_t::array;
4165         j.m_value = value_t::array;
4166         j.m_value.array->resize(arr.size());
4167         if (arr.size() > 0)
4168         {
4169             std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4170         }
4171         j.assert_invariant();
4172     }
4173 };
4174 
4175 template<>
4176 struct external_constructor<value_t::object>
4177 {
4178     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4179     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4180     {
4181         j.m_type = value_t::object;
4182         j.m_value = obj;
4183         j.assert_invariant();
4184     }
4185 
4186     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4187     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4188     {
4189         j.m_type = value_t::object;
4190         j.m_value = std::move(obj);
4191         j.assert_invariant();
4192     }
4193 
4194     template < typename BasicJsonType, typename CompatibleObjectType,
4195                enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
constructnlohmann::detail::external_constructor4196     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4197     {
4198         using std::begin;
4199         using std::end;
4200 
4201         j.m_type = value_t::object;
4202         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4203         j.assert_invariant();
4204     }
4205 };
4206 
4207 /////////////
4208 // to_json //
4209 /////////////
4210 
4211 template<typename BasicJsonType, typename T,
4212          enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)4213 void to_json(BasicJsonType& j, T b) noexcept
4214 {
4215     external_constructor<value_t::boolean>::construct(j, b);
4216 }
4217 
4218 template<typename BasicJsonType, typename CompatibleString,
4219          enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)4220 void to_json(BasicJsonType& j, const CompatibleString& s)
4221 {
4222     external_constructor<value_t::string>::construct(j, s);
4223 }
4224 
4225 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)4226 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4227 {
4228     external_constructor<value_t::string>::construct(j, std::move(s));
4229 }
4230 
4231 template<typename BasicJsonType, typename FloatType,
4232          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)4233 void to_json(BasicJsonType& j, FloatType val) noexcept
4234 {
4235     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4236 }
4237 
4238 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4239          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)4240 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4241 {
4242     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4243 }
4244 
4245 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4246          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)4247 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4248 {
4249     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4250 }
4251 
4252 template<typename BasicJsonType, typename EnumType,
4253          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)4254 void to_json(BasicJsonType& j, EnumType e) noexcept
4255 {
4256     using underlying_type = typename std::underlying_type<EnumType>::type;
4257     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4258 }
4259 
4260 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)4261 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4262 {
4263     external_constructor<value_t::array>::construct(j, e);
4264 }
4265 
4266 template < typename BasicJsonType, typename CompatibleArrayType,
4267            enable_if_t < is_compatible_array_type<BasicJsonType,
4268                          CompatibleArrayType>::value&&
4269                          !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4270                          !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4271                          !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4272                          !is_basic_json<CompatibleArrayType>::value,
4273                          int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)4274 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4275 {
4276     external_constructor<value_t::array>::construct(j, arr);
4277 }
4278 
4279 template<typename BasicJsonType>
to_json(BasicJsonType & j,const typename BasicJsonType::binary_t & bin)4280 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4281 {
4282     external_constructor<value_t::binary>::construct(j, bin);
4283 }
4284 
4285 template<typename BasicJsonType, typename T,
4286          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)4287 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4288 {
4289     external_constructor<value_t::array>::construct(j, std::move(arr));
4290 }
4291 
4292 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)4293 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4294 {
4295     external_constructor<value_t::array>::construct(j, std::move(arr));
4296 }
4297 
4298 template < typename BasicJsonType, typename CompatibleObjectType,
4299            enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)4300 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4301 {
4302     external_constructor<value_t::object>::construct(j, obj);
4303 }
4304 
4305 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)4306 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4307 {
4308     external_constructor<value_t::object>::construct(j, std::move(obj));
4309 }
4310 
4311 template <
4312     typename BasicJsonType, typename T, std::size_t N,
4313     enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4314                   const T(&)[N]>::value,
4315                   int > = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])4316 void to_json(BasicJsonType& j, const T(&arr)[N])
4317 {
4318     external_constructor<value_t::array>::construct(j, arr);
4319 }
4320 
4321 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
to_json(BasicJsonType & j,const std::pair<T1,T2> & p)4322 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4323 {
4324     j = { p.first, p.second };
4325 }
4326 
4327 // for https://github.com/nlohmann/json/pull/1134
4328 template<typename BasicJsonType, typename T,
4329          enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)4330 void to_json(BasicJsonType& j, const T& b)
4331 {
4332     j = { {b.key(), b.value()} };
4333 }
4334 
4335 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)4336 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4337 {
4338     j = { std::get<Idx>(t)... };
4339 }
4340 
4341 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
to_json(BasicJsonType & j,const T & t)4342 void to_json(BasicJsonType& j, const T& t)
4343 {
4344     to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4345 }
4346 
4347 struct to_json_fn
4348 {
4349     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn4350     auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4351     -> decltype(to_json(j, std::forward<T>(val)), void())
4352     {
4353         return to_json(j, std::forward<T>(val));
4354     }
4355 };
4356 }  // namespace detail
4357 
4358 /// namespace to hold default `to_json` function
4359 namespace
4360 {
4361 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4362 } // namespace
4363 } // namespace nlohmann
4364 
4365 
4366 namespace nlohmann
4367 {
4368 
4369 template<typename, typename>
4370 struct adl_serializer
4371 {
4372     /*!
4373     @brief convert a JSON value to any value type
4374 
4375     This function is usually called by the `get()` function of the
4376     @ref basic_json class (either explicit or via conversion operators).
4377 
4378     @param[in] j        JSON value to read from
4379     @param[in,out] val  value to write to
4380     */
4381     template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer4382     static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4383         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4384     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4385     {
4386         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4387     }
4388 
4389     /*!
4390     @brief convert any value type to a JSON value
4391 
4392     This function is usually called by the constructors of the @ref basic_json
4393     class.
4394 
4395     @param[in,out] j  JSON value to write to
4396     @param[in] val    value to read from
4397     */
4398     template<typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer4399     static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4400         noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4401     -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4402     {
4403         ::nlohmann::to_json(j, std::forward<ValueType>(val));
4404     }
4405 };
4406 
4407 }  // namespace nlohmann
4408 
4409 // #include <nlohmann/byte_container_with_subtype.hpp>
4410 
4411 
4412 #include <cstdint> // uint8_t
4413 #include <tuple> // tie
4414 #include <utility> // move
4415 
4416 namespace nlohmann
4417 {
4418 
4419 /*!
4420 @brief an internal type for a backed binary type
4421 
4422 This type extends the template parameter @a BinaryType provided to `basic_json`
4423 with a subtype used by BSON and MessagePack. This type exists so that the user
4424 does not have to specify a type themselves with a specific naming scheme in
4425 order to override the binary type.
4426 
4427 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
4428                    default)
4429 
4430 @since version 3.8.0
4431 */
4432 template<typename BinaryType>
4433 class byte_container_with_subtype : public BinaryType
4434 {
4435   public:
4436     /// the type of the underlying container
4437     using container_type = BinaryType;
4438 
byte_container_with_subtype()4439     byte_container_with_subtype() noexcept(noexcept(container_type()))
4440         : container_type()
4441     {}
4442 
byte_container_with_subtype(const container_type & b)4443     byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4444         : container_type(b)
4445     {}
4446 
byte_container_with_subtype(container_type && b)4447     byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4448         : container_type(std::move(b))
4449     {}
4450 
byte_container_with_subtype(const container_type & b,std::uint8_t subtype)4451     byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4452         : container_type(b)
4453         , m_subtype(subtype)
4454         , m_has_subtype(true)
4455     {}
4456 
byte_container_with_subtype(container_type && b,std::uint8_t subtype)4457     byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4458         : container_type(std::move(b))
4459         , m_subtype(subtype)
4460         , m_has_subtype(true)
4461     {}
4462 
operator ==(const byte_container_with_subtype & rhs) const4463     bool operator==(const byte_container_with_subtype& rhs) const
4464     {
4465         return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4466                std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4467     }
4468 
operator !=(const byte_container_with_subtype & rhs) const4469     bool operator!=(const byte_container_with_subtype& rhs) const
4470     {
4471         return !(rhs == *this);
4472     }
4473 
4474     /*!
4475     @brief sets the binary subtype
4476 
4477     Sets the binary subtype of the value, also flags a binary JSON value as
4478     having a subtype, which has implications for serialization.
4479 
4480     @complexity Constant.
4481 
4482     @exceptionsafety No-throw guarantee: this member function never throws
4483     exceptions.
4484 
4485     @sa @ref subtype() -- return the binary subtype
4486     @sa @ref clear_subtype() -- clears the binary subtype
4487     @sa @ref has_subtype() -- returns whether or not the binary value has a
4488     subtype
4489 
4490     @since version 3.8.0
4491     */
set_subtype(std::uint8_t subtype)4492     void set_subtype(std::uint8_t subtype) noexcept
4493     {
4494         m_subtype = subtype;
4495         m_has_subtype = true;
4496     }
4497 
4498     /*!
4499     @brief return the binary subtype
4500 
4501     Returns the numerical subtype of the value if it has a subtype. If it does
4502     not have a subtype, this function will return size_t(-1) as a sentinel
4503     value.
4504 
4505     @return the numerical subtype of the binary value
4506 
4507     @complexity Constant.
4508 
4509     @exceptionsafety No-throw guarantee: this member function never throws
4510     exceptions.
4511 
4512     @sa @ref set_subtype() -- sets the binary subtype
4513     @sa @ref clear_subtype() -- clears the binary subtype
4514     @sa @ref has_subtype() -- returns whether or not the binary value has a
4515     subtype
4516 
4517     @since version 3.8.0
4518     */
subtype() const4519     constexpr std::uint8_t subtype() const noexcept
4520     {
4521         return m_subtype;
4522     }
4523 
4524     /*!
4525     @brief return whether the value has a subtype
4526 
4527     @return whether the value has a subtype
4528 
4529     @complexity Constant.
4530 
4531     @exceptionsafety No-throw guarantee: this member function never throws
4532     exceptions.
4533 
4534     @sa @ref subtype() -- return the binary subtype
4535     @sa @ref set_subtype() -- sets the binary subtype
4536     @sa @ref clear_subtype() -- clears the binary subtype
4537 
4538     @since version 3.8.0
4539     */
has_subtype() const4540     constexpr bool has_subtype() const noexcept
4541     {
4542         return m_has_subtype;
4543     }
4544 
4545     /*!
4546     @brief clears the binary subtype
4547 
4548     Clears the binary subtype and flags the value as not having a subtype, which
4549     has implications for serialization; for instance MessagePack will prefer the
4550     bin family over the ext family.
4551 
4552     @complexity Constant.
4553 
4554     @exceptionsafety No-throw guarantee: this member function never throws
4555     exceptions.
4556 
4557     @sa @ref subtype() -- return the binary subtype
4558     @sa @ref set_subtype() -- sets the binary subtype
4559     @sa @ref has_subtype() -- returns whether or not the binary value has a
4560     subtype
4561 
4562     @since version 3.8.0
4563     */
clear_subtype()4564     void clear_subtype() noexcept
4565     {
4566         m_subtype = 0;
4567         m_has_subtype = false;
4568     }
4569 
4570   private:
4571     std::uint8_t m_subtype = 0;
4572     bool m_has_subtype = false;
4573 };
4574 
4575 }  // namespace nlohmann
4576 
4577 // #include <nlohmann/detail/conversions/from_json.hpp>
4578 
4579 // #include <nlohmann/detail/conversions/to_json.hpp>
4580 
4581 // #include <nlohmann/detail/exceptions.hpp>
4582 
4583 // #include <nlohmann/detail/hash.hpp>
4584 
4585 
4586 #include <cstddef> // size_t, uint8_t
4587 #include <functional> // hash
4588 
4589 namespace nlohmann
4590 {
4591 namespace detail
4592 {
4593 
4594 // boost::hash_combine
combine(std::size_t seed,std::size_t h)4595 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4596 {
4597     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4598     return seed;
4599 }
4600 
4601 /*!
4602 @brief hash a JSON value
4603 
4604 The hash function tries to rely on std::hash where possible. Furthermore, the
4605 type of the JSON value is taken into account to have different hash values for
4606 null, 0, 0U, and false, etc.
4607 
4608 @tparam BasicJsonType basic_json specialization
4609 @param j JSON value to hash
4610 @return hash value of j
4611 */
4612 template<typename BasicJsonType>
hash(const BasicJsonType & j)4613 std::size_t hash(const BasicJsonType& j)
4614 {
4615     using string_t = typename BasicJsonType::string_t;
4616     using number_integer_t = typename BasicJsonType::number_integer_t;
4617     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4618     using number_float_t = typename BasicJsonType::number_float_t;
4619 
4620     const auto type = static_cast<std::size_t>(j.type());
4621     switch (j.type())
4622     {
4623         case BasicJsonType::value_t::null:
4624         case BasicJsonType::value_t::discarded:
4625         {
4626             return combine(type, 0);
4627         }
4628 
4629         case BasicJsonType::value_t::object:
4630         {
4631             auto seed = combine(type, j.size());
4632             for (const auto& element : j.items())
4633             {
4634                 const auto h = std::hash<string_t> {}(element.key());
4635                 seed = combine(seed, h);
4636                 seed = combine(seed, hash(element.value()));
4637             }
4638             return seed;
4639         }
4640 
4641         case BasicJsonType::value_t::array:
4642         {
4643             auto seed = combine(type, j.size());
4644             for (const auto& element : j)
4645             {
4646                 seed = combine(seed, hash(element));
4647             }
4648             return seed;
4649         }
4650 
4651         case BasicJsonType::value_t::string:
4652         {
4653             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4654             return combine(type, h);
4655         }
4656 
4657         case BasicJsonType::value_t::boolean:
4658         {
4659             const auto h = std::hash<bool> {}(j.template get<bool>());
4660             return combine(type, h);
4661         }
4662 
4663         case BasicJsonType::value_t::number_integer:
4664         {
4665             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4666             return combine(type, h);
4667         }
4668 
4669         case nlohmann::detail::value_t::number_unsigned:
4670         {
4671             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4672             return combine(type, h);
4673         }
4674 
4675         case nlohmann::detail::value_t::number_float:
4676         {
4677             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4678             return combine(type, h);
4679         }
4680 
4681         case nlohmann::detail::value_t::binary:
4682         {
4683             auto seed = combine(type, j.get_binary().size());
4684             const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4685             seed = combine(seed, h);
4686             seed = combine(seed, j.get_binary().subtype());
4687             for (const auto byte : j.get_binary())
4688             {
4689                 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4690             }
4691             return seed;
4692         }
4693 
4694         default: // LCOV_EXCL_LINE
4695             JSON_ASSERT(false); // LCOV_EXCL_LINE
4696     }
4697 }
4698 
4699 }  // namespace detail
4700 }  // namespace nlohmann
4701 
4702 // #include <nlohmann/detail/input/binary_reader.hpp>
4703 
4704 
4705 #include <algorithm> // generate_n
4706 #include <array> // array
4707 #include <cmath> // ldexp
4708 #include <cstddef> // size_t
4709 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4710 #include <cstdio> // snprintf
4711 #include <cstring> // memcpy
4712 #include <iterator> // back_inserter
4713 #include <limits> // numeric_limits
4714 #include <string> // char_traits, string
4715 #include <utility> // make_pair, move
4716 
4717 // #include <nlohmann/detail/exceptions.hpp>
4718 
4719 // #include <nlohmann/detail/input/input_adapters.hpp>
4720 
4721 
4722 #include <array> // array
4723 #include <cstddef> // size_t
4724 #include <cstdio> //FILE *
4725 #include <cstring> // strlen
4726 #include <istream> // istream
4727 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4728 #include <memory> // shared_ptr, make_shared, addressof
4729 #include <numeric> // accumulate
4730 #include <string> // string, char_traits
4731 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4732 #include <utility> // pair, declval
4733 
4734 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4735 
4736 // #include <nlohmann/detail/macro_scope.hpp>
4737 
4738 
4739 namespace nlohmann
4740 {
4741 namespace detail
4742 {
4743 /// the supported input formats
4744 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4745 
4746 ////////////////////
4747 // input adapters //
4748 ////////////////////
4749 
4750 /*!
4751 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
4752  buffer. This adapter is a very low level adapter.
4753 */
4754 class file_input_adapter
4755 {
4756   public:
4757     using char_type = char;
4758 
4759     JSON_HEDLEY_NON_NULL(2)
file_input_adapter(std::FILE * f)4760     explicit file_input_adapter(std::FILE* f) noexcept
4761         : m_file(f)
4762     {}
4763 
4764     // make class move-only
4765     file_input_adapter(const file_input_adapter&) = delete;
4766     file_input_adapter(file_input_adapter&&) = default;
4767     file_input_adapter& operator=(const file_input_adapter&) = delete;
4768     file_input_adapter& operator=(file_input_adapter&&) = delete;
4769 
get_character()4770     std::char_traits<char>::int_type get_character() noexcept
4771     {
4772         return std::fgetc(m_file);
4773     }
4774 
4775   private:
4776     /// the file pointer to read from
4777     std::FILE* m_file;
4778 };
4779 
4780 
4781 /*!
4782 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
4783 beginning of input. Does not support changing the underlying std::streambuf
4784 in mid-input. Maintains underlying std::istream and std::streambuf to support
4785 subsequent use of standard std::istream operations to process any input
4786 characters following those used in parsing the JSON input.  Clears the
4787 std::istream flags; any input errors (e.g., EOF) will be detected by the first
4788 subsequent call for input from the std::istream.
4789 */
4790 class input_stream_adapter
4791 {
4792   public:
4793     using char_type = char;
4794 
~input_stream_adapter()4795     ~input_stream_adapter()
4796     {
4797         // clear stream flags; we use underlying streambuf I/O, do not
4798         // maintain ifstream flags, except eof
4799         if (is != nullptr)
4800         {
4801             is->clear(is->rdstate() & std::ios::eofbit);
4802         }
4803     }
4804 
input_stream_adapter(std::istream & i)4805     explicit input_stream_adapter(std::istream& i)
4806         : is(&i), sb(i.rdbuf())
4807     {}
4808 
4809     // delete because of pointer members
4810     input_stream_adapter(const input_stream_adapter&) = delete;
4811     input_stream_adapter& operator=(input_stream_adapter&) = delete;
4812     input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4813 
input_stream_adapter(input_stream_adapter && rhs)4814     input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4815     {
4816         rhs.is = nullptr;
4817         rhs.sb = nullptr;
4818     }
4819 
4820     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4821     // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4822     // end up as the same value, eg. 0xFFFFFFFF.
get_character()4823     std::char_traits<char>::int_type get_character()
4824     {
4825         auto res = sb->sbumpc();
4826         // set eof manually, as we don't use the istream interface.
4827         if (JSON_HEDLEY_UNLIKELY(res == EOF))
4828         {
4829             is->clear(is->rdstate() | std::ios::eofbit);
4830         }
4831         return res;
4832     }
4833 
4834   private:
4835     /// the associated input stream
4836     std::istream* is = nullptr;
4837     std::streambuf* sb = nullptr;
4838 };
4839 
4840 // General-purpose iterator-based adapter. It might not be as fast as
4841 // theoretically possible for some containers, but it is extremely versatile.
4842 template<typename IteratorType>
4843 class iterator_input_adapter
4844 {
4845   public:
4846     using char_type = typename std::iterator_traits<IteratorType>::value_type;
4847 
iterator_input_adapter(IteratorType first,IteratorType last)4848     iterator_input_adapter(IteratorType first, IteratorType last)
4849         : current(std::move(first)), end(std::move(last)) {}
4850 
get_character()4851     typename std::char_traits<char_type>::int_type get_character()
4852     {
4853         if (JSON_HEDLEY_LIKELY(current != end))
4854         {
4855             auto result = std::char_traits<char_type>::to_int_type(*current);
4856             std::advance(current, 1);
4857             return result;
4858         }
4859         else
4860         {
4861             return std::char_traits<char_type>::eof();
4862         }
4863     }
4864 
4865   private:
4866     IteratorType current;
4867     IteratorType end;
4868 
4869     template<typename BaseInputAdapter, size_t T>
4870     friend struct wide_string_input_helper;
4871 
empty() const4872     bool empty() const
4873     {
4874         return current == end;
4875     }
4876 
4877 };
4878 
4879 
4880 template<typename BaseInputAdapter, size_t T>
4881 struct wide_string_input_helper;
4882 
4883 template<typename BaseInputAdapter>
4884 struct wide_string_input_helper<BaseInputAdapter, 4>
4885 {
4886     // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper4887     static void fill_buffer(BaseInputAdapter& input,
4888                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4889                             size_t& utf8_bytes_index,
4890                             size_t& utf8_bytes_filled)
4891     {
4892         utf8_bytes_index = 0;
4893 
4894         if (JSON_HEDLEY_UNLIKELY(input.empty()))
4895         {
4896             utf8_bytes[0] = std::char_traits<char>::eof();
4897             utf8_bytes_filled = 1;
4898         }
4899         else
4900         {
4901             // get the current character
4902             const auto wc = input.get_character();
4903 
4904             // UTF-32 to UTF-8 encoding
4905             if (wc < 0x80)
4906             {
4907                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4908                 utf8_bytes_filled = 1;
4909             }
4910             else if (wc <= 0x7FF)
4911             {
4912                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4913                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4914                 utf8_bytes_filled = 2;
4915             }
4916             else if (wc <= 0xFFFF)
4917             {
4918                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4919                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4920                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4921                 utf8_bytes_filled = 3;
4922             }
4923             else if (wc <= 0x10FFFF)
4924             {
4925                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4926                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4927                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4928                 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4929                 utf8_bytes_filled = 4;
4930             }
4931             else
4932             {
4933                 // unknown character
4934                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4935                 utf8_bytes_filled = 1;
4936             }
4937         }
4938     }
4939 };
4940 
4941 template<typename BaseInputAdapter>
4942 struct wide_string_input_helper<BaseInputAdapter, 2>
4943 {
4944     // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper4945     static void fill_buffer(BaseInputAdapter& input,
4946                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4947                             size_t& utf8_bytes_index,
4948                             size_t& utf8_bytes_filled)
4949     {
4950         utf8_bytes_index = 0;
4951 
4952         if (JSON_HEDLEY_UNLIKELY(input.empty()))
4953         {
4954             utf8_bytes[0] = std::char_traits<char>::eof();
4955             utf8_bytes_filled = 1;
4956         }
4957         else
4958         {
4959             // get the current character
4960             const auto wc = input.get_character();
4961 
4962             // UTF-16 to UTF-8 encoding
4963             if (wc < 0x80)
4964             {
4965                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4966                 utf8_bytes_filled = 1;
4967             }
4968             else if (wc <= 0x7FF)
4969             {
4970                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
4971                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4972                 utf8_bytes_filled = 2;
4973             }
4974             else if (0xD800 > wc || wc >= 0xE000)
4975             {
4976                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
4977                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4978                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4979                 utf8_bytes_filled = 3;
4980             }
4981             else
4982             {
4983                 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
4984                 {
4985                     const auto wc2 = static_cast<unsigned int>(input.get_character());
4986                     const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
4987                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
4988                     utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
4989                     utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
4990                     utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
4991                     utf8_bytes_filled = 4;
4992                 }
4993                 else
4994                 {
4995                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4996                     utf8_bytes_filled = 1;
4997                 }
4998             }
4999         }
5000     }
5001 };
5002 
5003 // Wraps another input apdater to convert wide character types into individual bytes.
5004 template<typename BaseInputAdapter, typename WideCharType>
5005 class wide_string_input_adapter
5006 {
5007   public:
5008     using char_type = char;
5009 
wide_string_input_adapter(BaseInputAdapter base)5010     wide_string_input_adapter(BaseInputAdapter base)
5011         : base_adapter(base) {}
5012 
get_character()5013     typename std::char_traits<char>::int_type get_character() noexcept
5014     {
5015         // check if buffer needs to be filled
5016         if (utf8_bytes_index == utf8_bytes_filled)
5017         {
5018             fill_buffer<sizeof(WideCharType)>();
5019 
5020             JSON_ASSERT(utf8_bytes_filled > 0);
5021             JSON_ASSERT(utf8_bytes_index == 0);
5022         }
5023 
5024         // use buffer
5025         JSON_ASSERT(utf8_bytes_filled > 0);
5026         JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5027         return utf8_bytes[utf8_bytes_index++];
5028     }
5029 
5030   private:
5031     BaseInputAdapter base_adapter;
5032 
5033     template<size_t T>
fill_buffer()5034     void fill_buffer()
5035     {
5036         wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5037     }
5038 
5039     /// a buffer for UTF-8 bytes
5040     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5041 
5042     /// index to the utf8_codes array for the next valid byte
5043     std::size_t utf8_bytes_index = 0;
5044     /// number of valid bytes in the utf8_codes array
5045     std::size_t utf8_bytes_filled = 0;
5046 };
5047 
5048 
5049 template<typename IteratorType, typename Enable = void>
5050 struct iterator_input_adapter_factory
5051 {
5052     using iterator_type = IteratorType;
5053     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5054     using adapter_type = iterator_input_adapter<iterator_type>;
5055 
createnlohmann::detail::iterator_input_adapter_factory5056     static adapter_type create(IteratorType first, IteratorType last)
5057     {
5058         return adapter_type(std::move(first), std::move(last));
5059     }
5060 };
5061 
5062 template<typename T>
5063 struct is_iterator_of_multibyte
5064 {
5065     using value_type = typename std::iterator_traits<T>::value_type;
5066     enum
5067     {
5068         value = sizeof(value_type) > 1
5069     };
5070 };
5071 
5072 template<typename IteratorType>
5073 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5074 {
5075     using iterator_type = IteratorType;
5076     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5077     using base_adapter_type = iterator_input_adapter<iterator_type>;
5078     using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5079 
createnlohmann::detail::iterator_input_adapter_factory5080     static adapter_type create(IteratorType first, IteratorType last)
5081     {
5082         return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5083     }
5084 };
5085 
5086 // General purpose iterator-based input
5087 template<typename IteratorType>
input_adapter(IteratorType first,IteratorType last)5088 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5089 {
5090     using factory_type = iterator_input_adapter_factory<IteratorType>;
5091     return factory_type::create(first, last);
5092 }
5093 
5094 // Convenience shorthand from container to iterator
5095 template<typename ContainerType>
input_adapter(const ContainerType & container)5096 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5097 {
5098     // Enable ADL
5099     using std::begin;
5100     using std::end;
5101 
5102     return input_adapter(begin(container), end(container));
5103 }
5104 
5105 // Special cases with fast paths
input_adapter(std::FILE * file)5106 inline file_input_adapter input_adapter(std::FILE* file)
5107 {
5108     return file_input_adapter(file);
5109 }
5110 
input_adapter(std::istream & stream)5111 inline input_stream_adapter input_adapter(std::istream& stream)
5112 {
5113     return input_stream_adapter(stream);
5114 }
5115 
input_adapter(std::istream && stream)5116 inline input_stream_adapter input_adapter(std::istream&& stream)
5117 {
5118     return input_stream_adapter(stream);
5119 }
5120 
5121 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5122 
5123 // Null-delimited strings, and the like.
5124 template < typename CharT,
5125            typename std::enable_if <
5126                std::is_pointer<CharT>::value&&
5127                !std::is_array<CharT>::value&&
5128                std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5129                sizeof(typename std::remove_pointer<CharT>::type) == 1,
5130                int >::type = 0 >
input_adapter(CharT b)5131 contiguous_bytes_input_adapter input_adapter(CharT b)
5132 {
5133     auto length = std::strlen(reinterpret_cast<const char*>(b));
5134     const auto* ptr = reinterpret_cast<const char*>(b);
5135     return input_adapter(ptr, ptr + length);
5136 }
5137 
5138 template<typename T, std::size_t N>
input_adapter(T (& array)[N])5139 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5140 {
5141     return input_adapter(array, array + N);
5142 }
5143 
5144 // This class only handles inputs of input_buffer_adapter type.
5145 // It's required so that expressions like {ptr, len} can be implicitely casted
5146 // to the correct adapter.
5147 class span_input_adapter
5148 {
5149   public:
5150     template < typename CharT,
5151                typename std::enable_if <
5152                    std::is_pointer<CharT>::value&&
5153                    std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5154                    sizeof(typename std::remove_pointer<CharT>::type) == 1,
5155                    int >::type = 0 >
span_input_adapter(CharT b,std::size_t l)5156     span_input_adapter(CharT b, std::size_t l)
5157         : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5158 
5159     template<class IteratorType,
5160              typename std::enable_if<
5161                  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5162                  int>::type = 0>
span_input_adapter(IteratorType first,IteratorType last)5163     span_input_adapter(IteratorType first, IteratorType last)
5164         : ia(input_adapter(first, last)) {}
5165 
get()5166     contiguous_bytes_input_adapter&& get()
5167     {
5168         return std::move(ia);
5169     }
5170 
5171   private:
5172     contiguous_bytes_input_adapter ia;
5173 };
5174 }  // namespace detail
5175 }  // namespace nlohmann
5176 
5177 // #include <nlohmann/detail/input/json_sax.hpp>
5178 
5179 
5180 #include <cstddef>
5181 #include <string> // string
5182 #include <utility> // move
5183 #include <vector> // vector
5184 
5185 // #include <nlohmann/detail/exceptions.hpp>
5186 
5187 // #include <nlohmann/detail/macro_scope.hpp>
5188 
5189 
5190 namespace nlohmann
5191 {
5192 
5193 /*!
5194 @brief SAX interface
5195 
5196 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5197 Each function is called in different situations while the input is parsed. The
5198 boolean return value informs the parser whether to continue processing the
5199 input.
5200 */
5201 template<typename BasicJsonType>
5202 struct json_sax
5203 {
5204     using number_integer_t = typename BasicJsonType::number_integer_t;
5205     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5206     using number_float_t = typename BasicJsonType::number_float_t;
5207     using string_t = typename BasicJsonType::string_t;
5208     using binary_t = typename BasicJsonType::binary_t;
5209 
5210     /*!
5211     @brief a null value was read
5212     @return whether parsing should proceed
5213     */
5214     virtual bool null() = 0;
5215 
5216     /*!
5217     @brief a boolean value was read
5218     @param[in] val  boolean value
5219     @return whether parsing should proceed
5220     */
5221     virtual bool boolean(bool val) = 0;
5222 
5223     /*!
5224     @brief an integer number was read
5225     @param[in] val  integer value
5226     @return whether parsing should proceed
5227     */
5228     virtual bool number_integer(number_integer_t val) = 0;
5229 
5230     /*!
5231     @brief an unsigned integer number was read
5232     @param[in] val  unsigned integer value
5233     @return whether parsing should proceed
5234     */
5235     virtual bool number_unsigned(number_unsigned_t val) = 0;
5236 
5237     /*!
5238     @brief an floating-point number was read
5239     @param[in] val  floating-point value
5240     @param[in] s    raw token value
5241     @return whether parsing should proceed
5242     */
5243     virtual bool number_float(number_float_t val, const string_t& s) = 0;
5244 
5245     /*!
5246     @brief a string was read
5247     @param[in] val  string value
5248     @return whether parsing should proceed
5249     @note It is safe to move the passed string.
5250     */
5251     virtual bool string(string_t& val) = 0;
5252 
5253     /*!
5254     @brief a binary string was read
5255     @param[in] val  binary value
5256     @return whether parsing should proceed
5257     @note It is safe to move the passed binary.
5258     */
5259     virtual bool binary(binary_t& val) = 0;
5260 
5261     /*!
5262     @brief the beginning of an object was read
5263     @param[in] elements  number of object elements or -1 if unknown
5264     @return whether parsing should proceed
5265     @note binary formats may report the number of elements
5266     */
5267     virtual bool start_object(std::size_t elements) = 0;
5268 
5269     /*!
5270     @brief an object key was read
5271     @param[in] val  object key
5272     @return whether parsing should proceed
5273     @note It is safe to move the passed string.
5274     */
5275     virtual bool key(string_t& val) = 0;
5276 
5277     /*!
5278     @brief the end of an object was read
5279     @return whether parsing should proceed
5280     */
5281     virtual bool end_object() = 0;
5282 
5283     /*!
5284     @brief the beginning of an array was read
5285     @param[in] elements  number of array elements or -1 if unknown
5286     @return whether parsing should proceed
5287     @note binary formats may report the number of elements
5288     */
5289     virtual bool start_array(std::size_t elements) = 0;
5290 
5291     /*!
5292     @brief the end of an array was read
5293     @return whether parsing should proceed
5294     */
5295     virtual bool end_array() = 0;
5296 
5297     /*!
5298     @brief a parse error occurred
5299     @param[in] position    the position in the input where the error occurs
5300     @param[in] last_token  the last read token
5301     @param[in] ex          an exception object describing the error
5302     @return whether parsing should proceed (must return false)
5303     */
5304     virtual bool parse_error(std::size_t position,
5305                              const std::string& last_token,
5306                              const detail::exception& ex) = 0;
5307 
5308     virtual ~json_sax() = default;
5309 };
5310 
5311 
5312 namespace detail
5313 {
5314 /*!
5315 @brief SAX implementation to create a JSON value from SAX events
5316 
5317 This class implements the @ref json_sax interface and processes the SAX events
5318 to create a JSON value which makes it basically a DOM parser. The structure or
5319 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
5320 a pointer to the respective array or object for each recursion depth.
5321 
5322 After successful parsing, the value that is passed by reference to the
5323 constructor contains the parsed value.
5324 
5325 @tparam BasicJsonType  the JSON type
5326 */
5327 template<typename BasicJsonType>
5328 class json_sax_dom_parser
5329 {
5330   public:
5331     using number_integer_t = typename BasicJsonType::number_integer_t;
5332     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5333     using number_float_t = typename BasicJsonType::number_float_t;
5334     using string_t = typename BasicJsonType::string_t;
5335     using binary_t = typename BasicJsonType::binary_t;
5336 
5337     /*!
5338     @param[in, out] r  reference to a JSON value that is manipulated while
5339                        parsing
5340     @param[in] allow_exceptions_  whether parse errors yield exceptions
5341     */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)5342     explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5343         : root(r), allow_exceptions(allow_exceptions_)
5344     {}
5345 
5346     // make class move-only
5347     json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5348     json_sax_dom_parser(json_sax_dom_parser&&) = default;
5349     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5350     json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5351     ~json_sax_dom_parser() = default;
5352 
null()5353     bool null()
5354     {
5355         handle_value(nullptr);
5356         return true;
5357     }
5358 
boolean(bool val)5359     bool boolean(bool val)
5360     {
5361         handle_value(val);
5362         return true;
5363     }
5364 
number_integer(number_integer_t val)5365     bool number_integer(number_integer_t val)
5366     {
5367         handle_value(val);
5368         return true;
5369     }
5370 
number_unsigned(number_unsigned_t val)5371     bool number_unsigned(number_unsigned_t val)
5372     {
5373         handle_value(val);
5374         return true;
5375     }
5376 
number_float(number_float_t val,const string_t &)5377     bool number_float(number_float_t val, const string_t& /*unused*/)
5378     {
5379         handle_value(val);
5380         return true;
5381     }
5382 
string(string_t & val)5383     bool string(string_t& val)
5384     {
5385         handle_value(val);
5386         return true;
5387     }
5388 
binary(binary_t & val)5389     bool binary(binary_t& val)
5390     {
5391         handle_value(std::move(val));
5392         return true;
5393     }
5394 
start_object(std::size_t len)5395     bool start_object(std::size_t len)
5396     {
5397         ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5398 
5399         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5400         {
5401             JSON_THROW(out_of_range::create(408,
5402                                             "excessive object size: " + std::to_string(len)));
5403         }
5404 
5405         return true;
5406     }
5407 
key(string_t & val)5408     bool key(string_t& val)
5409     {
5410         // add null at given key and store the reference for later
5411         object_element = &(ref_stack.back()->m_value.object->operator[](val));
5412         return true;
5413     }
5414 
end_object()5415     bool end_object()
5416     {
5417         ref_stack.pop_back();
5418         return true;
5419     }
5420 
start_array(std::size_t len)5421     bool start_array(std::size_t len)
5422     {
5423         ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5424 
5425         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5426         {
5427             JSON_THROW(out_of_range::create(408,
5428                                             "excessive array size: " + std::to_string(len)));
5429         }
5430 
5431         return true;
5432     }
5433 
end_array()5434     bool end_array()
5435     {
5436         ref_stack.pop_back();
5437         return true;
5438     }
5439 
5440     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)5441     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5442                      const Exception& ex)
5443     {
5444         errored = true;
5445         static_cast<void>(ex);
5446         if (allow_exceptions)
5447         {
5448             JSON_THROW(ex);
5449         }
5450         return false;
5451     }
5452 
is_errored() const5453     constexpr bool is_errored() const
5454     {
5455         return errored;
5456     }
5457 
5458   private:
5459     /*!
5460     @invariant If the ref stack is empty, then the passed value will be the new
5461                root.
5462     @invariant If the ref stack contains a value, then it is an array or an
5463                object to which we can add elements
5464     */
5465     template<typename Value>
5466     JSON_HEDLEY_RETURNS_NON_NULL
handle_value(Value && v)5467     BasicJsonType* handle_value(Value&& v)
5468     {
5469         if (ref_stack.empty())
5470         {
5471             root = BasicJsonType(std::forward<Value>(v));
5472             return &root;
5473         }
5474 
5475         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5476 
5477         if (ref_stack.back()->is_array())
5478         {
5479             ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5480             return &(ref_stack.back()->m_value.array->back());
5481         }
5482 
5483         JSON_ASSERT(ref_stack.back()->is_object());
5484         JSON_ASSERT(object_element);
5485         *object_element = BasicJsonType(std::forward<Value>(v));
5486         return object_element;
5487     }
5488 
5489     /// the parsed JSON value
5490     BasicJsonType& root;
5491     /// stack to model hierarchy of values
5492     std::vector<BasicJsonType*> ref_stack {};
5493     /// helper to hold the reference for the next object element
5494     BasicJsonType* object_element = nullptr;
5495     /// whether a syntax error occurred
5496     bool errored = false;
5497     /// whether to throw exceptions in case of errors
5498     const bool allow_exceptions = true;
5499 };
5500 
5501 template<typename BasicJsonType>
5502 class json_sax_dom_callback_parser
5503 {
5504   public:
5505     using number_integer_t = typename BasicJsonType::number_integer_t;
5506     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5507     using number_float_t = typename BasicJsonType::number_float_t;
5508     using string_t = typename BasicJsonType::string_t;
5509     using binary_t = typename BasicJsonType::binary_t;
5510     using parser_callback_t = typename BasicJsonType::parser_callback_t;
5511     using parse_event_t = typename BasicJsonType::parse_event_t;
5512 
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)5513     json_sax_dom_callback_parser(BasicJsonType& r,
5514                                  const parser_callback_t cb,
5515                                  const bool allow_exceptions_ = true)
5516         : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5517     {
5518         keep_stack.push_back(true);
5519     }
5520 
5521     // make class move-only
5522     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5523     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5524     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5525     json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5526     ~json_sax_dom_callback_parser() = default;
5527 
null()5528     bool null()
5529     {
5530         handle_value(nullptr);
5531         return true;
5532     }
5533 
boolean(bool val)5534     bool boolean(bool val)
5535     {
5536         handle_value(val);
5537         return true;
5538     }
5539 
number_integer(number_integer_t val)5540     bool number_integer(number_integer_t val)
5541     {
5542         handle_value(val);
5543         return true;
5544     }
5545 
number_unsigned(number_unsigned_t val)5546     bool number_unsigned(number_unsigned_t val)
5547     {
5548         handle_value(val);
5549         return true;
5550     }
5551 
number_float(number_float_t val,const string_t &)5552     bool number_float(number_float_t val, const string_t& /*unused*/)
5553     {
5554         handle_value(val);
5555         return true;
5556     }
5557 
string(string_t & val)5558     bool string(string_t& val)
5559     {
5560         handle_value(val);
5561         return true;
5562     }
5563 
binary(binary_t & val)5564     bool binary(binary_t& val)
5565     {
5566         handle_value(std::move(val));
5567         return true;
5568     }
5569 
start_object(std::size_t len)5570     bool start_object(std::size_t len)
5571     {
5572         // check callback for object start
5573         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5574         keep_stack.push_back(keep);
5575 
5576         auto val = handle_value(BasicJsonType::value_t::object, true);
5577         ref_stack.push_back(val.second);
5578 
5579         // check object limit
5580         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5581         {
5582             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5583         }
5584 
5585         return true;
5586     }
5587 
key(string_t & val)5588     bool key(string_t& val)
5589     {
5590         BasicJsonType k = BasicJsonType(val);
5591 
5592         // check callback for key
5593         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5594         key_keep_stack.push_back(keep);
5595 
5596         // add discarded value at given key and store the reference for later
5597         if (keep && ref_stack.back())
5598         {
5599             object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5600         }
5601 
5602         return true;
5603     }
5604 
end_object()5605     bool end_object()
5606     {
5607         if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5608         {
5609             // discard object
5610             *ref_stack.back() = discarded;
5611         }
5612 
5613         JSON_ASSERT(!ref_stack.empty());
5614         JSON_ASSERT(!keep_stack.empty());
5615         ref_stack.pop_back();
5616         keep_stack.pop_back();
5617 
5618         if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5619         {
5620             // remove discarded value
5621             for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5622             {
5623                 if (it->is_discarded())
5624                 {
5625                     ref_stack.back()->erase(it);
5626                     break;
5627                 }
5628             }
5629         }
5630 
5631         return true;
5632     }
5633 
start_array(std::size_t len)5634     bool start_array(std::size_t len)
5635     {
5636         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5637         keep_stack.push_back(keep);
5638 
5639         auto val = handle_value(BasicJsonType::value_t::array, true);
5640         ref_stack.push_back(val.second);
5641 
5642         // check array limit
5643         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5644         {
5645             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5646         }
5647 
5648         return true;
5649     }
5650 
end_array()5651     bool end_array()
5652     {
5653         bool keep = true;
5654 
5655         if (ref_stack.back())
5656         {
5657             keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5658             if (!keep)
5659             {
5660                 // discard array
5661                 *ref_stack.back() = discarded;
5662             }
5663         }
5664 
5665         JSON_ASSERT(!ref_stack.empty());
5666         JSON_ASSERT(!keep_stack.empty());
5667         ref_stack.pop_back();
5668         keep_stack.pop_back();
5669 
5670         // remove discarded value
5671         if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5672         {
5673             ref_stack.back()->m_value.array->pop_back();
5674         }
5675 
5676         return true;
5677     }
5678 
5679     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)5680     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5681                      const Exception& ex)
5682     {
5683         errored = true;
5684         static_cast<void>(ex);
5685         if (allow_exceptions)
5686         {
5687             JSON_THROW(ex);
5688         }
5689         return false;
5690     }
5691 
is_errored() const5692     constexpr bool is_errored() const
5693     {
5694         return errored;
5695     }
5696 
5697   private:
5698     /*!
5699     @param[in] v  value to add to the JSON value we build during parsing
5700     @param[in] skip_callback  whether we should skip calling the callback
5701                function; this is required after start_array() and
5702                start_object() SAX events, because otherwise we would call the
5703                callback function with an empty array or object, respectively.
5704 
5705     @invariant If the ref stack is empty, then the passed value will be the new
5706                root.
5707     @invariant If the ref stack contains a value, then it is an array or an
5708                object to which we can add elements
5709 
5710     @return pair of boolean (whether value should be kept) and pointer (to the
5711             passed value in the ref_stack hierarchy; nullptr if not kept)
5712     */
5713     template<typename Value>
handle_value(Value && v,const bool skip_callback=false)5714     std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5715     {
5716         JSON_ASSERT(!keep_stack.empty());
5717 
5718         // do not handle this value if we know it would be added to a discarded
5719         // container
5720         if (!keep_stack.back())
5721         {
5722             return {false, nullptr};
5723         }
5724 
5725         // create value
5726         auto value = BasicJsonType(std::forward<Value>(v));
5727 
5728         // check callback
5729         const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5730 
5731         // do not handle this value if we just learnt it shall be discarded
5732         if (!keep)
5733         {
5734             return {false, nullptr};
5735         }
5736 
5737         if (ref_stack.empty())
5738         {
5739             root = std::move(value);
5740             return {true, &root};
5741         }
5742 
5743         // skip this value if we already decided to skip the parent
5744         // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5745         if (!ref_stack.back())
5746         {
5747             return {false, nullptr};
5748         }
5749 
5750         // we now only expect arrays and objects
5751         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5752 
5753         // array
5754         if (ref_stack.back()->is_array())
5755         {
5756             ref_stack.back()->m_value.array->push_back(std::move(value));
5757             return {true, &(ref_stack.back()->m_value.array->back())};
5758         }
5759 
5760         // object
5761         JSON_ASSERT(ref_stack.back()->is_object());
5762         // check if we should store an element for the current key
5763         JSON_ASSERT(!key_keep_stack.empty());
5764         const bool store_element = key_keep_stack.back();
5765         key_keep_stack.pop_back();
5766 
5767         if (!store_element)
5768         {
5769             return {false, nullptr};
5770         }
5771 
5772         JSON_ASSERT(object_element);
5773         *object_element = std::move(value);
5774         return {true, object_element};
5775     }
5776 
5777     /// the parsed JSON value
5778     BasicJsonType& root;
5779     /// stack to model hierarchy of values
5780     std::vector<BasicJsonType*> ref_stack {};
5781     /// stack to manage which values to keep
5782     std::vector<bool> keep_stack {};
5783     /// stack to manage which object keys to keep
5784     std::vector<bool> key_keep_stack {};
5785     /// helper to hold the reference for the next object element
5786     BasicJsonType* object_element = nullptr;
5787     /// whether a syntax error occurred
5788     bool errored = false;
5789     /// callback function
5790     const parser_callback_t callback = nullptr;
5791     /// whether to throw exceptions in case of errors
5792     const bool allow_exceptions = true;
5793     /// a discarded value for the callback
5794     BasicJsonType discarded = BasicJsonType::value_t::discarded;
5795 };
5796 
5797 template<typename BasicJsonType>
5798 class json_sax_acceptor
5799 {
5800   public:
5801     using number_integer_t = typename BasicJsonType::number_integer_t;
5802     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5803     using number_float_t = typename BasicJsonType::number_float_t;
5804     using string_t = typename BasicJsonType::string_t;
5805     using binary_t = typename BasicJsonType::binary_t;
5806 
null()5807     bool null()
5808     {
5809         return true;
5810     }
5811 
boolean(bool)5812     bool boolean(bool /*unused*/)
5813     {
5814         return true;
5815     }
5816 
number_integer(number_integer_t)5817     bool number_integer(number_integer_t /*unused*/)
5818     {
5819         return true;
5820     }
5821 
number_unsigned(number_unsigned_t)5822     bool number_unsigned(number_unsigned_t /*unused*/)
5823     {
5824         return true;
5825     }
5826 
number_float(number_float_t,const string_t &)5827     bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5828     {
5829         return true;
5830     }
5831 
string(string_t &)5832     bool string(string_t& /*unused*/)
5833     {
5834         return true;
5835     }
5836 
binary(binary_t &)5837     bool binary(binary_t& /*unused*/)
5838     {
5839         return true;
5840     }
5841 
start_object(std::size_t=std::size_t (-1))5842     bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5843     {
5844         return true;
5845     }
5846 
key(string_t &)5847     bool key(string_t& /*unused*/)
5848     {
5849         return true;
5850     }
5851 
end_object()5852     bool end_object()
5853     {
5854         return true;
5855     }
5856 
start_array(std::size_t=std::size_t (-1))5857     bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5858     {
5859         return true;
5860     }
5861 
end_array()5862     bool end_array()
5863     {
5864         return true;
5865     }
5866 
parse_error(std::size_t,const std::string &,const detail::exception &)5867     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5868     {
5869         return false;
5870     }
5871 };
5872 }  // namespace detail
5873 
5874 }  // namespace nlohmann
5875 
5876 // #include <nlohmann/detail/input/lexer.hpp>
5877 
5878 
5879 #include <array> // array
5880 #include <clocale> // localeconv
5881 #include <cstddef> // size_t
5882 #include <cstdio> // snprintf
5883 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5884 #include <initializer_list> // initializer_list
5885 #include <string> // char_traits, string
5886 #include <utility> // move
5887 #include <vector> // vector
5888 
5889 // #include <nlohmann/detail/input/input_adapters.hpp>
5890 
5891 // #include <nlohmann/detail/input/position_t.hpp>
5892 
5893 // #include <nlohmann/detail/macro_scope.hpp>
5894 
5895 
5896 namespace nlohmann
5897 {
5898 namespace detail
5899 {
5900 ///////////
5901 // lexer //
5902 ///////////
5903 
5904 template<typename BasicJsonType>
5905 class lexer_base
5906 {
5907   public:
5908     /// token types for the parser
5909     enum class token_type
5910     {
5911         uninitialized,    ///< indicating the scanner is uninitialized
5912         literal_true,     ///< the `true` literal
5913         literal_false,    ///< the `false` literal
5914         literal_null,     ///< the `null` literal
5915         value_string,     ///< a string -- use get_string() for actual value
5916         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
5917         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
5918         value_float,      ///< an floating point number -- use get_number_float() for actual value
5919         begin_array,      ///< the character for array begin `[`
5920         begin_object,     ///< the character for object begin `{`
5921         end_array,        ///< the character for array end `]`
5922         end_object,       ///< the character for object end `}`
5923         name_separator,   ///< the name separator `:`
5924         value_separator,  ///< the value separator `,`
5925         parse_error,      ///< indicating a parse error
5926         end_of_input,     ///< indicating the end of the input buffer
5927         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
5928     };
5929 
5930     /// return name of values of type token_type (only used for errors)
5931     JSON_HEDLEY_RETURNS_NON_NULL
5932     JSON_HEDLEY_CONST
token_type_name(const token_type t)5933     static const char* token_type_name(const token_type t) noexcept
5934     {
5935         switch (t)
5936         {
5937             case token_type::uninitialized:
5938                 return "<uninitialized>";
5939             case token_type::literal_true:
5940                 return "true literal";
5941             case token_type::literal_false:
5942                 return "false literal";
5943             case token_type::literal_null:
5944                 return "null literal";
5945             case token_type::value_string:
5946                 return "string literal";
5947             case token_type::value_unsigned:
5948             case token_type::value_integer:
5949             case token_type::value_float:
5950                 return "number literal";
5951             case token_type::begin_array:
5952                 return "'['";
5953             case token_type::begin_object:
5954                 return "'{'";
5955             case token_type::end_array:
5956                 return "']'";
5957             case token_type::end_object:
5958                 return "'}'";
5959             case token_type::name_separator:
5960                 return "':'";
5961             case token_type::value_separator:
5962                 return "','";
5963             case token_type::parse_error:
5964                 return "<parse error>";
5965             case token_type::end_of_input:
5966                 return "end of input";
5967             case token_type::literal_or_value:
5968                 return "'[', '{', or a literal";
5969             // LCOV_EXCL_START
5970             default: // catch non-enum values
5971                 return "unknown token";
5972                 // LCOV_EXCL_STOP
5973         }
5974     }
5975 };
5976 /*!
5977 @brief lexical analysis
5978 
5979 This class organizes the lexical analysis during JSON deserialization.
5980 */
5981 template<typename BasicJsonType, typename InputAdapterType>
5982 class lexer : public lexer_base<BasicJsonType>
5983 {
5984     using number_integer_t = typename BasicJsonType::number_integer_t;
5985     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5986     using number_float_t = typename BasicJsonType::number_float_t;
5987     using string_t = typename BasicJsonType::string_t;
5988     using char_type = typename InputAdapterType::char_type;
5989     using char_int_type = typename std::char_traits<char_type>::int_type;
5990 
5991   public:
5992     using token_type = typename lexer_base<BasicJsonType>::token_type;
5993 
lexer(InputAdapterType && adapter,bool ignore_comments_=false)5994     explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
5995         : ia(std::move(adapter))
5996         , ignore_comments(ignore_comments_)
5997         , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
5998     {}
5999 
6000     // delete because of pointer members
6001     lexer(const lexer&) = delete;
6002     lexer(lexer&&) = default;
6003     lexer& operator=(lexer&) = delete;
6004     lexer& operator=(lexer&&) = default;
6005     ~lexer() = default;
6006 
6007   private:
6008     /////////////////////
6009     // locales
6010     /////////////////////
6011 
6012     /// return the locale-dependent decimal point
6013     JSON_HEDLEY_PURE
get_decimal_point()6014     static char get_decimal_point() noexcept
6015     {
6016         const auto* loc = localeconv();
6017         JSON_ASSERT(loc != nullptr);
6018         return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6019     }
6020 
6021     /////////////////////
6022     // scan functions
6023     /////////////////////
6024 
6025     /*!
6026     @brief get codepoint from 4 hex characters following `\u`
6027 
6028     For input "\u c1 c2 c3 c4" the codepoint is:
6029       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6030     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6031 
6032     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6033     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6034     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6035     between the ASCII value of the character and the desired integer value.
6036 
6037     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6038             non-hex character)
6039     */
get_codepoint()6040     int get_codepoint()
6041     {
6042         // this function only makes sense after reading `\u`
6043         JSON_ASSERT(current == 'u');
6044         int codepoint = 0;
6045 
6046         const auto factors = { 12u, 8u, 4u, 0u };
6047         for (const auto factor : factors)
6048         {
6049             get();
6050 
6051             if (current >= '0' && current <= '9')
6052             {
6053                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6054             }
6055             else if (current >= 'A' && current <= 'F')
6056             {
6057                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6058             }
6059             else if (current >= 'a' && current <= 'f')
6060             {
6061                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6062             }
6063             else
6064             {
6065                 return -1;
6066             }
6067         }
6068 
6069         JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6070         return codepoint;
6071     }
6072 
6073     /*!
6074     @brief check if the next byte(s) are inside a given range
6075 
6076     Adds the current byte and, for each passed range, reads a new byte and
6077     checks if it is inside the range. If a violation was detected, set up an
6078     error message and return false. Otherwise, return true.
6079 
6080     @param[in] ranges  list of integers; interpreted as list of pairs of
6081                        inclusive lower and upper bound, respectively
6082 
6083     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6084          1, 2, or 3 pairs. This precondition is enforced by an assertion.
6085 
6086     @return true if and only if no range violation was detected
6087     */
next_byte_in_range(std::initializer_list<char_int_type> ranges)6088     bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6089     {
6090         JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6091         add(current);
6092 
6093         for (auto range = ranges.begin(); range != ranges.end(); ++range)
6094         {
6095             get();
6096             if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6097             {
6098                 add(current);
6099             }
6100             else
6101             {
6102                 error_message = "invalid string: ill-formed UTF-8 byte";
6103                 return false;
6104             }
6105         }
6106 
6107         return true;
6108     }
6109 
6110     /*!
6111     @brief scan a string literal
6112 
6113     This function scans a string according to Sect. 7 of RFC 7159. While
6114     scanning, bytes are escaped and copied into buffer token_buffer. Then the
6115     function returns successfully, token_buffer is *not* null-terminated (as it
6116     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6117     string.
6118 
6119     @return token_type::value_string if string could be successfully scanned,
6120             token_type::parse_error otherwise
6121 
6122     @note In case of errors, variable error_message contains a textual
6123           description.
6124     */
scan_string()6125     token_type scan_string()
6126     {
6127         // reset token_buffer (ignore opening quote)
6128         reset();
6129 
6130         // we entered the function by reading an open quote
6131         JSON_ASSERT(current == '\"');
6132 
6133         while (true)
6134         {
6135             // get next character
6136             switch (get())
6137             {
6138                 // end of file while parsing string
6139                 case std::char_traits<char_type>::eof():
6140                 {
6141                     error_message = "invalid string: missing closing quote";
6142                     return token_type::parse_error;
6143                 }
6144 
6145                 // closing quote
6146                 case '\"':
6147                 {
6148                     return token_type::value_string;
6149                 }
6150 
6151                 // escapes
6152                 case '\\':
6153                 {
6154                     switch (get())
6155                     {
6156                         // quotation mark
6157                         case '\"':
6158                             add('\"');
6159                             break;
6160                         // reverse solidus
6161                         case '\\':
6162                             add('\\');
6163                             break;
6164                         // solidus
6165                         case '/':
6166                             add('/');
6167                             break;
6168                         // backspace
6169                         case 'b':
6170                             add('\b');
6171                             break;
6172                         // form feed
6173                         case 'f':
6174                             add('\f');
6175                             break;
6176                         // line feed
6177                         case 'n':
6178                             add('\n');
6179                             break;
6180                         // carriage return
6181                         case 'r':
6182                             add('\r');
6183                             break;
6184                         // tab
6185                         case 't':
6186                             add('\t');
6187                             break;
6188 
6189                         // unicode escapes
6190                         case 'u':
6191                         {
6192                             const int codepoint1 = get_codepoint();
6193                             int codepoint = codepoint1; // start with codepoint1
6194 
6195                             if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6196                             {
6197                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6198                                 return token_type::parse_error;
6199                             }
6200 
6201                             // check if code point is a high surrogate
6202                             if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6203                             {
6204                                 // expect next \uxxxx entry
6205                                 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6206                                 {
6207                                     const int codepoint2 = get_codepoint();
6208 
6209                                     if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6210                                     {
6211                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6212                                         return token_type::parse_error;
6213                                     }
6214 
6215                                     // check if codepoint2 is a low surrogate
6216                                     if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6217                                     {
6218                                         // overwrite codepoint
6219                                         codepoint = static_cast<int>(
6220                                                         // high surrogate occupies the most significant 22 bits
6221                                                         (static_cast<unsigned int>(codepoint1) << 10u)
6222                                                         // low surrogate occupies the least significant 15 bits
6223                                                         + static_cast<unsigned int>(codepoint2)
6224                                                         // there is still the 0xD800, 0xDC00 and 0x10000 noise
6225                                                         // in the result so we have to subtract with:
6226                                                         // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6227                                                         - 0x35FDC00u);
6228                                     }
6229                                     else
6230                                     {
6231                                         error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6232                                         return token_type::parse_error;
6233                                     }
6234                                 }
6235                                 else
6236                                 {
6237                                     error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6238                                     return token_type::parse_error;
6239                                 }
6240                             }
6241                             else
6242                             {
6243                                 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6244                                 {
6245                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6246                                     return token_type::parse_error;
6247                                 }
6248                             }
6249 
6250                             // result of the above calculation yields a proper codepoint
6251                             JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6252 
6253                             // translate codepoint into bytes
6254                             if (codepoint < 0x80)
6255                             {
6256                                 // 1-byte characters: 0xxxxxxx (ASCII)
6257                                 add(static_cast<char_int_type>(codepoint));
6258                             }
6259                             else if (codepoint <= 0x7FF)
6260                             {
6261                                 // 2-byte characters: 110xxxxx 10xxxxxx
6262                                 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6263                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6264                             }
6265                             else if (codepoint <= 0xFFFF)
6266                             {
6267                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6268                                 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6269                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6270                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6271                             }
6272                             else
6273                             {
6274                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6275                                 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6276                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6277                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6278                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6279                             }
6280 
6281                             break;
6282                         }
6283 
6284                         // other characters after escape
6285                         default:
6286                             error_message = "invalid string: forbidden character after backslash";
6287                             return token_type::parse_error;
6288                     }
6289 
6290                     break;
6291                 }
6292 
6293                 // invalid control characters
6294                 case 0x00:
6295                 {
6296                     error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6297                     return token_type::parse_error;
6298                 }
6299 
6300                 case 0x01:
6301                 {
6302                     error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6303                     return token_type::parse_error;
6304                 }
6305 
6306                 case 0x02:
6307                 {
6308                     error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6309                     return token_type::parse_error;
6310                 }
6311 
6312                 case 0x03:
6313                 {
6314                     error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6315                     return token_type::parse_error;
6316                 }
6317 
6318                 case 0x04:
6319                 {
6320                     error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6321                     return token_type::parse_error;
6322                 }
6323 
6324                 case 0x05:
6325                 {
6326                     error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6327                     return token_type::parse_error;
6328                 }
6329 
6330                 case 0x06:
6331                 {
6332                     error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6333                     return token_type::parse_error;
6334                 }
6335 
6336                 case 0x07:
6337                 {
6338                     error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6339                     return token_type::parse_error;
6340                 }
6341 
6342                 case 0x08:
6343                 {
6344                     error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6345                     return token_type::parse_error;
6346                 }
6347 
6348                 case 0x09:
6349                 {
6350                     error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6351                     return token_type::parse_error;
6352                 }
6353 
6354                 case 0x0A:
6355                 {
6356                     error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6357                     return token_type::parse_error;
6358                 }
6359 
6360                 case 0x0B:
6361                 {
6362                     error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6363                     return token_type::parse_error;
6364                 }
6365 
6366                 case 0x0C:
6367                 {
6368                     error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6369                     return token_type::parse_error;
6370                 }
6371 
6372                 case 0x0D:
6373                 {
6374                     error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6375                     return token_type::parse_error;
6376                 }
6377 
6378                 case 0x0E:
6379                 {
6380                     error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6381                     return token_type::parse_error;
6382                 }
6383 
6384                 case 0x0F:
6385                 {
6386                     error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6387                     return token_type::parse_error;
6388                 }
6389 
6390                 case 0x10:
6391                 {
6392                     error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6393                     return token_type::parse_error;
6394                 }
6395 
6396                 case 0x11:
6397                 {
6398                     error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6399                     return token_type::parse_error;
6400                 }
6401 
6402                 case 0x12:
6403                 {
6404                     error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6405                     return token_type::parse_error;
6406                 }
6407 
6408                 case 0x13:
6409                 {
6410                     error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6411                     return token_type::parse_error;
6412                 }
6413 
6414                 case 0x14:
6415                 {
6416                     error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6417                     return token_type::parse_error;
6418                 }
6419 
6420                 case 0x15:
6421                 {
6422                     error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6423                     return token_type::parse_error;
6424                 }
6425 
6426                 case 0x16:
6427                 {
6428                     error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6429                     return token_type::parse_error;
6430                 }
6431 
6432                 case 0x17:
6433                 {
6434                     error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6435                     return token_type::parse_error;
6436                 }
6437 
6438                 case 0x18:
6439                 {
6440                     error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6441                     return token_type::parse_error;
6442                 }
6443 
6444                 case 0x19:
6445                 {
6446                     error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6447                     return token_type::parse_error;
6448                 }
6449 
6450                 case 0x1A:
6451                 {
6452                     error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6453                     return token_type::parse_error;
6454                 }
6455 
6456                 case 0x1B:
6457                 {
6458                     error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6459                     return token_type::parse_error;
6460                 }
6461 
6462                 case 0x1C:
6463                 {
6464                     error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6465                     return token_type::parse_error;
6466                 }
6467 
6468                 case 0x1D:
6469                 {
6470                     error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6471                     return token_type::parse_error;
6472                 }
6473 
6474                 case 0x1E:
6475                 {
6476                     error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6477                     return token_type::parse_error;
6478                 }
6479 
6480                 case 0x1F:
6481                 {
6482                     error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6483                     return token_type::parse_error;
6484                 }
6485 
6486                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6487                 case 0x20:
6488                 case 0x21:
6489                 case 0x23:
6490                 case 0x24:
6491                 case 0x25:
6492                 case 0x26:
6493                 case 0x27:
6494                 case 0x28:
6495                 case 0x29:
6496                 case 0x2A:
6497                 case 0x2B:
6498                 case 0x2C:
6499                 case 0x2D:
6500                 case 0x2E:
6501                 case 0x2F:
6502                 case 0x30:
6503                 case 0x31:
6504                 case 0x32:
6505                 case 0x33:
6506                 case 0x34:
6507                 case 0x35:
6508                 case 0x36:
6509                 case 0x37:
6510                 case 0x38:
6511                 case 0x39:
6512                 case 0x3A:
6513                 case 0x3B:
6514                 case 0x3C:
6515                 case 0x3D:
6516                 case 0x3E:
6517                 case 0x3F:
6518                 case 0x40:
6519                 case 0x41:
6520                 case 0x42:
6521                 case 0x43:
6522                 case 0x44:
6523                 case 0x45:
6524                 case 0x46:
6525                 case 0x47:
6526                 case 0x48:
6527                 case 0x49:
6528                 case 0x4A:
6529                 case 0x4B:
6530                 case 0x4C:
6531                 case 0x4D:
6532                 case 0x4E:
6533                 case 0x4F:
6534                 case 0x50:
6535                 case 0x51:
6536                 case 0x52:
6537                 case 0x53:
6538                 case 0x54:
6539                 case 0x55:
6540                 case 0x56:
6541                 case 0x57:
6542                 case 0x58:
6543                 case 0x59:
6544                 case 0x5A:
6545                 case 0x5B:
6546                 case 0x5D:
6547                 case 0x5E:
6548                 case 0x5F:
6549                 case 0x60:
6550                 case 0x61:
6551                 case 0x62:
6552                 case 0x63:
6553                 case 0x64:
6554                 case 0x65:
6555                 case 0x66:
6556                 case 0x67:
6557                 case 0x68:
6558                 case 0x69:
6559                 case 0x6A:
6560                 case 0x6B:
6561                 case 0x6C:
6562                 case 0x6D:
6563                 case 0x6E:
6564                 case 0x6F:
6565                 case 0x70:
6566                 case 0x71:
6567                 case 0x72:
6568                 case 0x73:
6569                 case 0x74:
6570                 case 0x75:
6571                 case 0x76:
6572                 case 0x77:
6573                 case 0x78:
6574                 case 0x79:
6575                 case 0x7A:
6576                 case 0x7B:
6577                 case 0x7C:
6578                 case 0x7D:
6579                 case 0x7E:
6580                 case 0x7F:
6581                 {
6582                     add(current);
6583                     break;
6584                 }
6585 
6586                 // U+0080..U+07FF: bytes C2..DF 80..BF
6587                 case 0xC2:
6588                 case 0xC3:
6589                 case 0xC4:
6590                 case 0xC5:
6591                 case 0xC6:
6592                 case 0xC7:
6593                 case 0xC8:
6594                 case 0xC9:
6595                 case 0xCA:
6596                 case 0xCB:
6597                 case 0xCC:
6598                 case 0xCD:
6599                 case 0xCE:
6600                 case 0xCF:
6601                 case 0xD0:
6602                 case 0xD1:
6603                 case 0xD2:
6604                 case 0xD3:
6605                 case 0xD4:
6606                 case 0xD5:
6607                 case 0xD6:
6608                 case 0xD7:
6609                 case 0xD8:
6610                 case 0xD9:
6611                 case 0xDA:
6612                 case 0xDB:
6613                 case 0xDC:
6614                 case 0xDD:
6615                 case 0xDE:
6616                 case 0xDF:
6617                 {
6618                     if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6619                     {
6620                         return token_type::parse_error;
6621                     }
6622                     break;
6623                 }
6624 
6625                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6626                 case 0xE0:
6627                 {
6628                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6629                     {
6630                         return token_type::parse_error;
6631                     }
6632                     break;
6633                 }
6634 
6635                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6636                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6637                 case 0xE1:
6638                 case 0xE2:
6639                 case 0xE3:
6640                 case 0xE4:
6641                 case 0xE5:
6642                 case 0xE6:
6643                 case 0xE7:
6644                 case 0xE8:
6645                 case 0xE9:
6646                 case 0xEA:
6647                 case 0xEB:
6648                 case 0xEC:
6649                 case 0xEE:
6650                 case 0xEF:
6651                 {
6652                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6653                     {
6654                         return token_type::parse_error;
6655                     }
6656                     break;
6657                 }
6658 
6659                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6660                 case 0xED:
6661                 {
6662                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6663                     {
6664                         return token_type::parse_error;
6665                     }
6666                     break;
6667                 }
6668 
6669                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6670                 case 0xF0:
6671                 {
6672                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6673                     {
6674                         return token_type::parse_error;
6675                     }
6676                     break;
6677                 }
6678 
6679                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6680                 case 0xF1:
6681                 case 0xF2:
6682                 case 0xF3:
6683                 {
6684                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6685                     {
6686                         return token_type::parse_error;
6687                     }
6688                     break;
6689                 }
6690 
6691                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6692                 case 0xF4:
6693                 {
6694                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6695                     {
6696                         return token_type::parse_error;
6697                     }
6698                     break;
6699                 }
6700 
6701                 // remaining bytes (80..C1 and F5..FF) are ill-formed
6702                 default:
6703                 {
6704                     error_message = "invalid string: ill-formed UTF-8 byte";
6705                     return token_type::parse_error;
6706                 }
6707             }
6708         }
6709     }
6710 
6711     /*!
6712      * @brief scan a comment
6713      * @return whether comment could be scanned successfully
6714      */
scan_comment()6715     bool scan_comment()
6716     {
6717         switch (get())
6718         {
6719             // single-line comments skip input until a newline or EOF is read
6720             case '/':
6721             {
6722                 while (true)
6723                 {
6724                     switch (get())
6725                     {
6726                         case '\n':
6727                         case '\r':
6728                         case std::char_traits<char_type>::eof():
6729                         case '\0':
6730                             return true;
6731 
6732                         default:
6733                             break;
6734                     }
6735                 }
6736             }
6737 
6738             // multi-line comments skip input until */ is read
6739             case '*':
6740             {
6741                 while (true)
6742                 {
6743                     switch (get())
6744                     {
6745                         case std::char_traits<char_type>::eof():
6746                         case '\0':
6747                         {
6748                             error_message = "invalid comment; missing closing '*/'";
6749                             return false;
6750                         }
6751 
6752                         case '*':
6753                         {
6754                             switch (get())
6755                             {
6756                                 case '/':
6757                                     return true;
6758 
6759                                 default:
6760                                 {
6761                                     unget();
6762                                     break;
6763                                 }
6764                             }
6765                         }
6766 
6767                         default:
6768                             break;
6769                     }
6770                 }
6771             }
6772 
6773             // unexpected character after reading '/'
6774             default:
6775             {
6776                 error_message = "invalid comment; expecting '/' or '*' after '/'";
6777                 return false;
6778             }
6779         }
6780     }
6781 
6782     JSON_HEDLEY_NON_NULL(2)
strtof(float & f,const char * str,char ** endptr)6783     static void strtof(float& f, const char* str, char** endptr) noexcept
6784     {
6785         f = std::strtof(str, endptr);
6786     }
6787 
6788     JSON_HEDLEY_NON_NULL(2)
strtof(double & f,const char * str,char ** endptr)6789     static void strtof(double& f, const char* str, char** endptr) noexcept
6790     {
6791         f = std::strtod(str, endptr);
6792     }
6793 
6794     JSON_HEDLEY_NON_NULL(2)
strtof(long double & f,const char * str,char ** endptr)6795     static void strtof(long double& f, const char* str, char** endptr) noexcept
6796     {
6797         f = std::strtold(str, endptr);
6798     }
6799 
6800     /*!
6801     @brief scan a number literal
6802 
6803     This function scans a string according to Sect. 6 of RFC 7159.
6804 
6805     The function is realized with a deterministic finite state machine derived
6806     from the grammar described in RFC 7159. Starting in state "init", the
6807     input is read and used to determined the next state. Only state "done"
6808     accepts the number. State "error" is a trap state to model errors. In the
6809     table below, "anything" means any character but the ones listed before.
6810 
6811     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
6812     ---------|----------|----------|----------|---------|---------|----------|-----------
6813     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
6814     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
6815     zero     | done     | done     | exponent | done    | done    | decimal1 | done
6816     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
6817     decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
6818     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
6819     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
6820     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
6821     any2     | any2     | any2     | done     | done    | done    | done     | done
6822 
6823     The state machine is realized with one label per state (prefixed with
6824     "scan_number_") and `goto` statements between them. The state machine
6825     contains cycles, but any cycle can be left when EOF is read. Therefore,
6826     the function is guaranteed to terminate.
6827 
6828     During scanning, the read bytes are stored in token_buffer. This string is
6829     then converted to a signed integer, an unsigned integer, or a
6830     floating-point number.
6831 
6832     @return token_type::value_unsigned, token_type::value_integer, or
6833             token_type::value_float if number could be successfully scanned,
6834             token_type::parse_error otherwise
6835 
6836     @note The scanner is independent of the current locale. Internally, the
6837           locale's decimal point is used instead of `.` to work with the
6838           locale-dependent converters.
6839     */
scan_number()6840     token_type scan_number()  // lgtm [cpp/use-of-goto]
6841     {
6842         // reset token_buffer to store the number's bytes
6843         reset();
6844 
6845         // the type of the parsed number; initially set to unsigned; will be
6846         // changed if minus sign, decimal point or exponent is read
6847         token_type number_type = token_type::value_unsigned;
6848 
6849         // state (init): we just found out we need to scan a number
6850         switch (current)
6851         {
6852             case '-':
6853             {
6854                 add(current);
6855                 goto scan_number_minus;
6856             }
6857 
6858             case '0':
6859             {
6860                 add(current);
6861                 goto scan_number_zero;
6862             }
6863 
6864             case '1':
6865             case '2':
6866             case '3':
6867             case '4':
6868             case '5':
6869             case '6':
6870             case '7':
6871             case '8':
6872             case '9':
6873             {
6874                 add(current);
6875                 goto scan_number_any1;
6876             }
6877 
6878             // all other characters are rejected outside scan_number()
6879             default:            // LCOV_EXCL_LINE
6880                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
6881         }
6882 
6883 scan_number_minus:
6884         // state: we just parsed a leading minus sign
6885         number_type = token_type::value_integer;
6886         switch (get())
6887         {
6888             case '0':
6889             {
6890                 add(current);
6891                 goto scan_number_zero;
6892             }
6893 
6894             case '1':
6895             case '2':
6896             case '3':
6897             case '4':
6898             case '5':
6899             case '6':
6900             case '7':
6901             case '8':
6902             case '9':
6903             {
6904                 add(current);
6905                 goto scan_number_any1;
6906             }
6907 
6908             default:
6909             {
6910                 error_message = "invalid number; expected digit after '-'";
6911                 return token_type::parse_error;
6912             }
6913         }
6914 
6915 scan_number_zero:
6916         // state: we just parse a zero (maybe with a leading minus sign)
6917         switch (get())
6918         {
6919             case '.':
6920             {
6921                 add(decimal_point_char);
6922                 goto scan_number_decimal1;
6923             }
6924 
6925             case 'e':
6926             case 'E':
6927             {
6928                 add(current);
6929                 goto scan_number_exponent;
6930             }
6931 
6932             default:
6933                 goto scan_number_done;
6934         }
6935 
6936 scan_number_any1:
6937         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6938         switch (get())
6939         {
6940             case '0':
6941             case '1':
6942             case '2':
6943             case '3':
6944             case '4':
6945             case '5':
6946             case '6':
6947             case '7':
6948             case '8':
6949             case '9':
6950             {
6951                 add(current);
6952                 goto scan_number_any1;
6953             }
6954 
6955             case '.':
6956             {
6957                 add(decimal_point_char);
6958                 goto scan_number_decimal1;
6959             }
6960 
6961             case 'e':
6962             case 'E':
6963             {
6964                 add(current);
6965                 goto scan_number_exponent;
6966             }
6967 
6968             default:
6969                 goto scan_number_done;
6970         }
6971 
6972 scan_number_decimal1:
6973         // state: we just parsed a decimal point
6974         number_type = token_type::value_float;
6975         switch (get())
6976         {
6977             case '0':
6978             case '1':
6979             case '2':
6980             case '3':
6981             case '4':
6982             case '5':
6983             case '6':
6984             case '7':
6985             case '8':
6986             case '9':
6987             {
6988                 add(current);
6989                 goto scan_number_decimal2;
6990             }
6991 
6992             default:
6993             {
6994                 error_message = "invalid number; expected digit after '.'";
6995                 return token_type::parse_error;
6996             }
6997         }
6998 
6999 scan_number_decimal2:
7000         // we just parsed at least one number after a decimal point
7001         switch (get())
7002         {
7003             case '0':
7004             case '1':
7005             case '2':
7006             case '3':
7007             case '4':
7008             case '5':
7009             case '6':
7010             case '7':
7011             case '8':
7012             case '9':
7013             {
7014                 add(current);
7015                 goto scan_number_decimal2;
7016             }
7017 
7018             case 'e':
7019             case 'E':
7020             {
7021                 add(current);
7022                 goto scan_number_exponent;
7023             }
7024 
7025             default:
7026                 goto scan_number_done;
7027         }
7028 
7029 scan_number_exponent:
7030         // we just parsed an exponent
7031         number_type = token_type::value_float;
7032         switch (get())
7033         {
7034             case '+':
7035             case '-':
7036             {
7037                 add(current);
7038                 goto scan_number_sign;
7039             }
7040 
7041             case '0':
7042             case '1':
7043             case '2':
7044             case '3':
7045             case '4':
7046             case '5':
7047             case '6':
7048             case '7':
7049             case '8':
7050             case '9':
7051             {
7052                 add(current);
7053                 goto scan_number_any2;
7054             }
7055 
7056             default:
7057             {
7058                 error_message =
7059                     "invalid number; expected '+', '-', or digit after exponent";
7060                 return token_type::parse_error;
7061             }
7062         }
7063 
7064 scan_number_sign:
7065         // we just parsed an exponent sign
7066         switch (get())
7067         {
7068             case '0':
7069             case '1':
7070             case '2':
7071             case '3':
7072             case '4':
7073             case '5':
7074             case '6':
7075             case '7':
7076             case '8':
7077             case '9':
7078             {
7079                 add(current);
7080                 goto scan_number_any2;
7081             }
7082 
7083             default:
7084             {
7085                 error_message = "invalid number; expected digit after exponent sign";
7086                 return token_type::parse_error;
7087             }
7088         }
7089 
7090 scan_number_any2:
7091         // we just parsed a number after the exponent or exponent sign
7092         switch (get())
7093         {
7094             case '0':
7095             case '1':
7096             case '2':
7097             case '3':
7098             case '4':
7099             case '5':
7100             case '6':
7101             case '7':
7102             case '8':
7103             case '9':
7104             {
7105                 add(current);
7106                 goto scan_number_any2;
7107             }
7108 
7109             default:
7110                 goto scan_number_done;
7111         }
7112 
7113 scan_number_done:
7114         // unget the character after the number (we only read it to know that
7115         // we are done scanning a number)
7116         unget();
7117 
7118         char* endptr = nullptr;
7119         errno = 0;
7120 
7121         // try to parse integers first and fall back to floats
7122         if (number_type == token_type::value_unsigned)
7123         {
7124             const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7125 
7126             // we checked the number format before
7127             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7128 
7129             if (errno == 0)
7130             {
7131                 value_unsigned = static_cast<number_unsigned_t>(x);
7132                 if (value_unsigned == x)
7133                 {
7134                     return token_type::value_unsigned;
7135                 }
7136             }
7137         }
7138         else if (number_type == token_type::value_integer)
7139         {
7140             const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7141 
7142             // we checked the number format before
7143             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7144 
7145             if (errno == 0)
7146             {
7147                 value_integer = static_cast<number_integer_t>(x);
7148                 if (value_integer == x)
7149                 {
7150                     return token_type::value_integer;
7151                 }
7152             }
7153         }
7154 
7155         // this code is reached if we parse a floating-point number or if an
7156         // integer conversion above failed
7157         strtof(value_float, token_buffer.data(), &endptr);
7158 
7159         // we checked the number format before
7160         JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7161 
7162         return token_type::value_float;
7163     }
7164 
7165     /*!
7166     @param[in] literal_text  the literal text to expect
7167     @param[in] length        the length of the passed literal text
7168     @param[in] return_type   the token type to return on success
7169     */
7170     JSON_HEDLEY_NON_NULL(2)
scan_literal(const char_type * literal_text,const std::size_t length,token_type return_type)7171     token_type scan_literal(const char_type* literal_text, const std::size_t length,
7172                             token_type return_type)
7173     {
7174         JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7175         for (std::size_t i = 1; i < length; ++i)
7176         {
7177             if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7178             {
7179                 error_message = "invalid literal";
7180                 return token_type::parse_error;
7181             }
7182         }
7183         return return_type;
7184     }
7185 
7186     /////////////////////
7187     // input management
7188     /////////////////////
7189 
7190     /// reset token_buffer; current character is beginning of token
reset()7191     void reset() noexcept
7192     {
7193         token_buffer.clear();
7194         token_string.clear();
7195         token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7196     }
7197 
7198     /*
7199     @brief get next character from the input
7200 
7201     This function provides the interface to the used input adapter. It does
7202     not throw in case the input reached EOF, but returns a
7203     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
7204     for use in error messages.
7205 
7206     @return character read from the input
7207     */
get()7208     char_int_type get()
7209     {
7210         ++position.chars_read_total;
7211         ++position.chars_read_current_line;
7212 
7213         if (next_unget)
7214         {
7215             // just reset the next_unget variable and work with current
7216             next_unget = false;
7217         }
7218         else
7219         {
7220             current = ia.get_character();
7221         }
7222 
7223         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7224         {
7225             token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7226         }
7227 
7228         if (current == '\n')
7229         {
7230             ++position.lines_read;
7231             position.chars_read_current_line = 0;
7232         }
7233 
7234         return current;
7235     }
7236 
7237     /*!
7238     @brief unget current character (read it again on next get)
7239 
7240     We implement unget by setting variable next_unget to true. The input is not
7241     changed - we just simulate ungetting by modifying chars_read_total,
7242     chars_read_current_line, and token_string. The next call to get() will
7243     behave as if the unget character is read again.
7244     */
unget()7245     void unget()
7246     {
7247         next_unget = true;
7248 
7249         --position.chars_read_total;
7250 
7251         // in case we "unget" a newline, we have to also decrement the lines_read
7252         if (position.chars_read_current_line == 0)
7253         {
7254             if (position.lines_read > 0)
7255             {
7256                 --position.lines_read;
7257             }
7258         }
7259         else
7260         {
7261             --position.chars_read_current_line;
7262         }
7263 
7264         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7265         {
7266             JSON_ASSERT(!token_string.empty());
7267             token_string.pop_back();
7268         }
7269     }
7270 
7271     /// add a character to token_buffer
add(char_int_type c)7272     void add(char_int_type c)
7273     {
7274         token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7275     }
7276 
7277   public:
7278     /////////////////////
7279     // value getters
7280     /////////////////////
7281 
7282     /// return integer value
get_number_integer() const7283     constexpr number_integer_t get_number_integer() const noexcept
7284     {
7285         return value_integer;
7286     }
7287 
7288     /// return unsigned integer value
get_number_unsigned() const7289     constexpr number_unsigned_t get_number_unsigned() const noexcept
7290     {
7291         return value_unsigned;
7292     }
7293 
7294     /// return floating-point value
get_number_float() const7295     constexpr number_float_t get_number_float() const noexcept
7296     {
7297         return value_float;
7298     }
7299 
7300     /// return current string value (implicitly resets the token; useful only once)
get_string()7301     string_t& get_string()
7302     {
7303         return token_buffer;
7304     }
7305 
7306     /////////////////////
7307     // diagnostics
7308     /////////////////////
7309 
7310     /// return position of last read token
get_position() const7311     constexpr position_t get_position() const noexcept
7312     {
7313         return position;
7314     }
7315 
7316     /// return the last read token (for errors only).  Will never contain EOF
7317     /// (an arbitrary value that is not a valid char value, often -1), because
7318     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
get_token_string() const7319     std::string get_token_string() const
7320     {
7321         // escape control characters
7322         std::string result;
7323         for (const auto c : token_string)
7324         {
7325             if (static_cast<unsigned char>(c) <= '\x1F')
7326             {
7327                 // escape control characters
7328                 std::array<char, 9> cs{{}};
7329                 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7330                 result += cs.data();
7331             }
7332             else
7333             {
7334                 // add character as is
7335                 result.push_back(static_cast<std::string::value_type>(c));
7336             }
7337         }
7338 
7339         return result;
7340     }
7341 
7342     /// return syntax error message
7343     JSON_HEDLEY_RETURNS_NON_NULL
get_error_message() const7344     constexpr const char* get_error_message() const noexcept
7345     {
7346         return error_message;
7347     }
7348 
7349     /////////////////////
7350     // actual scanner
7351     /////////////////////
7352 
7353     /*!
7354     @brief skip the UTF-8 byte order mark
7355     @return true iff there is no BOM or the correct BOM has been skipped
7356     */
skip_bom()7357     bool skip_bom()
7358     {
7359         if (get() == 0xEF)
7360         {
7361             // check if we completely parse the BOM
7362             return get() == 0xBB && get() == 0xBF;
7363         }
7364 
7365         // the first character is not the beginning of the BOM; unget it to
7366         // process is later
7367         unget();
7368         return true;
7369     }
7370 
skip_whitespace()7371     void skip_whitespace()
7372     {
7373         do
7374         {
7375             get();
7376         }
7377         while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7378     }
7379 
scan()7380     token_type scan()
7381     {
7382         // initially, skip the BOM
7383         if (position.chars_read_total == 0 && !skip_bom())
7384         {
7385             error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7386             return token_type::parse_error;
7387         }
7388 
7389         // read next character and ignore whitespace
7390         skip_whitespace();
7391 
7392         // ignore comments
7393         if (ignore_comments && current == '/')
7394         {
7395             if (!scan_comment())
7396             {
7397                 return token_type::parse_error;
7398             }
7399 
7400             // skip following whitespace
7401             skip_whitespace();
7402         }
7403 
7404         switch (current)
7405         {
7406             // structural characters
7407             case '[':
7408                 return token_type::begin_array;
7409             case ']':
7410                 return token_type::end_array;
7411             case '{':
7412                 return token_type::begin_object;
7413             case '}':
7414                 return token_type::end_object;
7415             case ':':
7416                 return token_type::name_separator;
7417             case ',':
7418                 return token_type::value_separator;
7419 
7420             // literals
7421             case 't':
7422             {
7423                 std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7424                 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7425             }
7426             case 'f':
7427             {
7428                 std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7429                 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7430             }
7431             case 'n':
7432             {
7433                 std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7434                 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7435             }
7436 
7437             // string
7438             case '\"':
7439                 return scan_string();
7440 
7441             // number
7442             case '-':
7443             case '0':
7444             case '1':
7445             case '2':
7446             case '3':
7447             case '4':
7448             case '5':
7449             case '6':
7450             case '7':
7451             case '8':
7452             case '9':
7453                 return scan_number();
7454 
7455             // end of input (the null byte is needed when parsing from
7456             // string literals)
7457             case '\0':
7458             case std::char_traits<char_type>::eof():
7459                 return token_type::end_of_input;
7460 
7461             // error
7462             default:
7463                 error_message = "invalid literal";
7464                 return token_type::parse_error;
7465         }
7466     }
7467 
7468   private:
7469     /// input adapter
7470     InputAdapterType ia;
7471 
7472     /// whether comments should be ignored (true) or signaled as errors (false)
7473     const bool ignore_comments = false;
7474 
7475     /// the current character
7476     char_int_type current = std::char_traits<char_type>::eof();
7477 
7478     /// whether the next get() call should just return current
7479     bool next_unget = false;
7480 
7481     /// the start position of the current token
7482     position_t position {};
7483 
7484     /// raw input token string (for error messages)
7485     std::vector<char_type> token_string {};
7486 
7487     /// buffer for variable-length tokens (numbers, strings)
7488     string_t token_buffer {};
7489 
7490     /// a description of occurred lexer errors
7491     const char* error_message = "";
7492 
7493     // number values
7494     number_integer_t value_integer = 0;
7495     number_unsigned_t value_unsigned = 0;
7496     number_float_t value_float = 0;
7497 
7498     /// the decimal point
7499     const char_int_type decimal_point_char = '.';
7500 };
7501 }  // namespace detail
7502 }  // namespace nlohmann
7503 
7504 // #include <nlohmann/detail/macro_scope.hpp>
7505 
7506 // #include <nlohmann/detail/meta/is_sax.hpp>
7507 
7508 
7509 #include <cstdint> // size_t
7510 #include <utility> // declval
7511 #include <string> // string
7512 
7513 // #include <nlohmann/detail/meta/detected.hpp>
7514 
7515 // #include <nlohmann/detail/meta/type_traits.hpp>
7516 
7517 
7518 namespace nlohmann
7519 {
7520 namespace detail
7521 {
7522 template<typename T>
7523 using null_function_t = decltype(std::declval<T&>().null());
7524 
7525 template<typename T>
7526 using boolean_function_t =
7527     decltype(std::declval<T&>().boolean(std::declval<bool>()));
7528 
7529 template<typename T, typename Integer>
7530 using number_integer_function_t =
7531     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7532 
7533 template<typename T, typename Unsigned>
7534 using number_unsigned_function_t =
7535     decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7536 
7537 template<typename T, typename Float, typename String>
7538 using number_float_function_t = decltype(std::declval<T&>().number_float(
7539                                     std::declval<Float>(), std::declval<const String&>()));
7540 
7541 template<typename T, typename String>
7542 using string_function_t =
7543     decltype(std::declval<T&>().string(std::declval<String&>()));
7544 
7545 template<typename T, typename Binary>
7546 using binary_function_t =
7547     decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7548 
7549 template<typename T>
7550 using start_object_function_t =
7551     decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7552 
7553 template<typename T, typename String>
7554 using key_function_t =
7555     decltype(std::declval<T&>().key(std::declval<String&>()));
7556 
7557 template<typename T>
7558 using end_object_function_t = decltype(std::declval<T&>().end_object());
7559 
7560 template<typename T>
7561 using start_array_function_t =
7562     decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7563 
7564 template<typename T>
7565 using end_array_function_t = decltype(std::declval<T&>().end_array());
7566 
7567 template<typename T, typename Exception>
7568 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7569         std::declval<std::size_t>(), std::declval<const std::string&>(),
7570         std::declval<const Exception&>()));
7571 
7572 template<typename SAX, typename BasicJsonType>
7573 struct is_sax
7574 {
7575   private:
7576     static_assert(is_basic_json<BasicJsonType>::value,
7577                   "BasicJsonType must be of type basic_json<...>");
7578 
7579     using number_integer_t = typename BasicJsonType::number_integer_t;
7580     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7581     using number_float_t = typename BasicJsonType::number_float_t;
7582     using string_t = typename BasicJsonType::string_t;
7583     using binary_t = typename BasicJsonType::binary_t;
7584     using exception_t = typename BasicJsonType::exception;
7585 
7586   public:
7587     static constexpr bool value =
7588         is_detected_exact<bool, null_function_t, SAX>::value &&
7589         is_detected_exact<bool, boolean_function_t, SAX>::value &&
7590         is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
7591         is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
7592         is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
7593         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
7594         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
7595         is_detected_exact<bool, start_object_function_t, SAX>::value &&
7596         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
7597         is_detected_exact<bool, end_object_function_t, SAX>::value &&
7598         is_detected_exact<bool, start_array_function_t, SAX>::value &&
7599         is_detected_exact<bool, end_array_function_t, SAX>::value &&
7600         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
7601 };
7602 
7603 template<typename SAX, typename BasicJsonType>
7604 struct is_sax_static_asserts
7605 {
7606   private:
7607     static_assert(is_basic_json<BasicJsonType>::value,
7608                   "BasicJsonType must be of type basic_json<...>");
7609 
7610     using number_integer_t = typename BasicJsonType::number_integer_t;
7611     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7612     using number_float_t = typename BasicJsonType::number_float_t;
7613     using string_t = typename BasicJsonType::string_t;
7614     using binary_t = typename BasicJsonType::binary_t;
7615     using exception_t = typename BasicJsonType::exception;
7616 
7617   public:
7618     static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
7619                   "Missing/invalid function: bool null()");
7620     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7621                   "Missing/invalid function: bool boolean(bool)");
7622     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7623                   "Missing/invalid function: bool boolean(bool)");
7624     static_assert(
7625         is_detected_exact<bool, number_integer_function_t, SAX,
7626         number_integer_t>::value,
7627         "Missing/invalid function: bool number_integer(number_integer_t)");
7628     static_assert(
7629         is_detected_exact<bool, number_unsigned_function_t, SAX,
7630         number_unsigned_t>::value,
7631         "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7632     static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7633                   number_float_t, string_t>::value,
7634                   "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7635     static_assert(
7636         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
7637         "Missing/invalid function: bool string(string_t&)");
7638     static_assert(
7639         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
7640         "Missing/invalid function: bool binary(binary_t&)");
7641     static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
7642                   "Missing/invalid function: bool start_object(std::size_t)");
7643     static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
7644                   "Missing/invalid function: bool key(string_t&)");
7645     static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
7646                   "Missing/invalid function: bool end_object()");
7647     static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
7648                   "Missing/invalid function: bool start_array(std::size_t)");
7649     static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
7650                   "Missing/invalid function: bool end_array()");
7651     static_assert(
7652         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
7653         "Missing/invalid function: bool parse_error(std::size_t, const "
7654         "std::string&, const exception&)");
7655 };
7656 }  // namespace detail
7657 }  // namespace nlohmann
7658 
7659 // #include <nlohmann/detail/value_t.hpp>
7660 
7661 
7662 namespace nlohmann
7663 {
7664 namespace detail
7665 {
7666 
7667 /// how to treat CBOR tags
7668 enum class cbor_tag_handler_t
7669 {
7670     error,  ///< throw a parse_error exception in case of a tag
7671     ignore   ///< ignore tags
7672 };
7673 
7674 /*!
7675 @brief determine system byte order
7676 
7677 @return true if and only if system's byte order is little endian
7678 
7679 @note from https://stackoverflow.com/a/1001328/266378
7680 */
little_endianess(int num=1)7681 static inline bool little_endianess(int num = 1) noexcept
7682 {
7683     return *reinterpret_cast<char*>(&num) == 1;
7684 }
7685 
7686 
7687 ///////////////////
7688 // binary reader //
7689 ///////////////////
7690 
7691 /*!
7692 @brief deserialization of CBOR, MessagePack, and UBJSON values
7693 */
7694 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7695 class binary_reader
7696 {
7697     using number_integer_t = typename BasicJsonType::number_integer_t;
7698     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7699     using number_float_t = typename BasicJsonType::number_float_t;
7700     using string_t = typename BasicJsonType::string_t;
7701     using binary_t = typename BasicJsonType::binary_t;
7702     using json_sax_t = SAX;
7703     using char_type = typename InputAdapterType::char_type;
7704     using char_int_type = typename std::char_traits<char_type>::int_type;
7705 
7706   public:
7707     /*!
7708     @brief create a binary reader
7709 
7710     @param[in] adapter  input adapter to read from
7711     */
binary_reader(InputAdapterType && adapter)7712     explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7713     {
7714         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7715     }
7716 
7717     // make class move-only
7718     binary_reader(const binary_reader&) = delete;
7719     binary_reader(binary_reader&&) = default;
7720     binary_reader& operator=(const binary_reader&) = delete;
7721     binary_reader& operator=(binary_reader&&) = default;
7722     ~binary_reader() = default;
7723 
7724     /*!
7725     @param[in] format  the binary format to parse
7726     @param[in] sax_    a SAX event processor
7727     @param[in] strict  whether to expect the input to be consumed completed
7728     @param[in] tag_handler  how to treat CBOR tags
7729 
7730     @return
7731     */
7732     JSON_HEDLEY_NON_NULL(3)
sax_parse(const input_format_t format,json_sax_t * sax_,const bool strict=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)7733     bool sax_parse(const input_format_t format,
7734                    json_sax_t* sax_,
7735                    const bool strict = true,
7736                    const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7737     {
7738         sax = sax_;
7739         bool result = false;
7740 
7741         switch (format)
7742         {
7743             case input_format_t::bson:
7744                 result = parse_bson_internal();
7745                 break;
7746 
7747             case input_format_t::cbor:
7748                 result = parse_cbor_internal(true, tag_handler);
7749                 break;
7750 
7751             case input_format_t::msgpack:
7752                 result = parse_msgpack_internal();
7753                 break;
7754 
7755             case input_format_t::ubjson:
7756                 result = parse_ubjson_internal();
7757                 break;
7758 
7759             default:            // LCOV_EXCL_LINE
7760                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
7761         }
7762 
7763         // strict mode: next byte must be EOF
7764         if (result && strict)
7765         {
7766             if (format == input_format_t::ubjson)
7767             {
7768                 get_ignore_noop();
7769             }
7770             else
7771             {
7772                 get();
7773             }
7774 
7775             if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7776             {
7777                 return sax->parse_error(chars_read, get_token_string(),
7778                                         parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7779             }
7780         }
7781 
7782         return result;
7783     }
7784 
7785   private:
7786     //////////
7787     // BSON //
7788     //////////
7789 
7790     /*!
7791     @brief Reads in a BSON-object and passes it to the SAX-parser.
7792     @return whether a valid BSON-value was passed to the SAX parser
7793     */
parse_bson_internal()7794     bool parse_bson_internal()
7795     {
7796         std::int32_t document_size{};
7797         get_number<std::int32_t, true>(input_format_t::bson, document_size);
7798 
7799         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7800         {
7801             return false;
7802         }
7803 
7804         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7805         {
7806             return false;
7807         }
7808 
7809         return sax->end_object();
7810     }
7811 
7812     /*!
7813     @brief Parses a C-style string from the BSON input.
7814     @param[in, out] result  A reference to the string variable where the read
7815                             string is to be stored.
7816     @return `true` if the \x00-byte indicating the end of the string was
7817              encountered before the EOF; false` indicates an unexpected EOF.
7818     */
get_bson_cstr(string_t & result)7819     bool get_bson_cstr(string_t& result)
7820     {
7821         auto out = std::back_inserter(result);
7822         while (true)
7823         {
7824             get();
7825             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
7826             {
7827                 return false;
7828             }
7829             if (current == 0x00)
7830             {
7831                 return true;
7832             }
7833             *out++ = static_cast<typename string_t::value_type>(current);
7834         }
7835     }
7836 
7837     /*!
7838     @brief Parses a zero-terminated string of length @a len from the BSON
7839            input.
7840     @param[in] len  The length (including the zero-byte at the end) of the
7841                     string to be read.
7842     @param[in, out] result  A reference to the string variable where the read
7843                             string is to be stored.
7844     @tparam NumberType The type of the length @a len
7845     @pre len >= 1
7846     @return `true` if the string was successfully parsed
7847     */
7848     template<typename NumberType>
get_bson_string(const NumberType len,string_t & result)7849     bool get_bson_string(const NumberType len, string_t& result)
7850     {
7851         if (JSON_HEDLEY_UNLIKELY(len < 1))
7852         {
7853             auto last_token = get_token_string();
7854             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
7855         }
7856 
7857         return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7858     }
7859 
7860     /*!
7861     @brief Parses a byte array input of length @a len from the BSON input.
7862     @param[in] len  The length of the byte array to be read.
7863     @param[in, out] result  A reference to the binary variable where the read
7864                             array is to be stored.
7865     @tparam NumberType The type of the length @a len
7866     @pre len >= 0
7867     @return `true` if the byte array was successfully parsed
7868     */
7869     template<typename NumberType>
get_bson_binary(const NumberType len,binary_t & result)7870     bool get_bson_binary(const NumberType len, binary_t& result)
7871     {
7872         if (JSON_HEDLEY_UNLIKELY(len < 0))
7873         {
7874             auto last_token = get_token_string();
7875             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
7876         }
7877 
7878         // All BSON binary values have a subtype
7879         std::uint8_t subtype{};
7880         get_number<std::uint8_t>(input_format_t::bson, subtype);
7881         result.set_subtype(subtype);
7882 
7883         return get_binary(input_format_t::bson, len, result);
7884     }
7885 
7886     /*!
7887     @brief Read a BSON document element of the given @a element_type.
7888     @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
7889     @param[in] element_type_parse_position The position in the input stream,
7890                where the `element_type` was read.
7891     @warning Not all BSON element types are supported yet. An unsupported
7892              @a element_type will give rise to a parse_error.114:
7893              Unsupported BSON record type 0x...
7894     @return whether a valid BSON-object/array was passed to the SAX parser
7895     */
parse_bson_element_internal(const char_int_type element_type,const std::size_t element_type_parse_position)7896     bool parse_bson_element_internal(const char_int_type element_type,
7897                                      const std::size_t element_type_parse_position)
7898     {
7899         switch (element_type)
7900         {
7901             case 0x01: // double
7902             {
7903                 double number{};
7904                 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7905             }
7906 
7907             case 0x02: // string
7908             {
7909                 std::int32_t len{};
7910                 string_t value;
7911                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7912             }
7913 
7914             case 0x03: // object
7915             {
7916                 return parse_bson_internal();
7917             }
7918 
7919             case 0x04: // array
7920             {
7921                 return parse_bson_array();
7922             }
7923 
7924             case 0x05: // binary
7925             {
7926                 std::int32_t len{};
7927                 binary_t value;
7928                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7929             }
7930 
7931             case 0x08: // boolean
7932             {
7933                 return sax->boolean(get() != 0);
7934             }
7935 
7936             case 0x0A: // null
7937             {
7938                 return sax->null();
7939             }
7940 
7941             case 0x10: // int32
7942             {
7943                 std::int32_t value{};
7944                 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7945             }
7946 
7947             case 0x12: // int64
7948             {
7949                 std::int64_t value{};
7950                 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
7951             }
7952 
7953             default: // anything else not supported (yet)
7954             {
7955                 std::array<char, 3> cr{{}};
7956                 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
7957                 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
7958             }
7959         }
7960     }
7961 
7962     /*!
7963     @brief Read a BSON element list (as specified in the BSON-spec)
7964 
7965     The same binary layout is used for objects and arrays, hence it must be
7966     indicated with the argument @a is_array which one is expected
7967     (true --> array, false --> object).
7968 
7969     @param[in] is_array Determines if the element list being read is to be
7970                         treated as an object (@a is_array == false), or as an
7971                         array (@a is_array == true).
7972     @return whether a valid BSON-object/array was passed to the SAX parser
7973     */
parse_bson_element_list(const bool is_array)7974     bool parse_bson_element_list(const bool is_array)
7975     {
7976         string_t key;
7977 
7978         while (auto element_type = get())
7979         {
7980             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
7981             {
7982                 return false;
7983             }
7984 
7985             const std::size_t element_type_parse_position = chars_read;
7986             if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
7987             {
7988                 return false;
7989             }
7990 
7991             if (!is_array && !sax->key(key))
7992             {
7993                 return false;
7994             }
7995 
7996             if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
7997             {
7998                 return false;
7999             }
8000 
8001             // get_bson_cstr only appends
8002             key.clear();
8003         }
8004 
8005         return true;
8006     }
8007 
8008     /*!
8009     @brief Reads an array from the BSON input and passes it to the SAX-parser.
8010     @return whether a valid BSON-array was passed to the SAX parser
8011     */
parse_bson_array()8012     bool parse_bson_array()
8013     {
8014         std::int32_t document_size{};
8015         get_number<std::int32_t, true>(input_format_t::bson, document_size);
8016 
8017         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8018         {
8019             return false;
8020         }
8021 
8022         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8023         {
8024             return false;
8025         }
8026 
8027         return sax->end_array();
8028     }
8029 
8030     //////////
8031     // CBOR //
8032     //////////
8033 
8034     /*!
8035     @param[in] get_char  whether a new character should be retrieved from the
8036                          input (true) or whether the last read character should
8037                          be considered instead (false)
8038     @param[in] tag_handler how CBOR tags should be treated
8039 
8040     @return whether a valid CBOR value was passed to the SAX parser
8041     */
parse_cbor_internal(const bool get_char,const cbor_tag_handler_t tag_handler)8042     bool parse_cbor_internal(const bool get_char,
8043                              const cbor_tag_handler_t tag_handler)
8044     {
8045         switch (get_char ? get() : current)
8046         {
8047             // EOF
8048             case std::char_traits<char_type>::eof():
8049                 return unexpect_eof(input_format_t::cbor, "value");
8050 
8051             // Integer 0x00..0x17 (0..23)
8052             case 0x00:
8053             case 0x01:
8054             case 0x02:
8055             case 0x03:
8056             case 0x04:
8057             case 0x05:
8058             case 0x06:
8059             case 0x07:
8060             case 0x08:
8061             case 0x09:
8062             case 0x0A:
8063             case 0x0B:
8064             case 0x0C:
8065             case 0x0D:
8066             case 0x0E:
8067             case 0x0F:
8068             case 0x10:
8069             case 0x11:
8070             case 0x12:
8071             case 0x13:
8072             case 0x14:
8073             case 0x15:
8074             case 0x16:
8075             case 0x17:
8076                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8077 
8078             case 0x18: // Unsigned integer (one-byte uint8_t follows)
8079             {
8080                 std::uint8_t number{};
8081                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8082             }
8083 
8084             case 0x19: // Unsigned integer (two-byte uint16_t follows)
8085             {
8086                 std::uint16_t number{};
8087                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8088             }
8089 
8090             case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8091             {
8092                 std::uint32_t number{};
8093                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8094             }
8095 
8096             case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8097             {
8098                 std::uint64_t number{};
8099                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8100             }
8101 
8102             // Negative integer -1-0x00..-1-0x17 (-1..-24)
8103             case 0x20:
8104             case 0x21:
8105             case 0x22:
8106             case 0x23:
8107             case 0x24:
8108             case 0x25:
8109             case 0x26:
8110             case 0x27:
8111             case 0x28:
8112             case 0x29:
8113             case 0x2A:
8114             case 0x2B:
8115             case 0x2C:
8116             case 0x2D:
8117             case 0x2E:
8118             case 0x2F:
8119             case 0x30:
8120             case 0x31:
8121             case 0x32:
8122             case 0x33:
8123             case 0x34:
8124             case 0x35:
8125             case 0x36:
8126             case 0x37:
8127                 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8128 
8129             case 0x38: // Negative integer (one-byte uint8_t follows)
8130             {
8131                 std::uint8_t number{};
8132                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8133             }
8134 
8135             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8136             {
8137                 std::uint16_t number{};
8138                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8139             }
8140 
8141             case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8142             {
8143                 std::uint32_t number{};
8144                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8145             }
8146 
8147             case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8148             {
8149                 std::uint64_t number{};
8150                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8151                         - static_cast<number_integer_t>(number));
8152             }
8153 
8154             // Binary data (0x00..0x17 bytes follow)
8155             case 0x40:
8156             case 0x41:
8157             case 0x42:
8158             case 0x43:
8159             case 0x44:
8160             case 0x45:
8161             case 0x46:
8162             case 0x47:
8163             case 0x48:
8164             case 0x49:
8165             case 0x4A:
8166             case 0x4B:
8167             case 0x4C:
8168             case 0x4D:
8169             case 0x4E:
8170             case 0x4F:
8171             case 0x50:
8172             case 0x51:
8173             case 0x52:
8174             case 0x53:
8175             case 0x54:
8176             case 0x55:
8177             case 0x56:
8178             case 0x57:
8179             case 0x58: // Binary data (one-byte uint8_t for n follows)
8180             case 0x59: // Binary data (two-byte uint16_t for n follow)
8181             case 0x5A: // Binary data (four-byte uint32_t for n follow)
8182             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8183             case 0x5F: // Binary data (indefinite length)
8184             {
8185                 binary_t b;
8186                 return get_cbor_binary(b) && sax->binary(b);
8187             }
8188 
8189             // UTF-8 string (0x00..0x17 bytes follow)
8190             case 0x60:
8191             case 0x61:
8192             case 0x62:
8193             case 0x63:
8194             case 0x64:
8195             case 0x65:
8196             case 0x66:
8197             case 0x67:
8198             case 0x68:
8199             case 0x69:
8200             case 0x6A:
8201             case 0x6B:
8202             case 0x6C:
8203             case 0x6D:
8204             case 0x6E:
8205             case 0x6F:
8206             case 0x70:
8207             case 0x71:
8208             case 0x72:
8209             case 0x73:
8210             case 0x74:
8211             case 0x75:
8212             case 0x76:
8213             case 0x77:
8214             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8215             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8216             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8217             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8218             case 0x7F: // UTF-8 string (indefinite length)
8219             {
8220                 string_t s;
8221                 return get_cbor_string(s) && sax->string(s);
8222             }
8223 
8224             // array (0x00..0x17 data items follow)
8225             case 0x80:
8226             case 0x81:
8227             case 0x82:
8228             case 0x83:
8229             case 0x84:
8230             case 0x85:
8231             case 0x86:
8232             case 0x87:
8233             case 0x88:
8234             case 0x89:
8235             case 0x8A:
8236             case 0x8B:
8237             case 0x8C:
8238             case 0x8D:
8239             case 0x8E:
8240             case 0x8F:
8241             case 0x90:
8242             case 0x91:
8243             case 0x92:
8244             case 0x93:
8245             case 0x94:
8246             case 0x95:
8247             case 0x96:
8248             case 0x97:
8249                 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8250 
8251             case 0x98: // array (one-byte uint8_t for n follows)
8252             {
8253                 std::uint8_t len{};
8254                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8255             }
8256 
8257             case 0x99: // array (two-byte uint16_t for n follow)
8258             {
8259                 std::uint16_t len{};
8260                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8261             }
8262 
8263             case 0x9A: // array (four-byte uint32_t for n follow)
8264             {
8265                 std::uint32_t len{};
8266                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8267             }
8268 
8269             case 0x9B: // array (eight-byte uint64_t for n follow)
8270             {
8271                 std::uint64_t len{};
8272                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8273             }
8274 
8275             case 0x9F: // array (indefinite length)
8276                 return get_cbor_array(std::size_t(-1), tag_handler);
8277 
8278             // map (0x00..0x17 pairs of data items follow)
8279             case 0xA0:
8280             case 0xA1:
8281             case 0xA2:
8282             case 0xA3:
8283             case 0xA4:
8284             case 0xA5:
8285             case 0xA6:
8286             case 0xA7:
8287             case 0xA8:
8288             case 0xA9:
8289             case 0xAA:
8290             case 0xAB:
8291             case 0xAC:
8292             case 0xAD:
8293             case 0xAE:
8294             case 0xAF:
8295             case 0xB0:
8296             case 0xB1:
8297             case 0xB2:
8298             case 0xB3:
8299             case 0xB4:
8300             case 0xB5:
8301             case 0xB6:
8302             case 0xB7:
8303                 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8304 
8305             case 0xB8: // map (one-byte uint8_t for n follows)
8306             {
8307                 std::uint8_t len{};
8308                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8309             }
8310 
8311             case 0xB9: // map (two-byte uint16_t for n follow)
8312             {
8313                 std::uint16_t len{};
8314                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8315             }
8316 
8317             case 0xBA: // map (four-byte uint32_t for n follow)
8318             {
8319                 std::uint32_t len{};
8320                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8321             }
8322 
8323             case 0xBB: // map (eight-byte uint64_t for n follow)
8324             {
8325                 std::uint64_t len{};
8326                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8327             }
8328 
8329             case 0xBF: // map (indefinite length)
8330                 return get_cbor_object(std::size_t(-1), tag_handler);
8331 
8332             case 0xC6: // tagged item
8333             case 0xC7:
8334             case 0xC8:
8335             case 0xC9:
8336             case 0xCA:
8337             case 0xCB:
8338             case 0xCC:
8339             case 0xCD:
8340             case 0xCE:
8341             case 0xCF:
8342             case 0xD0:
8343             case 0xD1:
8344             case 0xD2:
8345             case 0xD3:
8346             case 0xD4:
8347             case 0xD8: // tagged item (1 bytes follow)
8348             case 0xD9: // tagged item (2 bytes follow)
8349             case 0xDA: // tagged item (4 bytes follow)
8350             case 0xDB: // tagged item (8 bytes follow)
8351             {
8352                 switch (tag_handler)
8353                 {
8354                     case cbor_tag_handler_t::error:
8355                     {
8356                         auto last_token = get_token_string();
8357                         return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
8358                     }
8359 
8360                     case cbor_tag_handler_t::ignore:
8361                     {
8362                         switch (current)
8363                         {
8364                             case 0xD8:
8365                             {
8366                                 std::uint8_t len{};
8367                                 get_number(input_format_t::cbor, len);
8368                                 break;
8369                             }
8370                             case 0xD9:
8371                             {
8372                                 std::uint16_t len{};
8373                                 get_number(input_format_t::cbor, len);
8374                                 break;
8375                             }
8376                             case 0xDA:
8377                             {
8378                                 std::uint32_t len{};
8379                                 get_number(input_format_t::cbor, len);
8380                                 break;
8381                             }
8382                             case 0xDB:
8383                             {
8384                                 std::uint64_t len{};
8385                                 get_number(input_format_t::cbor, len);
8386                                 break;
8387                             }
8388                             default:
8389                                 break;
8390                         }
8391                         return parse_cbor_internal(true, tag_handler);
8392                     }
8393 
8394                     default:            // LCOV_EXCL_LINE
8395                         JSON_ASSERT(false);  // LCOV_EXCL_LINE
8396                 }
8397             }
8398 
8399             case 0xF4: // false
8400                 return sax->boolean(false);
8401 
8402             case 0xF5: // true
8403                 return sax->boolean(true);
8404 
8405             case 0xF6: // null
8406                 return sax->null();
8407 
8408             case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8409             {
8410                 const auto byte1_raw = get();
8411                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8412                 {
8413                     return false;
8414                 }
8415                 const auto byte2_raw = get();
8416                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8417                 {
8418                     return false;
8419                 }
8420 
8421                 const auto byte1 = static_cast<unsigned char>(byte1_raw);
8422                 const auto byte2 = static_cast<unsigned char>(byte2_raw);
8423 
8424                 // code from RFC 7049, Appendix D, Figure 3:
8425                 // As half-precision floating-point numbers were only added
8426                 // to IEEE 754 in 2008, today's programming platforms often
8427                 // still only have limited support for them. It is very
8428                 // easy to include at least decoding support for them even
8429                 // without such support. An example of a small decoder for
8430                 // half-precision floating-point numbers in the C language
8431                 // is shown in Fig. 3.
8432                 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8433                 const double val = [&half]
8434                 {
8435                     const int exp = (half >> 10u) & 0x1Fu;
8436                     const unsigned int mant = half & 0x3FFu;
8437                     JSON_ASSERT(0 <= exp&& exp <= 32);
8438                     JSON_ASSERT(mant <= 1024);
8439                     switch (exp)
8440                     {
8441                         case 0:
8442                             return std::ldexp(mant, -24);
8443                         case 31:
8444                             return (mant == 0)
8445                             ? std::numeric_limits<double>::infinity()
8446                             : std::numeric_limits<double>::quiet_NaN();
8447                         default:
8448                             return std::ldexp(mant + 1024, exp - 25);
8449                     }
8450                 }();
8451                 return sax->number_float((half & 0x8000u) != 0
8452                                          ? static_cast<number_float_t>(-val)
8453                                          : static_cast<number_float_t>(val), "");
8454             }
8455 
8456             case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8457             {
8458                 float number{};
8459                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8460             }
8461 
8462             case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8463             {
8464                 double number{};
8465                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8466             }
8467 
8468             default: // anything else (0xFF is handled inside the other types)
8469             {
8470                 auto last_token = get_token_string();
8471                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
8472             }
8473         }
8474     }
8475 
8476     /*!
8477     @brief reads a CBOR string
8478 
8479     This function first reads starting bytes to determine the expected
8480     string length and then copies this number of bytes into a string.
8481     Additionally, CBOR's strings with indefinite lengths are supported.
8482 
8483     @param[out] result  created string
8484 
8485     @return whether string creation completed
8486     */
get_cbor_string(string_t & result)8487     bool get_cbor_string(string_t& result)
8488     {
8489         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
8490         {
8491             return false;
8492         }
8493 
8494         switch (current)
8495         {
8496             // UTF-8 string (0x00..0x17 bytes follow)
8497             case 0x60:
8498             case 0x61:
8499             case 0x62:
8500             case 0x63:
8501             case 0x64:
8502             case 0x65:
8503             case 0x66:
8504             case 0x67:
8505             case 0x68:
8506             case 0x69:
8507             case 0x6A:
8508             case 0x6B:
8509             case 0x6C:
8510             case 0x6D:
8511             case 0x6E:
8512             case 0x6F:
8513             case 0x70:
8514             case 0x71:
8515             case 0x72:
8516             case 0x73:
8517             case 0x74:
8518             case 0x75:
8519             case 0x76:
8520             case 0x77:
8521             {
8522                 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8523             }
8524 
8525             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8526             {
8527                 std::uint8_t len{};
8528                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8529             }
8530 
8531             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8532             {
8533                 std::uint16_t len{};
8534                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8535             }
8536 
8537             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8538             {
8539                 std::uint32_t len{};
8540                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8541             }
8542 
8543             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8544             {
8545                 std::uint64_t len{};
8546                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8547             }
8548 
8549             case 0x7F: // UTF-8 string (indefinite length)
8550             {
8551                 while (get() != 0xFF)
8552                 {
8553                     string_t chunk;
8554                     if (!get_cbor_string(chunk))
8555                     {
8556                         return false;
8557                     }
8558                     result.append(chunk);
8559                 }
8560                 return true;
8561             }
8562 
8563             default:
8564             {
8565                 auto last_token = get_token_string();
8566                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
8567             }
8568         }
8569     }
8570 
8571     /*!
8572     @brief reads a CBOR byte array
8573 
8574     This function first reads starting bytes to determine the expected
8575     byte array length and then copies this number of bytes into the byte array.
8576     Additionally, CBOR's byte arrays with indefinite lengths are supported.
8577 
8578     @param[out] result  created byte array
8579 
8580     @return whether byte array creation completed
8581     */
get_cbor_binary(binary_t & result)8582     bool get_cbor_binary(binary_t& result)
8583     {
8584         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
8585         {
8586             return false;
8587         }
8588 
8589         switch (current)
8590         {
8591             // Binary data (0x00..0x17 bytes follow)
8592             case 0x40:
8593             case 0x41:
8594             case 0x42:
8595             case 0x43:
8596             case 0x44:
8597             case 0x45:
8598             case 0x46:
8599             case 0x47:
8600             case 0x48:
8601             case 0x49:
8602             case 0x4A:
8603             case 0x4B:
8604             case 0x4C:
8605             case 0x4D:
8606             case 0x4E:
8607             case 0x4F:
8608             case 0x50:
8609             case 0x51:
8610             case 0x52:
8611             case 0x53:
8612             case 0x54:
8613             case 0x55:
8614             case 0x56:
8615             case 0x57:
8616             {
8617                 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8618             }
8619 
8620             case 0x58: // Binary data (one-byte uint8_t for n follows)
8621             {
8622                 std::uint8_t len{};
8623                 return get_number(input_format_t::cbor, len) &&
8624                        get_binary(input_format_t::cbor, len, result);
8625             }
8626 
8627             case 0x59: // Binary data (two-byte uint16_t for n follow)
8628             {
8629                 std::uint16_t len{};
8630                 return get_number(input_format_t::cbor, len) &&
8631                        get_binary(input_format_t::cbor, len, result);
8632             }
8633 
8634             case 0x5A: // Binary data (four-byte uint32_t for n follow)
8635             {
8636                 std::uint32_t len{};
8637                 return get_number(input_format_t::cbor, len) &&
8638                        get_binary(input_format_t::cbor, len, result);
8639             }
8640 
8641             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8642             {
8643                 std::uint64_t len{};
8644                 return get_number(input_format_t::cbor, len) &&
8645                        get_binary(input_format_t::cbor, len, result);
8646             }
8647 
8648             case 0x5F: // Binary data (indefinite length)
8649             {
8650                 while (get() != 0xFF)
8651                 {
8652                     binary_t chunk;
8653                     if (!get_cbor_binary(chunk))
8654                     {
8655                         return false;
8656                     }
8657                     result.insert(result.end(), chunk.begin(), chunk.end());
8658                 }
8659                 return true;
8660             }
8661 
8662             default:
8663             {
8664                 auto last_token = get_token_string();
8665                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
8666             }
8667         }
8668     }
8669 
8670     /*!
8671     @param[in] len  the length of the array or std::size_t(-1) for an
8672                     array of indefinite size
8673     @param[in] tag_handler how CBOR tags should be treated
8674     @return whether array creation completed
8675     */
get_cbor_array(const std::size_t len,const cbor_tag_handler_t tag_handler)8676     bool get_cbor_array(const std::size_t len,
8677                         const cbor_tag_handler_t tag_handler)
8678     {
8679         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8680         {
8681             return false;
8682         }
8683 
8684         if (len != std::size_t(-1))
8685         {
8686             for (std::size_t i = 0; i < len; ++i)
8687             {
8688                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8689                 {
8690                     return false;
8691                 }
8692             }
8693         }
8694         else
8695         {
8696             while (get() != 0xFF)
8697             {
8698                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8699                 {
8700                     return false;
8701                 }
8702             }
8703         }
8704 
8705         return sax->end_array();
8706     }
8707 
8708     /*!
8709     @param[in] len  the length of the object or std::size_t(-1) for an
8710                     object of indefinite size
8711     @param[in] tag_handler how CBOR tags should be treated
8712     @return whether object creation completed
8713     */
get_cbor_object(const std::size_t len,const cbor_tag_handler_t tag_handler)8714     bool get_cbor_object(const std::size_t len,
8715                          const cbor_tag_handler_t tag_handler)
8716     {
8717         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8718         {
8719             return false;
8720         }
8721 
8722         string_t key;
8723         if (len != std::size_t(-1))
8724         {
8725             for (std::size_t i = 0; i < len; ++i)
8726             {
8727                 get();
8728                 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8729                 {
8730                     return false;
8731                 }
8732 
8733                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8734                 {
8735                     return false;
8736                 }
8737                 key.clear();
8738             }
8739         }
8740         else
8741         {
8742             while (get() != 0xFF)
8743             {
8744                 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8745                 {
8746                     return false;
8747                 }
8748 
8749                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8750                 {
8751                     return false;
8752                 }
8753                 key.clear();
8754             }
8755         }
8756 
8757         return sax->end_object();
8758     }
8759 
8760     /////////////
8761     // MsgPack //
8762     /////////////
8763 
8764     /*!
8765     @return whether a valid MessagePack value was passed to the SAX parser
8766     */
parse_msgpack_internal()8767     bool parse_msgpack_internal()
8768     {
8769         switch (get())
8770         {
8771             // EOF
8772             case std::char_traits<char_type>::eof():
8773                 return unexpect_eof(input_format_t::msgpack, "value");
8774 
8775             // positive fixint
8776             case 0x00:
8777             case 0x01:
8778             case 0x02:
8779             case 0x03:
8780             case 0x04:
8781             case 0x05:
8782             case 0x06:
8783             case 0x07:
8784             case 0x08:
8785             case 0x09:
8786             case 0x0A:
8787             case 0x0B:
8788             case 0x0C:
8789             case 0x0D:
8790             case 0x0E:
8791             case 0x0F:
8792             case 0x10:
8793             case 0x11:
8794             case 0x12:
8795             case 0x13:
8796             case 0x14:
8797             case 0x15:
8798             case 0x16:
8799             case 0x17:
8800             case 0x18:
8801             case 0x19:
8802             case 0x1A:
8803             case 0x1B:
8804             case 0x1C:
8805             case 0x1D:
8806             case 0x1E:
8807             case 0x1F:
8808             case 0x20:
8809             case 0x21:
8810             case 0x22:
8811             case 0x23:
8812             case 0x24:
8813             case 0x25:
8814             case 0x26:
8815             case 0x27:
8816             case 0x28:
8817             case 0x29:
8818             case 0x2A:
8819             case 0x2B:
8820             case 0x2C:
8821             case 0x2D:
8822             case 0x2E:
8823             case 0x2F:
8824             case 0x30:
8825             case 0x31:
8826             case 0x32:
8827             case 0x33:
8828             case 0x34:
8829             case 0x35:
8830             case 0x36:
8831             case 0x37:
8832             case 0x38:
8833             case 0x39:
8834             case 0x3A:
8835             case 0x3B:
8836             case 0x3C:
8837             case 0x3D:
8838             case 0x3E:
8839             case 0x3F:
8840             case 0x40:
8841             case 0x41:
8842             case 0x42:
8843             case 0x43:
8844             case 0x44:
8845             case 0x45:
8846             case 0x46:
8847             case 0x47:
8848             case 0x48:
8849             case 0x49:
8850             case 0x4A:
8851             case 0x4B:
8852             case 0x4C:
8853             case 0x4D:
8854             case 0x4E:
8855             case 0x4F:
8856             case 0x50:
8857             case 0x51:
8858             case 0x52:
8859             case 0x53:
8860             case 0x54:
8861             case 0x55:
8862             case 0x56:
8863             case 0x57:
8864             case 0x58:
8865             case 0x59:
8866             case 0x5A:
8867             case 0x5B:
8868             case 0x5C:
8869             case 0x5D:
8870             case 0x5E:
8871             case 0x5F:
8872             case 0x60:
8873             case 0x61:
8874             case 0x62:
8875             case 0x63:
8876             case 0x64:
8877             case 0x65:
8878             case 0x66:
8879             case 0x67:
8880             case 0x68:
8881             case 0x69:
8882             case 0x6A:
8883             case 0x6B:
8884             case 0x6C:
8885             case 0x6D:
8886             case 0x6E:
8887             case 0x6F:
8888             case 0x70:
8889             case 0x71:
8890             case 0x72:
8891             case 0x73:
8892             case 0x74:
8893             case 0x75:
8894             case 0x76:
8895             case 0x77:
8896             case 0x78:
8897             case 0x79:
8898             case 0x7A:
8899             case 0x7B:
8900             case 0x7C:
8901             case 0x7D:
8902             case 0x7E:
8903             case 0x7F:
8904                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8905 
8906             // fixmap
8907             case 0x80:
8908             case 0x81:
8909             case 0x82:
8910             case 0x83:
8911             case 0x84:
8912             case 0x85:
8913             case 0x86:
8914             case 0x87:
8915             case 0x88:
8916             case 0x89:
8917             case 0x8A:
8918             case 0x8B:
8919             case 0x8C:
8920             case 0x8D:
8921             case 0x8E:
8922             case 0x8F:
8923                 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8924 
8925             // fixarray
8926             case 0x90:
8927             case 0x91:
8928             case 0x92:
8929             case 0x93:
8930             case 0x94:
8931             case 0x95:
8932             case 0x96:
8933             case 0x97:
8934             case 0x98:
8935             case 0x99:
8936             case 0x9A:
8937             case 0x9B:
8938             case 0x9C:
8939             case 0x9D:
8940             case 0x9E:
8941             case 0x9F:
8942                 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8943 
8944             // fixstr
8945             case 0xA0:
8946             case 0xA1:
8947             case 0xA2:
8948             case 0xA3:
8949             case 0xA4:
8950             case 0xA5:
8951             case 0xA6:
8952             case 0xA7:
8953             case 0xA8:
8954             case 0xA9:
8955             case 0xAA:
8956             case 0xAB:
8957             case 0xAC:
8958             case 0xAD:
8959             case 0xAE:
8960             case 0xAF:
8961             case 0xB0:
8962             case 0xB1:
8963             case 0xB2:
8964             case 0xB3:
8965             case 0xB4:
8966             case 0xB5:
8967             case 0xB6:
8968             case 0xB7:
8969             case 0xB8:
8970             case 0xB9:
8971             case 0xBA:
8972             case 0xBB:
8973             case 0xBC:
8974             case 0xBD:
8975             case 0xBE:
8976             case 0xBF:
8977             case 0xD9: // str 8
8978             case 0xDA: // str 16
8979             case 0xDB: // str 32
8980             {
8981                 string_t s;
8982                 return get_msgpack_string(s) && sax->string(s);
8983             }
8984 
8985             case 0xC0: // nil
8986                 return sax->null();
8987 
8988             case 0xC2: // false
8989                 return sax->boolean(false);
8990 
8991             case 0xC3: // true
8992                 return sax->boolean(true);
8993 
8994             case 0xC4: // bin 8
8995             case 0xC5: // bin 16
8996             case 0xC6: // bin 32
8997             case 0xC7: // ext 8
8998             case 0xC8: // ext 16
8999             case 0xC9: // ext 32
9000             case 0xD4: // fixext 1
9001             case 0xD5: // fixext 2
9002             case 0xD6: // fixext 4
9003             case 0xD7: // fixext 8
9004             case 0xD8: // fixext 16
9005             {
9006                 binary_t b;
9007                 return get_msgpack_binary(b) && sax->binary(b);
9008             }
9009 
9010             case 0xCA: // float 32
9011             {
9012                 float number{};
9013                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9014             }
9015 
9016             case 0xCB: // float 64
9017             {
9018                 double number{};
9019                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9020             }
9021 
9022             case 0xCC: // uint 8
9023             {
9024                 std::uint8_t number{};
9025                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9026             }
9027 
9028             case 0xCD: // uint 16
9029             {
9030                 std::uint16_t number{};
9031                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9032             }
9033 
9034             case 0xCE: // uint 32
9035             {
9036                 std::uint32_t number{};
9037                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9038             }
9039 
9040             case 0xCF: // uint 64
9041             {
9042                 std::uint64_t number{};
9043                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9044             }
9045 
9046             case 0xD0: // int 8
9047             {
9048                 std::int8_t number{};
9049                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9050             }
9051 
9052             case 0xD1: // int 16
9053             {
9054                 std::int16_t number{};
9055                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9056             }
9057 
9058             case 0xD2: // int 32
9059             {
9060                 std::int32_t number{};
9061                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9062             }
9063 
9064             case 0xD3: // int 64
9065             {
9066                 std::int64_t number{};
9067                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9068             }
9069 
9070             case 0xDC: // array 16
9071             {
9072                 std::uint16_t len{};
9073                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9074             }
9075 
9076             case 0xDD: // array 32
9077             {
9078                 std::uint32_t len{};
9079                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9080             }
9081 
9082             case 0xDE: // map 16
9083             {
9084                 std::uint16_t len{};
9085                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9086             }
9087 
9088             case 0xDF: // map 32
9089             {
9090                 std::uint32_t len{};
9091                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9092             }
9093 
9094             // negative fixint
9095             case 0xE0:
9096             case 0xE1:
9097             case 0xE2:
9098             case 0xE3:
9099             case 0xE4:
9100             case 0xE5:
9101             case 0xE6:
9102             case 0xE7:
9103             case 0xE8:
9104             case 0xE9:
9105             case 0xEA:
9106             case 0xEB:
9107             case 0xEC:
9108             case 0xED:
9109             case 0xEE:
9110             case 0xEF:
9111             case 0xF0:
9112             case 0xF1:
9113             case 0xF2:
9114             case 0xF3:
9115             case 0xF4:
9116             case 0xF5:
9117             case 0xF6:
9118             case 0xF7:
9119             case 0xF8:
9120             case 0xF9:
9121             case 0xFA:
9122             case 0xFB:
9123             case 0xFC:
9124             case 0xFD:
9125             case 0xFE:
9126             case 0xFF:
9127                 return sax->number_integer(static_cast<std::int8_t>(current));
9128 
9129             default: // anything else
9130             {
9131                 auto last_token = get_token_string();
9132                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
9133             }
9134         }
9135     }
9136 
9137     /*!
9138     @brief reads a MessagePack string
9139 
9140     This function first reads starting bytes to determine the expected
9141     string length and then copies this number of bytes into a string.
9142 
9143     @param[out] result  created string
9144 
9145     @return whether string creation completed
9146     */
get_msgpack_string(string_t & result)9147     bool get_msgpack_string(string_t& result)
9148     {
9149         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9150         {
9151             return false;
9152         }
9153 
9154         switch (current)
9155         {
9156             // fixstr
9157             case 0xA0:
9158             case 0xA1:
9159             case 0xA2:
9160             case 0xA3:
9161             case 0xA4:
9162             case 0xA5:
9163             case 0xA6:
9164             case 0xA7:
9165             case 0xA8:
9166             case 0xA9:
9167             case 0xAA:
9168             case 0xAB:
9169             case 0xAC:
9170             case 0xAD:
9171             case 0xAE:
9172             case 0xAF:
9173             case 0xB0:
9174             case 0xB1:
9175             case 0xB2:
9176             case 0xB3:
9177             case 0xB4:
9178             case 0xB5:
9179             case 0xB6:
9180             case 0xB7:
9181             case 0xB8:
9182             case 0xB9:
9183             case 0xBA:
9184             case 0xBB:
9185             case 0xBC:
9186             case 0xBD:
9187             case 0xBE:
9188             case 0xBF:
9189             {
9190                 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9191             }
9192 
9193             case 0xD9: // str 8
9194             {
9195                 std::uint8_t len{};
9196                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9197             }
9198 
9199             case 0xDA: // str 16
9200             {
9201                 std::uint16_t len{};
9202                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9203             }
9204 
9205             case 0xDB: // str 32
9206             {
9207                 std::uint32_t len{};
9208                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9209             }
9210 
9211             default:
9212             {
9213                 auto last_token = get_token_string();
9214                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
9215             }
9216         }
9217     }
9218 
9219     /*!
9220     @brief reads a MessagePack byte array
9221 
9222     This function first reads starting bytes to determine the expected
9223     byte array length and then copies this number of bytes into a byte array.
9224 
9225     @param[out] result  created byte array
9226 
9227     @return whether byte array creation completed
9228     */
get_msgpack_binary(binary_t & result)9229     bool get_msgpack_binary(binary_t& result)
9230     {
9231         // helper function to set the subtype
9232         auto assign_and_return_true = [&result](std::int8_t subtype)
9233         {
9234             result.set_subtype(static_cast<std::uint8_t>(subtype));
9235             return true;
9236         };
9237 
9238         switch (current)
9239         {
9240             case 0xC4: // bin 8
9241             {
9242                 std::uint8_t len{};
9243                 return get_number(input_format_t::msgpack, len) &&
9244                        get_binary(input_format_t::msgpack, len, result);
9245             }
9246 
9247             case 0xC5: // bin 16
9248             {
9249                 std::uint16_t len{};
9250                 return get_number(input_format_t::msgpack, len) &&
9251                        get_binary(input_format_t::msgpack, len, result);
9252             }
9253 
9254             case 0xC6: // bin 32
9255             {
9256                 std::uint32_t len{};
9257                 return get_number(input_format_t::msgpack, len) &&
9258                        get_binary(input_format_t::msgpack, len, result);
9259             }
9260 
9261             case 0xC7: // ext 8
9262             {
9263                 std::uint8_t len{};
9264                 std::int8_t subtype{};
9265                 return get_number(input_format_t::msgpack, len) &&
9266                        get_number(input_format_t::msgpack, subtype) &&
9267                        get_binary(input_format_t::msgpack, len, result) &&
9268                        assign_and_return_true(subtype);
9269             }
9270 
9271             case 0xC8: // ext 16
9272             {
9273                 std::uint16_t len{};
9274                 std::int8_t subtype{};
9275                 return get_number(input_format_t::msgpack, len) &&
9276                        get_number(input_format_t::msgpack, subtype) &&
9277                        get_binary(input_format_t::msgpack, len, result) &&
9278                        assign_and_return_true(subtype);
9279             }
9280 
9281             case 0xC9: // ext 32
9282             {
9283                 std::uint32_t len{};
9284                 std::int8_t subtype{};
9285                 return get_number(input_format_t::msgpack, len) &&
9286                        get_number(input_format_t::msgpack, subtype) &&
9287                        get_binary(input_format_t::msgpack, len, result) &&
9288                        assign_and_return_true(subtype);
9289             }
9290 
9291             case 0xD4: // fixext 1
9292             {
9293                 std::int8_t subtype{};
9294                 return get_number(input_format_t::msgpack, subtype) &&
9295                        get_binary(input_format_t::msgpack, 1, result) &&
9296                        assign_and_return_true(subtype);
9297             }
9298 
9299             case 0xD5: // fixext 2
9300             {
9301                 std::int8_t subtype{};
9302                 return get_number(input_format_t::msgpack, subtype) &&
9303                        get_binary(input_format_t::msgpack, 2, result) &&
9304                        assign_and_return_true(subtype);
9305             }
9306 
9307             case 0xD6: // fixext 4
9308             {
9309                 std::int8_t subtype{};
9310                 return get_number(input_format_t::msgpack, subtype) &&
9311                        get_binary(input_format_t::msgpack, 4, result) &&
9312                        assign_and_return_true(subtype);
9313             }
9314 
9315             case 0xD7: // fixext 8
9316             {
9317                 std::int8_t subtype{};
9318                 return get_number(input_format_t::msgpack, subtype) &&
9319                        get_binary(input_format_t::msgpack, 8, result) &&
9320                        assign_and_return_true(subtype);
9321             }
9322 
9323             case 0xD8: // fixext 16
9324             {
9325                 std::int8_t subtype{};
9326                 return get_number(input_format_t::msgpack, subtype) &&
9327                        get_binary(input_format_t::msgpack, 16, result) &&
9328                        assign_and_return_true(subtype);
9329             }
9330 
9331             default:           // LCOV_EXCL_LINE
9332                 return false;  // LCOV_EXCL_LINE
9333         }
9334     }
9335 
9336     /*!
9337     @param[in] len  the length of the array
9338     @return whether array creation completed
9339     */
get_msgpack_array(const std::size_t len)9340     bool get_msgpack_array(const std::size_t len)
9341     {
9342         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9343         {
9344             return false;
9345         }
9346 
9347         for (std::size_t i = 0; i < len; ++i)
9348         {
9349             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9350             {
9351                 return false;
9352             }
9353         }
9354 
9355         return sax->end_array();
9356     }
9357 
9358     /*!
9359     @param[in] len  the length of the object
9360     @return whether object creation completed
9361     */
get_msgpack_object(const std::size_t len)9362     bool get_msgpack_object(const std::size_t len)
9363     {
9364         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9365         {
9366             return false;
9367         }
9368 
9369         string_t key;
9370         for (std::size_t i = 0; i < len; ++i)
9371         {
9372             get();
9373             if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9374             {
9375                 return false;
9376             }
9377 
9378             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9379             {
9380                 return false;
9381             }
9382             key.clear();
9383         }
9384 
9385         return sax->end_object();
9386     }
9387 
9388     ////////////
9389     // UBJSON //
9390     ////////////
9391 
9392     /*!
9393     @param[in] get_char  whether a new character should be retrieved from the
9394                          input (true, default) or whether the last read
9395                          character should be considered instead
9396 
9397     @return whether a valid UBJSON value was passed to the SAX parser
9398     */
parse_ubjson_internal(const bool get_char=true)9399     bool parse_ubjson_internal(const bool get_char = true)
9400     {
9401         return get_ubjson_value(get_char ? get_ignore_noop() : current);
9402     }
9403 
9404     /*!
9405     @brief reads a UBJSON string
9406 
9407     This function is either called after reading the 'S' byte explicitly
9408     indicating a string, or in case of an object key where the 'S' byte can be
9409     left out.
9410 
9411     @param[out] result   created string
9412     @param[in] get_char  whether a new character should be retrieved from the
9413                          input (true, default) or whether the last read
9414                          character should be considered instead
9415 
9416     @return whether string creation completed
9417     */
get_ubjson_string(string_t & result,const bool get_char=true)9418     bool get_ubjson_string(string_t& result, const bool get_char = true)
9419     {
9420         if (get_char)
9421         {
9422             get();  // TODO(niels): may we ignore N here?
9423         }
9424 
9425         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9426         {
9427             return false;
9428         }
9429 
9430         switch (current)
9431         {
9432             case 'U':
9433             {
9434                 std::uint8_t len{};
9435                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9436             }
9437 
9438             case 'i':
9439             {
9440                 std::int8_t len{};
9441                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9442             }
9443 
9444             case 'I':
9445             {
9446                 std::int16_t len{};
9447                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9448             }
9449 
9450             case 'l':
9451             {
9452                 std::int32_t len{};
9453                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9454             }
9455 
9456             case 'L':
9457             {
9458                 std::int64_t len{};
9459                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9460             }
9461 
9462             default:
9463                 auto last_token = get_token_string();
9464                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
9465         }
9466     }
9467 
9468     /*!
9469     @param[out] result  determined size
9470     @return whether size determination completed
9471     */
get_ubjson_size_value(std::size_t & result)9472     bool get_ubjson_size_value(std::size_t& result)
9473     {
9474         switch (get_ignore_noop())
9475         {
9476             case 'U':
9477             {
9478                 std::uint8_t number{};
9479                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9480                 {
9481                     return false;
9482                 }
9483                 result = static_cast<std::size_t>(number);
9484                 return true;
9485             }
9486 
9487             case 'i':
9488             {
9489                 std::int8_t number{};
9490                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9491                 {
9492                     return false;
9493                 }
9494                 result = static_cast<std::size_t>(number);
9495                 return true;
9496             }
9497 
9498             case 'I':
9499             {
9500                 std::int16_t number{};
9501                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9502                 {
9503                     return false;
9504                 }
9505                 result = static_cast<std::size_t>(number);
9506                 return true;
9507             }
9508 
9509             case 'l':
9510             {
9511                 std::int32_t number{};
9512                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9513                 {
9514                     return false;
9515                 }
9516                 result = static_cast<std::size_t>(number);
9517                 return true;
9518             }
9519 
9520             case 'L':
9521             {
9522                 std::int64_t number{};
9523                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9524                 {
9525                     return false;
9526                 }
9527                 result = static_cast<std::size_t>(number);
9528                 return true;
9529             }
9530 
9531             default:
9532             {
9533                 auto last_token = get_token_string();
9534                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
9535             }
9536         }
9537     }
9538 
9539     /*!
9540     @brief determine the type and size for a container
9541 
9542     In the optimized UBJSON format, a type and a size can be provided to allow
9543     for a more compact representation.
9544 
9545     @param[out] result  pair of the size and the type
9546 
9547     @return whether pair creation completed
9548     */
get_ubjson_size_type(std::pair<std::size_t,char_int_type> & result)9549     bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9550     {
9551         result.first = string_t::npos; // size
9552         result.second = 0; // type
9553 
9554         get_ignore_noop();
9555 
9556         if (current == '$')
9557         {
9558             result.second = get();  // must not ignore 'N', because 'N' maybe the type
9559             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
9560             {
9561                 return false;
9562             }
9563 
9564             get_ignore_noop();
9565             if (JSON_HEDLEY_UNLIKELY(current != '#'))
9566             {
9567                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9568                 {
9569                     return false;
9570                 }
9571                 auto last_token = get_token_string();
9572                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
9573             }
9574 
9575             return get_ubjson_size_value(result.first);
9576         }
9577 
9578         if (current == '#')
9579         {
9580             return get_ubjson_size_value(result.first);
9581         }
9582 
9583         return true;
9584     }
9585 
9586     /*!
9587     @param prefix  the previously read or set type prefix
9588     @return whether value creation completed
9589     */
get_ubjson_value(const char_int_type prefix)9590     bool get_ubjson_value(const char_int_type prefix)
9591     {
9592         switch (prefix)
9593         {
9594             case std::char_traits<char_type>::eof():  // EOF
9595                 return unexpect_eof(input_format_t::ubjson, "value");
9596 
9597             case 'T':  // true
9598                 return sax->boolean(true);
9599             case 'F':  // false
9600                 return sax->boolean(false);
9601 
9602             case 'Z':  // null
9603                 return sax->null();
9604 
9605             case 'U':
9606             {
9607                 std::uint8_t number{};
9608                 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9609             }
9610 
9611             case 'i':
9612             {
9613                 std::int8_t number{};
9614                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9615             }
9616 
9617             case 'I':
9618             {
9619                 std::int16_t number{};
9620                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9621             }
9622 
9623             case 'l':
9624             {
9625                 std::int32_t number{};
9626                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9627             }
9628 
9629             case 'L':
9630             {
9631                 std::int64_t number{};
9632                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9633             }
9634 
9635             case 'd':
9636             {
9637                 float number{};
9638                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9639             }
9640 
9641             case 'D':
9642             {
9643                 double number{};
9644                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9645             }
9646 
9647             case 'H':
9648             {
9649                 return get_ubjson_high_precision_number();
9650             }
9651 
9652             case 'C':  // char
9653             {
9654                 get();
9655                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
9656                 {
9657                     return false;
9658                 }
9659                 if (JSON_HEDLEY_UNLIKELY(current > 127))
9660                 {
9661                     auto last_token = get_token_string();
9662                     return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
9663                 }
9664                 string_t s(1, static_cast<typename string_t::value_type>(current));
9665                 return sax->string(s);
9666             }
9667 
9668             case 'S':  // string
9669             {
9670                 string_t s;
9671                 return get_ubjson_string(s) && sax->string(s);
9672             }
9673 
9674             case '[':  // array
9675                 return get_ubjson_array();
9676 
9677             case '{':  // object
9678                 return get_ubjson_object();
9679 
9680             default: // anything else
9681             {
9682                 auto last_token = get_token_string();
9683                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
9684             }
9685         }
9686     }
9687 
9688     /*!
9689     @return whether array creation completed
9690     */
get_ubjson_array()9691     bool get_ubjson_array()
9692     {
9693         std::pair<std::size_t, char_int_type> size_and_type;
9694         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9695         {
9696             return false;
9697         }
9698 
9699         if (size_and_type.first != string_t::npos)
9700         {
9701             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9702             {
9703                 return false;
9704             }
9705 
9706             if (size_and_type.second != 0)
9707             {
9708                 if (size_and_type.second != 'N')
9709                 {
9710                     for (std::size_t i = 0; i < size_and_type.first; ++i)
9711                     {
9712                         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9713                         {
9714                             return false;
9715                         }
9716                     }
9717                 }
9718             }
9719             else
9720             {
9721                 for (std::size_t i = 0; i < size_and_type.first; ++i)
9722                 {
9723                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9724                     {
9725                         return false;
9726                     }
9727                 }
9728             }
9729         }
9730         else
9731         {
9732             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9733             {
9734                 return false;
9735             }
9736 
9737             while (current != ']')
9738             {
9739                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
9740                 {
9741                     return false;
9742                 }
9743                 get_ignore_noop();
9744             }
9745         }
9746 
9747         return sax->end_array();
9748     }
9749 
9750     /*!
9751     @return whether object creation completed
9752     */
get_ubjson_object()9753     bool get_ubjson_object()
9754     {
9755         std::pair<std::size_t, char_int_type> size_and_type;
9756         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9757         {
9758             return false;
9759         }
9760 
9761         string_t key;
9762         if (size_and_type.first != string_t::npos)
9763         {
9764             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9765             {
9766                 return false;
9767             }
9768 
9769             if (size_and_type.second != 0)
9770             {
9771                 for (std::size_t i = 0; i < size_and_type.first; ++i)
9772                 {
9773                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9774                     {
9775                         return false;
9776                     }
9777                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9778                     {
9779                         return false;
9780                     }
9781                     key.clear();
9782                 }
9783             }
9784             else
9785             {
9786                 for (std::size_t i = 0; i < size_and_type.first; ++i)
9787                 {
9788                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9789                     {
9790                         return false;
9791                     }
9792                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9793                     {
9794                         return false;
9795                     }
9796                     key.clear();
9797                 }
9798             }
9799         }
9800         else
9801         {
9802             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9803             {
9804                 return false;
9805             }
9806 
9807             while (current != '}')
9808             {
9809                 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9810                 {
9811                     return false;
9812                 }
9813                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9814                 {
9815                     return false;
9816                 }
9817                 get_ignore_noop();
9818                 key.clear();
9819             }
9820         }
9821 
9822         return sax->end_object();
9823     }
9824 
9825     // Note, no reader for UBJSON binary types is implemented because they do
9826     // not exist
9827 
get_ubjson_high_precision_number()9828     bool get_ubjson_high_precision_number()
9829     {
9830         // get size of following number string
9831         std::size_t size{};
9832         auto res = get_ubjson_size_value(size);
9833         if (JSON_HEDLEY_UNLIKELY(!res))
9834         {
9835             return res;
9836         }
9837 
9838         // get number string
9839         std::vector<char> number_vector;
9840         for (std::size_t i = 0; i < size; ++i)
9841         {
9842             get();
9843             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
9844             {
9845                 return false;
9846             }
9847             number_vector.push_back(static_cast<char>(current));
9848         }
9849 
9850         // parse number string
9851         auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9852         auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9853         const auto result_number = number_lexer.scan();
9854         const auto number_string = number_lexer.get_token_string();
9855         const auto result_remainder = number_lexer.scan();
9856 
9857         using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9858 
9859         if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9860         {
9861             return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9862         }
9863 
9864         switch (result_number)
9865         {
9866             case token_type::value_integer:
9867                 return sax->number_integer(number_lexer.get_number_integer());
9868             case token_type::value_unsigned:
9869                 return sax->number_unsigned(number_lexer.get_number_unsigned());
9870             case token_type::value_float:
9871                 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9872             default:
9873                 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9874         }
9875     }
9876 
9877     ///////////////////////
9878     // Utility functions //
9879     ///////////////////////
9880 
9881     /*!
9882     @brief get next character from the input
9883 
9884     This function provides the interface to the used input adapter. It does
9885     not throw in case the input reached EOF, but returns a -'ve valued
9886     `std::char_traits<char_type>::eof()` in that case.
9887 
9888     @return character read from the input
9889     */
get()9890     char_int_type get()
9891     {
9892         ++chars_read;
9893         return current = ia.get_character();
9894     }
9895 
9896     /*!
9897     @return character read from the input after ignoring all 'N' entries
9898     */
get_ignore_noop()9899     char_int_type get_ignore_noop()
9900     {
9901         do
9902         {
9903             get();
9904         }
9905         while (current == 'N');
9906 
9907         return current;
9908     }
9909 
9910     /*
9911     @brief read a number from the input
9912 
9913     @tparam NumberType the type of the number
9914     @param[in] format   the current format (for diagnostics)
9915     @param[out] result  number of type @a NumberType
9916 
9917     @return whether conversion completed
9918 
9919     @note This function needs to respect the system's endianess, because
9920           bytes in CBOR, MessagePack, and UBJSON are stored in network order
9921           (big endian) and therefore need reordering on little endian systems.
9922     */
9923     template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)9924     bool get_number(const input_format_t format, NumberType& result)
9925     {
9926         // step 1: read input into array with system's byte order
9927         std::array<std::uint8_t, sizeof(NumberType)> vec;
9928         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9929         {
9930             get();
9931             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
9932             {
9933                 return false;
9934             }
9935 
9936             // reverse byte order prior to conversion if necessary
9937             if (is_little_endian != InputIsLittleEndian)
9938             {
9939                 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
9940             }
9941             else
9942             {
9943                 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
9944             }
9945         }
9946 
9947         // step 2: convert array into number of type T and return
9948         std::memcpy(&result, vec.data(), sizeof(NumberType));
9949         return true;
9950     }
9951 
9952     /*!
9953     @brief create a string by reading characters from the input
9954 
9955     @tparam NumberType the type of the number
9956     @param[in] format the current format (for diagnostics)
9957     @param[in] len number of characters to read
9958     @param[out] result string created by reading @a len bytes
9959 
9960     @return whether string creation completed
9961 
9962     @note We can not reserve @a len bytes for the result, because @a len
9963           may be too large. Usually, @ref unexpect_eof() detects the end of
9964           the input before we run out of string memory.
9965     */
9966     template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)9967     bool get_string(const input_format_t format,
9968                     const NumberType len,
9969                     string_t& result)
9970     {
9971         bool success = true;
9972         for (NumberType i = 0; i < len; i++)
9973         {
9974             get();
9975             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
9976             {
9977                 success = false;
9978                 break;
9979             }
9980             result.push_back(static_cast<typename string_t::value_type>(current));
9981         };
9982         return success;
9983     }
9984 
9985     /*!
9986     @brief create a byte array by reading bytes from the input
9987 
9988     @tparam NumberType the type of the number
9989     @param[in] format the current format (for diagnostics)
9990     @param[in] len number of bytes to read
9991     @param[out] result byte array created by reading @a len bytes
9992 
9993     @return whether byte array creation completed
9994 
9995     @note We can not reserve @a len bytes for the result, because @a len
9996           may be too large. Usually, @ref unexpect_eof() detects the end of
9997           the input before we run out of memory.
9998     */
9999     template<typename NumberType>
get_binary(const input_format_t format,const NumberType len,binary_t & result)10000     bool get_binary(const input_format_t format,
10001                     const NumberType len,
10002                     binary_t& result)
10003     {
10004         bool success = true;
10005         for (NumberType i = 0; i < len; i++)
10006         {
10007             get();
10008             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10009             {
10010                 success = false;
10011                 break;
10012             }
10013             result.push_back(static_cast<std::uint8_t>(current));
10014         }
10015         return success;
10016     }
10017 
10018     /*!
10019     @param[in] format   the current format (for diagnostics)
10020     @param[in] context  further context information (for diagnostics)
10021     @return whether the last read character is not EOF
10022     */
10023     JSON_HEDLEY_NON_NULL(3)
unexpect_eof(const input_format_t format,const char * context) const10024     bool unexpect_eof(const input_format_t format, const char* context) const
10025     {
10026         if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10027         {
10028             return sax->parse_error(chars_read, "<end of file>",
10029                                     parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10030         }
10031         return true;
10032     }
10033 
10034     /*!
10035     @return a string representation of the last read byte
10036     */
get_token_string() const10037     std::string get_token_string() const
10038     {
10039         std::array<char, 3> cr{{}};
10040         (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10041         return std::string{cr.data()};
10042     }
10043 
10044     /*!
10045     @param[in] format   the current format
10046     @param[in] detail   a detailed error message
10047     @param[in] context  further context information
10048     @return a message string to use in the parse_error exceptions
10049     */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const10050     std::string exception_message(const input_format_t format,
10051                                   const std::string& detail,
10052                                   const std::string& context) const
10053     {
10054         std::string error_msg = "syntax error while parsing ";
10055 
10056         switch (format)
10057         {
10058             case input_format_t::cbor:
10059                 error_msg += "CBOR";
10060                 break;
10061 
10062             case input_format_t::msgpack:
10063                 error_msg += "MessagePack";
10064                 break;
10065 
10066             case input_format_t::ubjson:
10067                 error_msg += "UBJSON";
10068                 break;
10069 
10070             case input_format_t::bson:
10071                 error_msg += "BSON";
10072                 break;
10073 
10074             default:            // LCOV_EXCL_LINE
10075                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
10076         }
10077 
10078         return error_msg + " " + context + ": " + detail;
10079     }
10080 
10081   private:
10082     /// input adapter
10083     InputAdapterType ia;
10084 
10085     /// the current character
10086     char_int_type current = std::char_traits<char_type>::eof();
10087 
10088     /// the number of characters read
10089     std::size_t chars_read = 0;
10090 
10091     /// whether we can assume little endianess
10092     const bool is_little_endian = little_endianess();
10093 
10094     /// the SAX parser
10095     json_sax_t* sax = nullptr;
10096 };
10097 }  // namespace detail
10098 }  // namespace nlohmann
10099 
10100 // #include <nlohmann/detail/input/input_adapters.hpp>
10101 
10102 // #include <nlohmann/detail/input/lexer.hpp>
10103 
10104 // #include <nlohmann/detail/input/parser.hpp>
10105 
10106 
10107 #include <cmath> // isfinite
10108 #include <cstdint> // uint8_t
10109 #include <functional> // function
10110 #include <string> // string
10111 #include <utility> // move
10112 #include <vector> // vector
10113 
10114 // #include <nlohmann/detail/exceptions.hpp>
10115 
10116 // #include <nlohmann/detail/input/input_adapters.hpp>
10117 
10118 // #include <nlohmann/detail/input/json_sax.hpp>
10119 
10120 // #include <nlohmann/detail/input/lexer.hpp>
10121 
10122 // #include <nlohmann/detail/macro_scope.hpp>
10123 
10124 // #include <nlohmann/detail/meta/is_sax.hpp>
10125 
10126 // #include <nlohmann/detail/value_t.hpp>
10127 
10128 
10129 namespace nlohmann
10130 {
10131 namespace detail
10132 {
10133 ////////////
10134 // parser //
10135 ////////////
10136 
10137 enum class parse_event_t : uint8_t
10138 {
10139     /// the parser read `{` and started to process a JSON object
10140     object_start,
10141     /// the parser read `}` and finished processing a JSON object
10142     object_end,
10143     /// the parser read `[` and started to process a JSON array
10144     array_start,
10145     /// the parser read `]` and finished processing a JSON array
10146     array_end,
10147     /// the parser read a key of a value in an object
10148     key,
10149     /// the parser finished reading a JSON value
10150     value
10151 };
10152 
10153 template<typename BasicJsonType>
10154 using parser_callback_t =
10155     std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10156 
10157 /*!
10158 @brief syntax analysis
10159 
10160 This class implements a recursive descent parser.
10161 */
10162 template<typename BasicJsonType, typename InputAdapterType>
10163 class parser
10164 {
10165     using number_integer_t = typename BasicJsonType::number_integer_t;
10166     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10167     using number_float_t = typename BasicJsonType::number_float_t;
10168     using string_t = typename BasicJsonType::string_t;
10169     using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10170     using token_type = typename lexer_t::token_type;
10171 
10172   public:
10173     /// a parser reading from an input adapter
parser(InputAdapterType && adapter,const parser_callback_t<BasicJsonType> cb=nullptr,const bool allow_exceptions_=true,const bool skip_comments=false)10174     explicit parser(InputAdapterType&& adapter,
10175                     const parser_callback_t<BasicJsonType> cb = nullptr,
10176                     const bool allow_exceptions_ = true,
10177                     const bool skip_comments = false)
10178         : callback(cb)
10179         , m_lexer(std::move(adapter), skip_comments)
10180         , allow_exceptions(allow_exceptions_)
10181     {
10182         // read first token
10183         get_token();
10184     }
10185 
10186     /*!
10187     @brief public parser interface
10188 
10189     @param[in] strict      whether to expect the last token to be EOF
10190     @param[in,out] result  parsed JSON value
10191 
10192     @throw parse_error.101 in case of an unexpected token
10193     @throw parse_error.102 if to_unicode fails or surrogate error
10194     @throw parse_error.103 if to_unicode fails
10195     */
parse(const bool strict,BasicJsonType & result)10196     void parse(const bool strict, BasicJsonType& result)
10197     {
10198         if (callback)
10199         {
10200             json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10201             sax_parse_internal(&sdp);
10202             result.assert_invariant();
10203 
10204             // in strict mode, input must be completely read
10205             if (strict && (get_token() != token_type::end_of_input))
10206             {
10207                 sdp.parse_error(m_lexer.get_position(),
10208                                 m_lexer.get_token_string(),
10209                                 parse_error::create(101, m_lexer.get_position(),
10210                                                     exception_message(token_type::end_of_input, "value")));
10211             }
10212 
10213             // in case of an error, return discarded value
10214             if (sdp.is_errored())
10215             {
10216                 result = value_t::discarded;
10217                 return;
10218             }
10219 
10220             // set top-level value to null if it was discarded by the callback
10221             // function
10222             if (result.is_discarded())
10223             {
10224                 result = nullptr;
10225             }
10226         }
10227         else
10228         {
10229             json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10230             sax_parse_internal(&sdp);
10231             result.assert_invariant();
10232 
10233             // in strict mode, input must be completely read
10234             if (strict && (get_token() != token_type::end_of_input))
10235             {
10236                 sdp.parse_error(m_lexer.get_position(),
10237                                 m_lexer.get_token_string(),
10238                                 parse_error::create(101, m_lexer.get_position(),
10239                                                     exception_message(token_type::end_of_input, "value")));
10240             }
10241 
10242             // in case of an error, return discarded value
10243             if (sdp.is_errored())
10244             {
10245                 result = value_t::discarded;
10246                 return;
10247             }
10248         }
10249     }
10250 
10251     /*!
10252     @brief public accept interface
10253 
10254     @param[in] strict  whether to expect the last token to be EOF
10255     @return whether the input is a proper JSON text
10256     */
accept(const bool strict=true)10257     bool accept(const bool strict = true)
10258     {
10259         json_sax_acceptor<BasicJsonType> sax_acceptor;
10260         return sax_parse(&sax_acceptor, strict);
10261     }
10262 
10263     template<typename SAX>
10264     JSON_HEDLEY_NON_NULL(2)
sax_parse(SAX * sax,const bool strict=true)10265     bool sax_parse(SAX* sax, const bool strict = true)
10266     {
10267         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10268         const bool result = sax_parse_internal(sax);
10269 
10270         // strict mode: next byte must be EOF
10271         if (result && strict && (get_token() != token_type::end_of_input))
10272         {
10273             return sax->parse_error(m_lexer.get_position(),
10274                                     m_lexer.get_token_string(),
10275                                     parse_error::create(101, m_lexer.get_position(),
10276                                             exception_message(token_type::end_of_input, "value")));
10277         }
10278 
10279         return result;
10280     }
10281 
10282   private:
10283     template<typename SAX>
10284     JSON_HEDLEY_NON_NULL(2)
sax_parse_internal(SAX * sax)10285     bool sax_parse_internal(SAX* sax)
10286     {
10287         // stack to remember the hierarchy of structured values we are parsing
10288         // true = array; false = object
10289         std::vector<bool> states;
10290         // value to avoid a goto (see comment where set to true)
10291         bool skip_to_state_evaluation = false;
10292 
10293         while (true)
10294         {
10295             if (!skip_to_state_evaluation)
10296             {
10297                 // invariant: get_token() was called before each iteration
10298                 switch (last_token)
10299                 {
10300                     case token_type::begin_object:
10301                     {
10302                         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10303                         {
10304                             return false;
10305                         }
10306 
10307                         // closing } -> we are done
10308                         if (get_token() == token_type::end_object)
10309                         {
10310                             if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10311                             {
10312                                 return false;
10313                             }
10314                             break;
10315                         }
10316 
10317                         // parse key
10318                         if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10319                         {
10320                             return sax->parse_error(m_lexer.get_position(),
10321                                                     m_lexer.get_token_string(),
10322                                                     parse_error::create(101, m_lexer.get_position(),
10323                                                             exception_message(token_type::value_string, "object key")));
10324                         }
10325                         if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10326                         {
10327                             return false;
10328                         }
10329 
10330                         // parse separator (:)
10331                         if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10332                         {
10333                             return sax->parse_error(m_lexer.get_position(),
10334                                                     m_lexer.get_token_string(),
10335                                                     parse_error::create(101, m_lexer.get_position(),
10336                                                             exception_message(token_type::name_separator, "object separator")));
10337                         }
10338 
10339                         // remember we are now inside an object
10340                         states.push_back(false);
10341 
10342                         // parse values
10343                         get_token();
10344                         continue;
10345                     }
10346 
10347                     case token_type::begin_array:
10348                     {
10349                         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10350                         {
10351                             return false;
10352                         }
10353 
10354                         // closing ] -> we are done
10355                         if (get_token() == token_type::end_array)
10356                         {
10357                             if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10358                             {
10359                                 return false;
10360                             }
10361                             break;
10362                         }
10363 
10364                         // remember we are now inside an array
10365                         states.push_back(true);
10366 
10367                         // parse values (no need to call get_token)
10368                         continue;
10369                     }
10370 
10371                     case token_type::value_float:
10372                     {
10373                         const auto res = m_lexer.get_number_float();
10374 
10375                         if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10376                         {
10377                             return sax->parse_error(m_lexer.get_position(),
10378                                                     m_lexer.get_token_string(),
10379                                                     out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10380                         }
10381 
10382                         if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10383                         {
10384                             return false;
10385                         }
10386 
10387                         break;
10388                     }
10389 
10390                     case token_type::literal_false:
10391                     {
10392                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10393                         {
10394                             return false;
10395                         }
10396                         break;
10397                     }
10398 
10399                     case token_type::literal_null:
10400                     {
10401                         if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10402                         {
10403                             return false;
10404                         }
10405                         break;
10406                     }
10407 
10408                     case token_type::literal_true:
10409                     {
10410                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10411                         {
10412                             return false;
10413                         }
10414                         break;
10415                     }
10416 
10417                     case token_type::value_integer:
10418                     {
10419                         if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10420                         {
10421                             return false;
10422                         }
10423                         break;
10424                     }
10425 
10426                     case token_type::value_string:
10427                     {
10428                         if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10429                         {
10430                             return false;
10431                         }
10432                         break;
10433                     }
10434 
10435                     case token_type::value_unsigned:
10436                     {
10437                         if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10438                         {
10439                             return false;
10440                         }
10441                         break;
10442                     }
10443 
10444                     case token_type::parse_error:
10445                     {
10446                         // using "uninitialized" to avoid "expected" message
10447                         return sax->parse_error(m_lexer.get_position(),
10448                                                 m_lexer.get_token_string(),
10449                                                 parse_error::create(101, m_lexer.get_position(),
10450                                                         exception_message(token_type::uninitialized, "value")));
10451                     }
10452 
10453                     default: // the last token was unexpected
10454                     {
10455                         return sax->parse_error(m_lexer.get_position(),
10456                                                 m_lexer.get_token_string(),
10457                                                 parse_error::create(101, m_lexer.get_position(),
10458                                                         exception_message(token_type::literal_or_value, "value")));
10459                     }
10460                 }
10461             }
10462             else
10463             {
10464                 skip_to_state_evaluation = false;
10465             }
10466 
10467             // we reached this line after we successfully parsed a value
10468             if (states.empty())
10469             {
10470                 // empty stack: we reached the end of the hierarchy: done
10471                 return true;
10472             }
10473 
10474             if (states.back())  // array
10475             {
10476                 // comma -> next value
10477                 if (get_token() == token_type::value_separator)
10478                 {
10479                     // parse a new value
10480                     get_token();
10481                     continue;
10482                 }
10483 
10484                 // closing ]
10485                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10486                 {
10487                     if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10488                     {
10489                         return false;
10490                     }
10491 
10492                     // We are done with this array. Before we can parse a
10493                     // new value, we need to evaluate the new state first.
10494                     // By setting skip_to_state_evaluation to false, we
10495                     // are effectively jumping to the beginning of this if.
10496                     JSON_ASSERT(!states.empty());
10497                     states.pop_back();
10498                     skip_to_state_evaluation = true;
10499                     continue;
10500                 }
10501 
10502                 return sax->parse_error(m_lexer.get_position(),
10503                                         m_lexer.get_token_string(),
10504                                         parse_error::create(101, m_lexer.get_position(),
10505                                                 exception_message(token_type::end_array, "array")));
10506             }
10507             else  // object
10508             {
10509                 // comma -> next value
10510                 if (get_token() == token_type::value_separator)
10511                 {
10512                     // parse key
10513                     if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10514                     {
10515                         return sax->parse_error(m_lexer.get_position(),
10516                                                 m_lexer.get_token_string(),
10517                                                 parse_error::create(101, m_lexer.get_position(),
10518                                                         exception_message(token_type::value_string, "object key")));
10519                     }
10520 
10521                     if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10522                     {
10523                         return false;
10524                     }
10525 
10526                     // parse separator (:)
10527                     if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10528                     {
10529                         return sax->parse_error(m_lexer.get_position(),
10530                                                 m_lexer.get_token_string(),
10531                                                 parse_error::create(101, m_lexer.get_position(),
10532                                                         exception_message(token_type::name_separator, "object separator")));
10533                     }
10534 
10535                     // parse values
10536                     get_token();
10537                     continue;
10538                 }
10539 
10540                 // closing }
10541                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10542                 {
10543                     if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10544                     {
10545                         return false;
10546                     }
10547 
10548                     // We are done with this object. Before we can parse a
10549                     // new value, we need to evaluate the new state first.
10550                     // By setting skip_to_state_evaluation to false, we
10551                     // are effectively jumping to the beginning of this if.
10552                     JSON_ASSERT(!states.empty());
10553                     states.pop_back();
10554                     skip_to_state_evaluation = true;
10555                     continue;
10556                 }
10557 
10558                 return sax->parse_error(m_lexer.get_position(),
10559                                         m_lexer.get_token_string(),
10560                                         parse_error::create(101, m_lexer.get_position(),
10561                                                 exception_message(token_type::end_object, "object")));
10562             }
10563         }
10564     }
10565 
10566     /// get next token from lexer
get_token()10567     token_type get_token()
10568     {
10569         return last_token = m_lexer.scan();
10570     }
10571 
exception_message(const token_type expected,const std::string & context)10572     std::string exception_message(const token_type expected, const std::string& context)
10573     {
10574         std::string error_msg = "syntax error ";
10575 
10576         if (!context.empty())
10577         {
10578             error_msg += "while parsing " + context + " ";
10579         }
10580 
10581         error_msg += "- ";
10582 
10583         if (last_token == token_type::parse_error)
10584         {
10585             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10586                          m_lexer.get_token_string() + "'";
10587         }
10588         else
10589         {
10590             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10591         }
10592 
10593         if (expected != token_type::uninitialized)
10594         {
10595             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10596         }
10597 
10598         return error_msg;
10599     }
10600 
10601   private:
10602     /// callback function
10603     const parser_callback_t<BasicJsonType> callback = nullptr;
10604     /// the type of the last read token
10605     token_type last_token = token_type::uninitialized;
10606     /// the lexer
10607     lexer_t m_lexer;
10608     /// whether to throw exceptions in case of errors
10609     const bool allow_exceptions = true;
10610 };
10611 }  // namespace detail
10612 }  // namespace nlohmann
10613 
10614 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10615 
10616 
10617 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10618 
10619 
10620 #include <cstddef> // ptrdiff_t
10621 #include <limits>  // numeric_limits
10622 
10623 namespace nlohmann
10624 {
10625 namespace detail
10626 {
10627 /*
10628 @brief an iterator for primitive JSON types
10629 
10630 This class models an iterator for primitive JSON types (boolean, number,
10631 string). It's only purpose is to allow the iterator/const_iterator classes
10632 to "iterate" over primitive values. Internally, the iterator is modeled by
10633 a `difference_type` variable. Value begin_value (`0`) models the begin,
10634 end_value (`1`) models past the end.
10635 */
10636 class primitive_iterator_t
10637 {
10638   private:
10639     using difference_type = std::ptrdiff_t;
10640     static constexpr difference_type begin_value = 0;
10641     static constexpr difference_type end_value = begin_value + 1;
10642 
10643     /// iterator as signed integer type
10644     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10645 
10646   public:
get_value() const10647     constexpr difference_type get_value() const noexcept
10648     {
10649         return m_it;
10650     }
10651 
10652     /// set iterator to a defined beginning
set_begin()10653     void set_begin() noexcept
10654     {
10655         m_it = begin_value;
10656     }
10657 
10658     /// set iterator to a defined past the end
set_end()10659     void set_end() noexcept
10660     {
10661         m_it = end_value;
10662     }
10663 
10664     /// return whether the iterator can be dereferenced
is_begin() const10665     constexpr bool is_begin() const noexcept
10666     {
10667         return m_it == begin_value;
10668     }
10669 
10670     /// return whether the iterator is at end
is_end() const10671     constexpr bool is_end() const noexcept
10672     {
10673         return m_it == end_value;
10674     }
10675 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)10676     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10677     {
10678         return lhs.m_it == rhs.m_it;
10679     }
10680 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)10681     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10682     {
10683         return lhs.m_it < rhs.m_it;
10684     }
10685 
operator +(difference_type n)10686     primitive_iterator_t operator+(difference_type n) noexcept
10687     {
10688         auto result = *this;
10689         result += n;
10690         return result;
10691     }
10692 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)10693     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10694     {
10695         return lhs.m_it - rhs.m_it;
10696     }
10697 
operator ++()10698     primitive_iterator_t& operator++() noexcept
10699     {
10700         ++m_it;
10701         return *this;
10702     }
10703 
operator ++(int)10704     primitive_iterator_t const operator++(int) noexcept
10705     {
10706         auto result = *this;
10707         ++m_it;
10708         return result;
10709     }
10710 
operator --()10711     primitive_iterator_t& operator--() noexcept
10712     {
10713         --m_it;
10714         return *this;
10715     }
10716 
operator --(int)10717     primitive_iterator_t const operator--(int) noexcept
10718     {
10719         auto result = *this;
10720         --m_it;
10721         return result;
10722     }
10723 
operator +=(difference_type n)10724     primitive_iterator_t& operator+=(difference_type n) noexcept
10725     {
10726         m_it += n;
10727         return *this;
10728     }
10729 
operator -=(difference_type n)10730     primitive_iterator_t& operator-=(difference_type n) noexcept
10731     {
10732         m_it -= n;
10733         return *this;
10734     }
10735 };
10736 }  // namespace detail
10737 }  // namespace nlohmann
10738 
10739 
10740 namespace nlohmann
10741 {
10742 namespace detail
10743 {
10744 /*!
10745 @brief an iterator value
10746 
10747 @note This structure could easily be a union, but MSVC currently does not allow
10748 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
10749 */
10750 template<typename BasicJsonType> struct internal_iterator
10751 {
10752     /// iterator for JSON objects
10753     typename BasicJsonType::object_t::iterator object_iterator {};
10754     /// iterator for JSON arrays
10755     typename BasicJsonType::array_t::iterator array_iterator {};
10756     /// generic iterator for all other types
10757     primitive_iterator_t primitive_iterator {};
10758 };
10759 }  // namespace detail
10760 }  // namespace nlohmann
10761 
10762 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10763 
10764 
10765 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10766 #include <type_traits> // conditional, is_const, remove_const
10767 
10768 // #include <nlohmann/detail/exceptions.hpp>
10769 
10770 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10771 
10772 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10773 
10774 // #include <nlohmann/detail/macro_scope.hpp>
10775 
10776 // #include <nlohmann/detail/meta/cpp_future.hpp>
10777 
10778 // #include <nlohmann/detail/meta/type_traits.hpp>
10779 
10780 // #include <nlohmann/detail/value_t.hpp>
10781 
10782 
10783 namespace nlohmann
10784 {
10785 namespace detail
10786 {
10787 // forward declare, to be able to friend it later on
10788 template<typename IteratorType> class iteration_proxy;
10789 template<typename IteratorType> class iteration_proxy_value;
10790 
10791 /*!
10792 @brief a template for a bidirectional iterator for the @ref basic_json class
10793 This class implements a both iterators (iterator and const_iterator) for the
10794 @ref basic_json class.
10795 @note An iterator is called *initialized* when a pointer to a JSON value has
10796       been set (e.g., by a constructor or a copy assignment). If the iterator is
10797       default-constructed, it is *uninitialized* and most methods are undefined.
10798       **The library uses assertions to detect calls on uninitialized iterators.**
10799 @requirement The class satisfies the following concept requirements:
10800 -
10801 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
10802   The iterator that can be moved can be moved in both directions (i.e.
10803   incremented and decremented).
10804 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
10805        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
10806 */
10807 template<typename BasicJsonType>
10808 class iter_impl
10809 {
10810     /// allow basic_json to access private members
10811     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10812     friend BasicJsonType;
10813     friend iteration_proxy<iter_impl>;
10814     friend iteration_proxy_value<iter_impl>;
10815 
10816     using object_t = typename BasicJsonType::object_t;
10817     using array_t = typename BasicJsonType::array_t;
10818     // make sure BasicJsonType is basic_json or const basic_json
10819     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10820                   "iter_impl only accepts (const) basic_json");
10821 
10822   public:
10823 
10824     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
10825     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
10826     /// A user-defined iterator should provide publicly accessible typedefs named
10827     /// iterator_category, value_type, difference_type, pointer, and reference.
10828     /// Note that value_type is required to be non-const, even for constant iterators.
10829     using iterator_category = std::bidirectional_iterator_tag;
10830 
10831     /// the type of the values when the iterator is dereferenced
10832     using value_type = typename BasicJsonType::value_type;
10833     /// a type to represent differences between iterators
10834     using difference_type = typename BasicJsonType::difference_type;
10835     /// defines a pointer to the type iterated over (value_type)
10836     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10837           typename BasicJsonType::const_pointer,
10838           typename BasicJsonType::pointer>::type;
10839     /// defines a reference to the type iterated over (value_type)
10840     using reference =
10841         typename std::conditional<std::is_const<BasicJsonType>::value,
10842         typename BasicJsonType::const_reference,
10843         typename BasicJsonType::reference>::type;
10844 
10845     /// default constructor
10846     iter_impl() = default;
10847 
10848     /*!
10849     @brief constructor for a given JSON instance
10850     @param[in] object  pointer to a JSON object for this iterator
10851     @pre object != nullptr
10852     @post The iterator is initialized; i.e. `m_object != nullptr`.
10853     */
iter_impl(pointer object)10854     explicit iter_impl(pointer object) noexcept : m_object(object)
10855     {
10856         JSON_ASSERT(m_object != nullptr);
10857 
10858         switch (m_object->m_type)
10859         {
10860             case value_t::object:
10861             {
10862                 m_it.object_iterator = typename object_t::iterator();
10863                 break;
10864             }
10865 
10866             case value_t::array:
10867             {
10868                 m_it.array_iterator = typename array_t::iterator();
10869                 break;
10870             }
10871 
10872             default:
10873             {
10874                 m_it.primitive_iterator = primitive_iterator_t();
10875                 break;
10876             }
10877         }
10878     }
10879 
10880     /*!
10881     @note The conventional copy constructor and copy assignment are implicitly
10882           defined. Combined with the following converting constructor and
10883           assignment, they support: (1) copy from iterator to iterator, (2)
10884           copy from const iterator to const iterator, and (3) conversion from
10885           iterator to const iterator. However conversion from const iterator
10886           to iterator is not defined.
10887     */
10888 
10889     /*!
10890     @brief const copy constructor
10891     @param[in] other const iterator to copy from
10892     @note This copy constructor had to be defined explicitly to circumvent a bug
10893           occurring on msvc v19.0 compiler (VS 2015) debug build. For more
10894           information refer to: https://github.com/nlohmann/json/issues/1608
10895     */
iter_impl(const iter_impl<const BasicJsonType> & other)10896     iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10897         : m_object(other.m_object), m_it(other.m_it)
10898     {}
10899 
10900     /*!
10901     @brief converting assignment
10902     @param[in] other const iterator to copy from
10903     @return const/non-const iterator
10904     @note It is not checked whether @a other is initialized.
10905     */
operator =(const iter_impl<const BasicJsonType> & other)10906     iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10907     {
10908         m_object = other.m_object;
10909         m_it = other.m_it;
10910         return *this;
10911     }
10912 
10913     /*!
10914     @brief converting constructor
10915     @param[in] other  non-const iterator to copy from
10916     @note It is not checked whether @a other is initialized.
10917     */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)10918     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10919         : m_object(other.m_object), m_it(other.m_it)
10920     {}
10921 
10922     /*!
10923     @brief converting assignment
10924     @param[in] other  non-const iterator to copy from
10925     @return const/non-const iterator
10926     @note It is not checked whether @a other is initialized.
10927     */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)10928     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10929     {
10930         m_object = other.m_object;
10931         m_it = other.m_it;
10932         return *this;
10933     }
10934 
10935   private:
10936     /*!
10937     @brief set the iterator to the first value
10938     @pre The iterator is initialized; i.e. `m_object != nullptr`.
10939     */
set_begin()10940     void set_begin() noexcept
10941     {
10942         JSON_ASSERT(m_object != nullptr);
10943 
10944         switch (m_object->m_type)
10945         {
10946             case value_t::object:
10947             {
10948                 m_it.object_iterator = m_object->m_value.object->begin();
10949                 break;
10950             }
10951 
10952             case value_t::array:
10953             {
10954                 m_it.array_iterator = m_object->m_value.array->begin();
10955                 break;
10956             }
10957 
10958             case value_t::null:
10959             {
10960                 // set to end so begin()==end() is true: null is empty
10961                 m_it.primitive_iterator.set_end();
10962                 break;
10963             }
10964 
10965             default:
10966             {
10967                 m_it.primitive_iterator.set_begin();
10968                 break;
10969             }
10970         }
10971     }
10972 
10973     /*!
10974     @brief set the iterator past the last value
10975     @pre The iterator is initialized; i.e. `m_object != nullptr`.
10976     */
set_end()10977     void set_end() noexcept
10978     {
10979         JSON_ASSERT(m_object != nullptr);
10980 
10981         switch (m_object->m_type)
10982         {
10983             case value_t::object:
10984             {
10985                 m_it.object_iterator = m_object->m_value.object->end();
10986                 break;
10987             }
10988 
10989             case value_t::array:
10990             {
10991                 m_it.array_iterator = m_object->m_value.array->end();
10992                 break;
10993             }
10994 
10995             default:
10996             {
10997                 m_it.primitive_iterator.set_end();
10998                 break;
10999             }
11000         }
11001     }
11002 
11003   public:
11004     /*!
11005     @brief return a reference to the value pointed to by the iterator
11006     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11007     */
operator *() const11008     reference operator*() const
11009     {
11010         JSON_ASSERT(m_object != nullptr);
11011 
11012         switch (m_object->m_type)
11013         {
11014             case value_t::object:
11015             {
11016                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11017                 return m_it.object_iterator->second;
11018             }
11019 
11020             case value_t::array:
11021             {
11022                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11023                 return *m_it.array_iterator;
11024             }
11025 
11026             case value_t::null:
11027                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11028 
11029             default:
11030             {
11031                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11032                 {
11033                     return *m_object;
11034                 }
11035 
11036                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11037             }
11038         }
11039     }
11040 
11041     /*!
11042     @brief dereference the iterator
11043     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11044     */
operator ->() const11045     pointer operator->() const
11046     {
11047         JSON_ASSERT(m_object != nullptr);
11048 
11049         switch (m_object->m_type)
11050         {
11051             case value_t::object:
11052             {
11053                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11054                 return &(m_it.object_iterator->second);
11055             }
11056 
11057             case value_t::array:
11058             {
11059                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11060                 return &*m_it.array_iterator;
11061             }
11062 
11063             default:
11064             {
11065                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11066                 {
11067                     return m_object;
11068                 }
11069 
11070                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11071             }
11072         }
11073     }
11074 
11075     /*!
11076     @brief post-increment (it++)
11077     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11078     */
operator ++(int)11079     iter_impl const operator++(int)
11080     {
11081         auto result = *this;
11082         ++(*this);
11083         return result;
11084     }
11085 
11086     /*!
11087     @brief pre-increment (++it)
11088     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11089     */
operator ++()11090     iter_impl& operator++()
11091     {
11092         JSON_ASSERT(m_object != nullptr);
11093 
11094         switch (m_object->m_type)
11095         {
11096             case value_t::object:
11097             {
11098                 std::advance(m_it.object_iterator, 1);
11099                 break;
11100             }
11101 
11102             case value_t::array:
11103             {
11104                 std::advance(m_it.array_iterator, 1);
11105                 break;
11106             }
11107 
11108             default:
11109             {
11110                 ++m_it.primitive_iterator;
11111                 break;
11112             }
11113         }
11114 
11115         return *this;
11116     }
11117 
11118     /*!
11119     @brief post-decrement (it--)
11120     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11121     */
operator --(int)11122     iter_impl const operator--(int)
11123     {
11124         auto result = *this;
11125         --(*this);
11126         return result;
11127     }
11128 
11129     /*!
11130     @brief pre-decrement (--it)
11131     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11132     */
operator --()11133     iter_impl& operator--()
11134     {
11135         JSON_ASSERT(m_object != nullptr);
11136 
11137         switch (m_object->m_type)
11138         {
11139             case value_t::object:
11140             {
11141                 std::advance(m_it.object_iterator, -1);
11142                 break;
11143             }
11144 
11145             case value_t::array:
11146             {
11147                 std::advance(m_it.array_iterator, -1);
11148                 break;
11149             }
11150 
11151             default:
11152             {
11153                 --m_it.primitive_iterator;
11154                 break;
11155             }
11156         }
11157 
11158         return *this;
11159     }
11160 
11161     /*!
11162     @brief  comparison: equal
11163     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11164     */
operator ==(const iter_impl & other) const11165     bool operator==(const iter_impl& other) const
11166     {
11167         // if objects are not the same, the comparison is undefined
11168         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11169         {
11170             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11171         }
11172 
11173         JSON_ASSERT(m_object != nullptr);
11174 
11175         switch (m_object->m_type)
11176         {
11177             case value_t::object:
11178                 return (m_it.object_iterator == other.m_it.object_iterator);
11179 
11180             case value_t::array:
11181                 return (m_it.array_iterator == other.m_it.array_iterator);
11182 
11183             default:
11184                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11185         }
11186     }
11187 
11188     /*!
11189     @brief  comparison: not equal
11190     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11191     */
operator !=(const iter_impl & other) const11192     bool operator!=(const iter_impl& other) const
11193     {
11194         return !operator==(other);
11195     }
11196 
11197     /*!
11198     @brief  comparison: smaller
11199     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11200     */
operator <(const iter_impl & other) const11201     bool operator<(const iter_impl& other) const
11202     {
11203         // if objects are not the same, the comparison is undefined
11204         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11205         {
11206             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11207         }
11208 
11209         JSON_ASSERT(m_object != nullptr);
11210 
11211         switch (m_object->m_type)
11212         {
11213             case value_t::object:
11214                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11215 
11216             case value_t::array:
11217                 return (m_it.array_iterator < other.m_it.array_iterator);
11218 
11219             default:
11220                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11221         }
11222     }
11223 
11224     /*!
11225     @brief  comparison: less than or equal
11226     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11227     */
operator <=(const iter_impl & other) const11228     bool operator<=(const iter_impl& other) const
11229     {
11230         return !other.operator < (*this);
11231     }
11232 
11233     /*!
11234     @brief  comparison: greater than
11235     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11236     */
operator >(const iter_impl & other) const11237     bool operator>(const iter_impl& other) const
11238     {
11239         return !operator<=(other);
11240     }
11241 
11242     /*!
11243     @brief  comparison: greater than or equal
11244     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11245     */
operator >=(const iter_impl & other) const11246     bool operator>=(const iter_impl& other) const
11247     {
11248         return !operator<(other);
11249     }
11250 
11251     /*!
11252     @brief  add to iterator
11253     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11254     */
operator +=(difference_type i)11255     iter_impl& operator+=(difference_type i)
11256     {
11257         JSON_ASSERT(m_object != nullptr);
11258 
11259         switch (m_object->m_type)
11260         {
11261             case value_t::object:
11262                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11263 
11264             case value_t::array:
11265             {
11266                 std::advance(m_it.array_iterator, i);
11267                 break;
11268             }
11269 
11270             default:
11271             {
11272                 m_it.primitive_iterator += i;
11273                 break;
11274             }
11275         }
11276 
11277         return *this;
11278     }
11279 
11280     /*!
11281     @brief  subtract from iterator
11282     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11283     */
operator -=(difference_type i)11284     iter_impl& operator-=(difference_type i)
11285     {
11286         return operator+=(-i);
11287     }
11288 
11289     /*!
11290     @brief  add to iterator
11291     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11292     */
operator +(difference_type i) const11293     iter_impl operator+(difference_type i) const
11294     {
11295         auto result = *this;
11296         result += i;
11297         return result;
11298     }
11299 
11300     /*!
11301     @brief  addition of distance and iterator
11302     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11303     */
operator +(difference_type i,const iter_impl & it)11304     friend iter_impl operator+(difference_type i, const iter_impl& it)
11305     {
11306         auto result = it;
11307         result += i;
11308         return result;
11309     }
11310 
11311     /*!
11312     @brief  subtract from iterator
11313     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11314     */
operator -(difference_type i) const11315     iter_impl operator-(difference_type i) const
11316     {
11317         auto result = *this;
11318         result -= i;
11319         return result;
11320     }
11321 
11322     /*!
11323     @brief  return difference
11324     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11325     */
operator -(const iter_impl & other) const11326     difference_type operator-(const iter_impl& other) const
11327     {
11328         JSON_ASSERT(m_object != nullptr);
11329 
11330         switch (m_object->m_type)
11331         {
11332             case value_t::object:
11333                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11334 
11335             case value_t::array:
11336                 return m_it.array_iterator - other.m_it.array_iterator;
11337 
11338             default:
11339                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
11340         }
11341     }
11342 
11343     /*!
11344     @brief  access to successor
11345     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11346     */
operator [](difference_type n) const11347     reference operator[](difference_type n) const
11348     {
11349         JSON_ASSERT(m_object != nullptr);
11350 
11351         switch (m_object->m_type)
11352         {
11353             case value_t::object:
11354                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11355 
11356             case value_t::array:
11357                 return *std::next(m_it.array_iterator, n);
11358 
11359             case value_t::null:
11360                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11361 
11362             default:
11363             {
11364                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11365                 {
11366                     return *m_object;
11367                 }
11368 
11369                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11370             }
11371         }
11372     }
11373 
11374     /*!
11375     @brief  return the key of an object iterator
11376     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11377     */
key() const11378     const typename object_t::key_type& key() const
11379     {
11380         JSON_ASSERT(m_object != nullptr);
11381 
11382         if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11383         {
11384             return m_it.object_iterator->first;
11385         }
11386 
11387         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11388     }
11389 
11390     /*!
11391     @brief  return the value of an iterator
11392     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11393     */
value() const11394     reference value() const
11395     {
11396         return operator*();
11397     }
11398 
11399   private:
11400     /// associated JSON instance
11401     pointer m_object = nullptr;
11402     /// the actual iterator of the associated instance
11403     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11404 };
11405 } // namespace detail
11406 } // namespace nlohmann
11407 
11408 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11409 
11410 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11411 
11412 
11413 #include <cstddef> // ptrdiff_t
11414 #include <iterator> // reverse_iterator
11415 #include <utility> // declval
11416 
11417 namespace nlohmann
11418 {
11419 namespace detail
11420 {
11421 //////////////////////
11422 // reverse_iterator //
11423 //////////////////////
11424 
11425 /*!
11426 @brief a template for a reverse iterator class
11427 
11428 @tparam Base the base iterator type to reverse. Valid types are @ref
11429 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
11430 create @ref const_reverse_iterator).
11431 
11432 @requirement The class satisfies the following concept requirements:
11433 -
11434 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11435   The iterator that can be moved can be moved in both directions (i.e.
11436   incremented and decremented).
11437 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
11438   It is possible to write to the pointed-to element (only if @a Base is
11439   @ref iterator).
11440 
11441 @since version 1.0.0
11442 */
11443 template<typename Base>
11444 class json_reverse_iterator : public std::reverse_iterator<Base>
11445 {
11446   public:
11447     using difference_type = std::ptrdiff_t;
11448     /// shortcut to the reverse iterator adapter
11449     using base_iterator = std::reverse_iterator<Base>;
11450     /// the reference type for the pointed-to element
11451     using reference = typename Base::reference;
11452 
11453     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)11454     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11455         : base_iterator(it) {}
11456 
11457     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)11458     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11459 
11460     /// post-increment (it++)
operator ++(int)11461     json_reverse_iterator const operator++(int)
11462     {
11463         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11464     }
11465 
11466     /// pre-increment (++it)
operator ++()11467     json_reverse_iterator& operator++()
11468     {
11469         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11470     }
11471 
11472     /// post-decrement (it--)
operator --(int)11473     json_reverse_iterator const operator--(int)
11474     {
11475         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11476     }
11477 
11478     /// pre-decrement (--it)
operator --()11479     json_reverse_iterator& operator--()
11480     {
11481         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11482     }
11483 
11484     /// add to iterator
operator +=(difference_type i)11485     json_reverse_iterator& operator+=(difference_type i)
11486     {
11487         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11488     }
11489 
11490     /// add to iterator
operator +(difference_type i) const11491     json_reverse_iterator operator+(difference_type i) const
11492     {
11493         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11494     }
11495 
11496     /// subtract from iterator
operator -(difference_type i) const11497     json_reverse_iterator operator-(difference_type i) const
11498     {
11499         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11500     }
11501 
11502     /// return difference
operator -(const json_reverse_iterator & other) const11503     difference_type operator-(const json_reverse_iterator& other) const
11504     {
11505         return base_iterator(*this) - base_iterator(other);
11506     }
11507 
11508     /// access to successor
operator [](difference_type n) const11509     reference operator[](difference_type n) const
11510     {
11511         return *(this->operator+(n));
11512     }
11513 
11514     /// return the key of an object iterator
key() const11515     auto key() const -> decltype(std::declval<Base>().key())
11516     {
11517         auto it = --this->base();
11518         return it.key();
11519     }
11520 
11521     /// return the value of an iterator
value() const11522     reference value() const
11523     {
11524         auto it = --this->base();
11525         return it.operator * ();
11526     }
11527 };
11528 }  // namespace detail
11529 }  // namespace nlohmann
11530 
11531 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11532 
11533 // #include <nlohmann/detail/json_pointer.hpp>
11534 
11535 
11536 #include <algorithm> // all_of
11537 #include <cctype> // isdigit
11538 #include <limits> // max
11539 #include <numeric> // accumulate
11540 #include <string> // string
11541 #include <utility> // move
11542 #include <vector> // vector
11543 
11544 // #include <nlohmann/detail/exceptions.hpp>
11545 
11546 // #include <nlohmann/detail/macro_scope.hpp>
11547 
11548 // #include <nlohmann/detail/value_t.hpp>
11549 
11550 
11551 namespace nlohmann
11552 {
11553 template<typename BasicJsonType>
11554 class json_pointer
11555 {
11556     // allow basic_json to access private members
11557     NLOHMANN_BASIC_JSON_TPL_DECLARATION
11558     friend class basic_json;
11559 
11560   public:
11561     /*!
11562     @brief create JSON pointer
11563 
11564     Create a JSON pointer according to the syntax described in
11565     [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
11566 
11567     @param[in] s  string representing the JSON pointer; if omitted, the empty
11568                   string is assumed which references the whole JSON value
11569 
11570     @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
11571                            not begin with a slash (`/`); see example below
11572 
11573     @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
11574     not followed by `0` (representing `~`) or `1` (representing `/`); see
11575     example below
11576 
11577     @liveexample{The example shows the construction several valid JSON pointers
11578     as well as the exceptional behavior.,json_pointer}
11579 
11580     @since version 2.0.0
11581     */
json_pointer(const std::string & s="")11582     explicit json_pointer(const std::string& s = "")
11583         : reference_tokens(split(s))
11584     {}
11585 
11586     /*!
11587     @brief return a string representation of the JSON pointer
11588 
11589     @invariant For each JSON pointer `ptr`, it holds:
11590     @code {.cpp}
11591     ptr == json_pointer(ptr.to_string());
11592     @endcode
11593 
11594     @return a string representation of the JSON pointer
11595 
11596     @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
11597 
11598     @since version 2.0.0
11599     */
to_string() const11600     std::string to_string() const
11601     {
11602         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11603                                std::string{},
11604                                [](const std::string & a, const std::string & b)
11605         {
11606             return a + "/" + escape(b);
11607         });
11608     }
11609 
11610     /// @copydoc to_string()
operator std::string() const11611     operator std::string() const
11612     {
11613         return to_string();
11614     }
11615 
11616     /*!
11617     @brief append another JSON pointer at the end of this JSON pointer
11618 
11619     @param[in] ptr  JSON pointer to append
11620     @return JSON pointer with @a ptr appended
11621 
11622     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11623 
11624     @complexity Linear in the length of @a ptr.
11625 
11626     @sa @ref operator/=(std::string) to append a reference token
11627     @sa @ref operator/=(std::size_t) to append an array index
11628     @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
11629 
11630     @since version 3.6.0
11631     */
operator /=(const json_pointer & ptr)11632     json_pointer& operator/=(const json_pointer& ptr)
11633     {
11634         reference_tokens.insert(reference_tokens.end(),
11635                                 ptr.reference_tokens.begin(),
11636                                 ptr.reference_tokens.end());
11637         return *this;
11638     }
11639 
11640     /*!
11641     @brief append an unescaped reference token at the end of this JSON pointer
11642 
11643     @param[in] token  reference token to append
11644     @return JSON pointer with @a token appended without escaping @a token
11645 
11646     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11647 
11648     @complexity Amortized constant.
11649 
11650     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11651     @sa @ref operator/=(std::size_t) to append an array index
11652     @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
11653 
11654     @since version 3.6.0
11655     */
operator /=(std::string token)11656     json_pointer& operator/=(std::string token)
11657     {
11658         push_back(std::move(token));
11659         return *this;
11660     }
11661 
11662     /*!
11663     @brief append an array index at the end of this JSON pointer
11664 
11665     @param[in] array_idx  array index to append
11666     @return JSON pointer with @a array_idx appended
11667 
11668     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11669 
11670     @complexity Amortized constant.
11671 
11672     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11673     @sa @ref operator/=(std::string) to append a reference token
11674     @sa @ref operator/(const json_pointer&, std::string) for a binary operator
11675 
11676     @since version 3.6.0
11677     */
operator /=(std::size_t array_idx)11678     json_pointer& operator/=(std::size_t array_idx)
11679     {
11680         return *this /= std::to_string(array_idx);
11681     }
11682 
11683     /*!
11684     @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
11685 
11686     @param[in] lhs  JSON pointer
11687     @param[in] rhs  JSON pointer
11688     @return a new JSON pointer with @a rhs appended to @a lhs
11689 
11690     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11691 
11692     @complexity Linear in the length of @a lhs and @a rhs.
11693 
11694     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11695 
11696     @since version 3.6.0
11697     */
operator /(const json_pointer & lhs,const json_pointer & rhs)11698     friend json_pointer operator/(const json_pointer& lhs,
11699                                   const json_pointer& rhs)
11700     {
11701         return json_pointer(lhs) /= rhs;
11702     }
11703 
11704     /*!
11705     @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
11706 
11707     @param[in] ptr  JSON pointer
11708     @param[in] token  reference token
11709     @return a new JSON pointer with unescaped @a token appended to @a ptr
11710 
11711     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11712 
11713     @complexity Linear in the length of @a ptr.
11714 
11715     @sa @ref operator/=(std::string) to append a reference token
11716 
11717     @since version 3.6.0
11718     */
operator /(const json_pointer & ptr,std::string token)11719     friend json_pointer operator/(const json_pointer& ptr, std::string token)
11720     {
11721         return json_pointer(ptr) /= std::move(token);
11722     }
11723 
11724     /*!
11725     @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
11726 
11727     @param[in] ptr  JSON pointer
11728     @param[in] array_idx  array index
11729     @return a new JSON pointer with @a array_idx appended to @a ptr
11730 
11731     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11732 
11733     @complexity Linear in the length of @a ptr.
11734 
11735     @sa @ref operator/=(std::size_t) to append an array index
11736 
11737     @since version 3.6.0
11738     */
operator /(const json_pointer & ptr,std::size_t array_idx)11739     friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11740     {
11741         return json_pointer(ptr) /= array_idx;
11742     }
11743 
11744     /*!
11745     @brief returns the parent of this JSON pointer
11746 
11747     @return parent of this JSON pointer; in case this JSON pointer is the root,
11748             the root itself is returned
11749 
11750     @complexity Linear in the length of the JSON pointer.
11751 
11752     @liveexample{The example shows the result of `parent_pointer` for different
11753     JSON Pointers.,json_pointer__parent_pointer}
11754 
11755     @since version 3.6.0
11756     */
parent_pointer() const11757     json_pointer parent_pointer() const
11758     {
11759         if (empty())
11760         {
11761             return *this;
11762         }
11763 
11764         json_pointer res = *this;
11765         res.pop_back();
11766         return res;
11767     }
11768 
11769     /*!
11770     @brief remove last reference token
11771 
11772     @pre not `empty()`
11773 
11774     @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
11775 
11776     @complexity Constant.
11777 
11778     @throw out_of_range.405 if JSON pointer has no parent
11779 
11780     @since version 3.6.0
11781     */
pop_back()11782     void pop_back()
11783     {
11784         if (JSON_HEDLEY_UNLIKELY(empty()))
11785         {
11786             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11787         }
11788 
11789         reference_tokens.pop_back();
11790     }
11791 
11792     /*!
11793     @brief return last reference token
11794 
11795     @pre not `empty()`
11796     @return last reference token
11797 
11798     @liveexample{The example shows the usage of `back`.,json_pointer__back}
11799 
11800     @complexity Constant.
11801 
11802     @throw out_of_range.405 if JSON pointer has no parent
11803 
11804     @since version 3.6.0
11805     */
back() const11806     const std::string& back() const
11807     {
11808         if (JSON_HEDLEY_UNLIKELY(empty()))
11809         {
11810             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11811         }
11812 
11813         return reference_tokens.back();
11814     }
11815 
11816     /*!
11817     @brief append an unescaped token at the end of the reference pointer
11818 
11819     @param[in] token  token to add
11820 
11821     @complexity Amortized constant.
11822 
11823     @liveexample{The example shows the result of `push_back` for different
11824     JSON Pointers.,json_pointer__push_back}
11825 
11826     @since version 3.6.0
11827     */
push_back(const std::string & token)11828     void push_back(const std::string& token)
11829     {
11830         reference_tokens.push_back(token);
11831     }
11832 
11833     /// @copydoc push_back(const std::string&)
push_back(std::string && token)11834     void push_back(std::string&& token)
11835     {
11836         reference_tokens.push_back(std::move(token));
11837     }
11838 
11839     /*!
11840     @brief return whether pointer points to the root document
11841 
11842     @return true iff the JSON pointer points to the root document
11843 
11844     @complexity Constant.
11845 
11846     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11847 
11848     @liveexample{The example shows the result of `empty` for different JSON
11849     Pointers.,json_pointer__empty}
11850 
11851     @since version 3.6.0
11852     */
empty() const11853     bool empty() const noexcept
11854     {
11855         return reference_tokens.empty();
11856     }
11857 
11858   private:
11859     /*!
11860     @param[in] s  reference token to be converted into an array index
11861 
11862     @return integer representation of @a s
11863 
11864     @throw parse_error.106  if an array index begins with '0'
11865     @throw parse_error.109  if an array index begins not with a digit
11866     @throw out_of_range.404 if string @a s could not be converted to an integer
11867     @throw out_of_range.410 if an array index exceeds size_type
11868     */
array_index(const std::string & s)11869     static typename BasicJsonType::size_type array_index(const std::string& s)
11870     {
11871         using size_type = typename BasicJsonType::size_type;
11872 
11873         // error condition (cf. RFC 6901, Sect. 4)
11874         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11875         {
11876             JSON_THROW(detail::parse_error::create(106, 0,
11877                                                    "array index '" + s +
11878                                                    "' must not begin with '0'"));
11879         }
11880 
11881         // error condition (cf. RFC 6901, Sect. 4)
11882         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11883         {
11884             JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11885         }
11886 
11887         std::size_t processed_chars = 0;
11888         unsigned long long res = 0;
11889         JSON_TRY
11890         {
11891             res = std::stoull(s, &processed_chars);
11892         }
11893         JSON_CATCH(std::out_of_range&)
11894         {
11895             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11896         }
11897 
11898         // check if the string was completely read
11899         if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11900         {
11901             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11902         }
11903 
11904         // only triggered on special platforms (like 32bit), see also
11905         // https://github.com/nlohmann/json/pull/2203
11906         if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11907         {
11908             JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11909         }
11910 
11911         return static_cast<size_type>(res);
11912     }
11913 
top() const11914     json_pointer top() const
11915     {
11916         if (JSON_HEDLEY_UNLIKELY(empty()))
11917         {
11918             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11919         }
11920 
11921         json_pointer result = *this;
11922         result.reference_tokens = {reference_tokens[0]};
11923         return result;
11924     }
11925 
11926     /*!
11927     @brief create and return a reference to the pointed to value
11928 
11929     @complexity Linear in the number of reference tokens.
11930 
11931     @throw parse_error.109 if array index is not a number
11932     @throw type_error.313 if value cannot be unflattened
11933     */
get_and_create(BasicJsonType & j) const11934     BasicJsonType& get_and_create(BasicJsonType& j) const
11935     {
11936         auto result = &j;
11937 
11938         // in case no reference tokens exist, return a reference to the JSON value
11939         // j which will be overwritten by a primitive value
11940         for (const auto& reference_token : reference_tokens)
11941         {
11942             switch (result->type())
11943             {
11944                 case detail::value_t::null:
11945                 {
11946                     if (reference_token == "0")
11947                     {
11948                         // start a new array if reference token is 0
11949                         result = &result->operator[](0);
11950                     }
11951                     else
11952                     {
11953                         // start a new object otherwise
11954                         result = &result->operator[](reference_token);
11955                     }
11956                     break;
11957                 }
11958 
11959                 case detail::value_t::object:
11960                 {
11961                     // create an entry in the object
11962                     result = &result->operator[](reference_token);
11963                     break;
11964                 }
11965 
11966                 case detail::value_t::array:
11967                 {
11968                     // create an entry in the array
11969                     result = &result->operator[](array_index(reference_token));
11970                     break;
11971                 }
11972 
11973                 /*
11974                 The following code is only reached if there exists a reference
11975                 token _and_ the current value is primitive. In this case, we have
11976                 an error situation, because primitive values may only occur as
11977                 single value; that is, with an empty list of reference tokens.
11978                 */
11979                 default:
11980                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
11981             }
11982         }
11983 
11984         return *result;
11985     }
11986 
11987     /*!
11988     @brief return a reference to the pointed to value
11989 
11990     @note This version does not throw if a value is not present, but tries to
11991           create nested values instead. For instance, calling this function
11992           with pointer `"/this/that"` on a null value is equivalent to calling
11993           `operator[]("this").operator[]("that")` on that value, effectively
11994           changing the null value to an object.
11995 
11996     @param[in] ptr  a JSON value
11997 
11998     @return reference to the JSON value pointed to by the JSON pointer
11999 
12000     @complexity Linear in the length of the JSON pointer.
12001 
12002     @throw parse_error.106   if an array index begins with '0'
12003     @throw parse_error.109   if an array index was not a number
12004     @throw out_of_range.404  if the JSON pointer can not be resolved
12005     */
get_unchecked(BasicJsonType * ptr) const12006     BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12007     {
12008         for (const auto& reference_token : reference_tokens)
12009         {
12010             // convert null values to arrays or objects before continuing
12011             if (ptr->is_null())
12012             {
12013                 // check if reference token is a number
12014                 const bool nums =
12015                     std::all_of(reference_token.begin(), reference_token.end(),
12016                                 [](const unsigned char x)
12017                 {
12018                     return std::isdigit(x);
12019                 });
12020 
12021                 // change value to array for numbers or "-" or to object otherwise
12022                 *ptr = (nums || reference_token == "-")
12023                        ? detail::value_t::array
12024                        : detail::value_t::object;
12025             }
12026 
12027             switch (ptr->type())
12028             {
12029                 case detail::value_t::object:
12030                 {
12031                     // use unchecked object access
12032                     ptr = &ptr->operator[](reference_token);
12033                     break;
12034                 }
12035 
12036                 case detail::value_t::array:
12037                 {
12038                     if (reference_token == "-")
12039                     {
12040                         // explicitly treat "-" as index beyond the end
12041                         ptr = &ptr->operator[](ptr->m_value.array->size());
12042                     }
12043                     else
12044                     {
12045                         // convert array index to number; unchecked access
12046                         ptr = &ptr->operator[](array_index(reference_token));
12047                     }
12048                     break;
12049                 }
12050 
12051                 default:
12052                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12053             }
12054         }
12055 
12056         return *ptr;
12057     }
12058 
12059     /*!
12060     @throw parse_error.106   if an array index begins with '0'
12061     @throw parse_error.109   if an array index was not a number
12062     @throw out_of_range.402  if the array index '-' is used
12063     @throw out_of_range.404  if the JSON pointer can not be resolved
12064     */
get_checked(BasicJsonType * ptr) const12065     BasicJsonType& get_checked(BasicJsonType* ptr) const
12066     {
12067         for (const auto& reference_token : reference_tokens)
12068         {
12069             switch (ptr->type())
12070             {
12071                 case detail::value_t::object:
12072                 {
12073                     // note: at performs range check
12074                     ptr = &ptr->at(reference_token);
12075                     break;
12076                 }
12077 
12078                 case detail::value_t::array:
12079                 {
12080                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12081                     {
12082                         // "-" always fails the range check
12083                         JSON_THROW(detail::out_of_range::create(402,
12084                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12085                                                                 ") is out of range"));
12086                     }
12087 
12088                     // note: at performs range check
12089                     ptr = &ptr->at(array_index(reference_token));
12090                     break;
12091                 }
12092 
12093                 default:
12094                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12095             }
12096         }
12097 
12098         return *ptr;
12099     }
12100 
12101     /*!
12102     @brief return a const reference to the pointed to value
12103 
12104     @param[in] ptr  a JSON value
12105 
12106     @return const reference to the JSON value pointed to by the JSON
12107     pointer
12108 
12109     @throw parse_error.106   if an array index begins with '0'
12110     @throw parse_error.109   if an array index was not a number
12111     @throw out_of_range.402  if the array index '-' is used
12112     @throw out_of_range.404  if the JSON pointer can not be resolved
12113     */
get_unchecked(const BasicJsonType * ptr) const12114     const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12115     {
12116         for (const auto& reference_token : reference_tokens)
12117         {
12118             switch (ptr->type())
12119             {
12120                 case detail::value_t::object:
12121                 {
12122                     // use unchecked object access
12123                     ptr = &ptr->operator[](reference_token);
12124                     break;
12125                 }
12126 
12127                 case detail::value_t::array:
12128                 {
12129                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12130                     {
12131                         // "-" cannot be used for const access
12132                         JSON_THROW(detail::out_of_range::create(402,
12133                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12134                                                                 ") is out of range"));
12135                     }
12136 
12137                     // use unchecked array access
12138                     ptr = &ptr->operator[](array_index(reference_token));
12139                     break;
12140                 }
12141 
12142                 default:
12143                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12144             }
12145         }
12146 
12147         return *ptr;
12148     }
12149 
12150     /*!
12151     @throw parse_error.106   if an array index begins with '0'
12152     @throw parse_error.109   if an array index was not a number
12153     @throw out_of_range.402  if the array index '-' is used
12154     @throw out_of_range.404  if the JSON pointer can not be resolved
12155     */
get_checked(const BasicJsonType * ptr) const12156     const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12157     {
12158         for (const auto& reference_token : reference_tokens)
12159         {
12160             switch (ptr->type())
12161             {
12162                 case detail::value_t::object:
12163                 {
12164                     // note: at performs range check
12165                     ptr = &ptr->at(reference_token);
12166                     break;
12167                 }
12168 
12169                 case detail::value_t::array:
12170                 {
12171                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12172                     {
12173                         // "-" always fails the range check
12174                         JSON_THROW(detail::out_of_range::create(402,
12175                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12176                                                                 ") is out of range"));
12177                     }
12178 
12179                     // note: at performs range check
12180                     ptr = &ptr->at(array_index(reference_token));
12181                     break;
12182                 }
12183 
12184                 default:
12185                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12186             }
12187         }
12188 
12189         return *ptr;
12190     }
12191 
12192     /*!
12193     @throw parse_error.106   if an array index begins with '0'
12194     @throw parse_error.109   if an array index was not a number
12195     */
contains(const BasicJsonType * ptr) const12196     bool contains(const BasicJsonType* ptr) const
12197     {
12198         for (const auto& reference_token : reference_tokens)
12199         {
12200             switch (ptr->type())
12201             {
12202                 case detail::value_t::object:
12203                 {
12204                     if (!ptr->contains(reference_token))
12205                     {
12206                         // we did not find the key in the object
12207                         return false;
12208                     }
12209 
12210                     ptr = &ptr->operator[](reference_token);
12211                     break;
12212                 }
12213 
12214                 case detail::value_t::array:
12215                 {
12216                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12217                     {
12218                         // "-" always fails the range check
12219                         return false;
12220                     }
12221                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12222                     {
12223                         // invalid char
12224                         return false;
12225                     }
12226                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12227                     {
12228                         if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12229                         {
12230                             // first char should be between '1' and '9'
12231                             return false;
12232                         }
12233                         for (std::size_t i = 1; i < reference_token.size(); i++)
12234                         {
12235                             if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12236                             {
12237                                 // other char should be between '0' and '9'
12238                                 return false;
12239                             }
12240                         }
12241                     }
12242 
12243                     const auto idx = array_index(reference_token);
12244                     if (idx >= ptr->size())
12245                     {
12246                         // index out of range
12247                         return false;
12248                     }
12249 
12250                     ptr = &ptr->operator[](idx);
12251                     break;
12252                 }
12253 
12254                 default:
12255                 {
12256                     // we do not expect primitive values if there is still a
12257                     // reference token to process
12258                     return false;
12259                 }
12260             }
12261         }
12262 
12263         // no reference token left means we found a primitive value
12264         return true;
12265     }
12266 
12267     /*!
12268     @brief split the string input to reference tokens
12269 
12270     @note This function is only called by the json_pointer constructor.
12271           All exceptions below are documented there.
12272 
12273     @throw parse_error.107  if the pointer is not empty or begins with '/'
12274     @throw parse_error.108  if character '~' is not followed by '0' or '1'
12275     */
split(const std::string & reference_string)12276     static std::vector<std::string> split(const std::string& reference_string)
12277     {
12278         std::vector<std::string> result;
12279 
12280         // special case: empty reference string -> no reference tokens
12281         if (reference_string.empty())
12282         {
12283             return result;
12284         }
12285 
12286         // check if nonempty reference string begins with slash
12287         if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12288         {
12289             JSON_THROW(detail::parse_error::create(107, 1,
12290                                                    "JSON pointer must be empty or begin with '/' - was: '" +
12291                                                    reference_string + "'"));
12292         }
12293 
12294         // extract the reference tokens:
12295         // - slash: position of the last read slash (or end of string)
12296         // - start: position after the previous slash
12297         for (
12298             // search for the first slash after the first character
12299             std::size_t slash = reference_string.find_first_of('/', 1),
12300             // set the beginning of the first reference token
12301             start = 1;
12302             // we can stop if start == 0 (if slash == std::string::npos)
12303             start != 0;
12304             // set the beginning of the next reference token
12305             // (will eventually be 0 if slash == std::string::npos)
12306             start = (slash == std::string::npos) ? 0 : slash + 1,
12307             // find next slash
12308             slash = reference_string.find_first_of('/', start))
12309         {
12310             // use the text between the beginning of the reference token
12311             // (start) and the last slash (slash).
12312             auto reference_token = reference_string.substr(start, slash - start);
12313 
12314             // check reference tokens are properly escaped
12315             for (std::size_t pos = reference_token.find_first_of('~');
12316                     pos != std::string::npos;
12317                     pos = reference_token.find_first_of('~', pos + 1))
12318             {
12319                 JSON_ASSERT(reference_token[pos] == '~');
12320 
12321                 // ~ must be followed by 0 or 1
12322                 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12323                                          (reference_token[pos + 1] != '0' &&
12324                                           reference_token[pos + 1] != '1')))
12325                 {
12326                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12327                 }
12328             }
12329 
12330             // finally, store the reference token
12331             unescape(reference_token);
12332             result.push_back(reference_token);
12333         }
12334 
12335         return result;
12336     }
12337 
12338     /*!
12339     @brief replace all occurrences of a substring by another string
12340 
12341     @param[in,out] s  the string to manipulate; changed so that all
12342                    occurrences of @a f are replaced with @a t
12343     @param[in]     f  the substring to replace with @a t
12344     @param[in]     t  the string to replace @a f
12345 
12346     @pre The search string @a f must not be empty. **This precondition is
12347     enforced with an assertion.**
12348 
12349     @since version 2.0.0
12350     */
replace_substring(std::string & s,const std::string & f,const std::string & t)12351     static void replace_substring(std::string& s, const std::string& f,
12352                                   const std::string& t)
12353     {
12354         JSON_ASSERT(!f.empty());
12355         for (auto pos = s.find(f);                // find first occurrence of f
12356                 pos != std::string::npos;         // make sure f was found
12357                 s.replace(pos, f.size(), t),      // replace with t, and
12358                 pos = s.find(f, pos + t.size()))  // find next occurrence of f
12359         {}
12360     }
12361 
12362     /// escape "~" to "~0" and "/" to "~1"
escape(std::string s)12363     static std::string escape(std::string s)
12364     {
12365         replace_substring(s, "~", "~0");
12366         replace_substring(s, "/", "~1");
12367         return s;
12368     }
12369 
12370     /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)12371     static void unescape(std::string& s)
12372     {
12373         replace_substring(s, "~1", "/");
12374         replace_substring(s, "~0", "~");
12375     }
12376 
12377     /*!
12378     @param[in] reference_string  the reference string to the current value
12379     @param[in] value             the value to consider
12380     @param[in,out] result        the result object to insert values to
12381 
12382     @note Empty objects or arrays are flattened to `null`.
12383     */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)12384     static void flatten(const std::string& reference_string,
12385                         const BasicJsonType& value,
12386                         BasicJsonType& result)
12387     {
12388         switch (value.type())
12389         {
12390             case detail::value_t::array:
12391             {
12392                 if (value.m_value.array->empty())
12393                 {
12394                     // flatten empty array as null
12395                     result[reference_string] = nullptr;
12396                 }
12397                 else
12398                 {
12399                     // iterate array and use index as reference string
12400                     for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12401                     {
12402                         flatten(reference_string + "/" + std::to_string(i),
12403                                 value.m_value.array->operator[](i), result);
12404                     }
12405                 }
12406                 break;
12407             }
12408 
12409             case detail::value_t::object:
12410             {
12411                 if (value.m_value.object->empty())
12412                 {
12413                     // flatten empty object as null
12414                     result[reference_string] = nullptr;
12415                 }
12416                 else
12417                 {
12418                     // iterate object and use keys as reference string
12419                     for (const auto& element : *value.m_value.object)
12420                     {
12421                         flatten(reference_string + "/" + escape(element.first), element.second, result);
12422                     }
12423                 }
12424                 break;
12425             }
12426 
12427             default:
12428             {
12429                 // add primitive value with its reference string
12430                 result[reference_string] = value;
12431                 break;
12432             }
12433         }
12434     }
12435 
12436     /*!
12437     @param[in] value  flattened JSON
12438 
12439     @return unflattened JSON
12440 
12441     @throw parse_error.109 if array index is not a number
12442     @throw type_error.314  if value is not an object
12443     @throw type_error.315  if object values are not primitive
12444     @throw type_error.313  if value cannot be unflattened
12445     */
12446     static BasicJsonType
unflatten(const BasicJsonType & value)12447     unflatten(const BasicJsonType& value)
12448     {
12449         if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12450         {
12451             JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12452         }
12453 
12454         BasicJsonType result;
12455 
12456         // iterate the JSON object values
12457         for (const auto& element : *value.m_value.object)
12458         {
12459             if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12460             {
12461                 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12462             }
12463 
12464             // assign value to reference pointed to by JSON pointer; Note that if
12465             // the JSON pointer is "" (i.e., points to the whole value), function
12466             // get_and_create returns a reference to result itself. An assignment
12467             // will then create a primitive value.
12468             json_pointer(element.first).get_and_create(result) = element.second;
12469         }
12470 
12471         return result;
12472     }
12473 
12474     /*!
12475     @brief compares two JSON pointers for equality
12476 
12477     @param[in] lhs  JSON pointer to compare
12478     @param[in] rhs  JSON pointer to compare
12479     @return whether @a lhs is equal to @a rhs
12480 
12481     @complexity Linear in the length of the JSON pointer
12482 
12483     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12484     */
operator ==(json_pointer const & lhs,json_pointer const & rhs)12485     friend bool operator==(json_pointer const& lhs,
12486                            json_pointer const& rhs) noexcept
12487     {
12488         return lhs.reference_tokens == rhs.reference_tokens;
12489     }
12490 
12491     /*!
12492     @brief compares two JSON pointers for inequality
12493 
12494     @param[in] lhs  JSON pointer to compare
12495     @param[in] rhs  JSON pointer to compare
12496     @return whether @a lhs is not equal @a rhs
12497 
12498     @complexity Linear in the length of the JSON pointer
12499 
12500     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12501     */
operator !=(json_pointer const & lhs,json_pointer const & rhs)12502     friend bool operator!=(json_pointer const& lhs,
12503                            json_pointer const& rhs) noexcept
12504     {
12505         return !(lhs == rhs);
12506     }
12507 
12508     /// the reference tokens
12509     std::vector<std::string> reference_tokens;
12510 };
12511 }  // namespace nlohmann
12512 
12513 // #include <nlohmann/detail/json_ref.hpp>
12514 
12515 
12516 #include <initializer_list>
12517 #include <utility>
12518 
12519 // #include <nlohmann/detail/meta/type_traits.hpp>
12520 
12521 
12522 namespace nlohmann
12523 {
12524 namespace detail
12525 {
12526 template<typename BasicJsonType>
12527 class json_ref
12528 {
12529   public:
12530     using value_type = BasicJsonType;
12531 
json_ref(value_type && value)12532     json_ref(value_type&& value)
12533         : owned_value(std::move(value))
12534         , value_ref(&owned_value)
12535         , is_rvalue(true)
12536     {}
12537 
json_ref(const value_type & value)12538     json_ref(const value_type& value)
12539         : value_ref(const_cast<value_type*>(&value))
12540         , is_rvalue(false)
12541     {}
12542 
json_ref(std::initializer_list<json_ref> init)12543     json_ref(std::initializer_list<json_ref> init)
12544         : owned_value(init)
12545         , value_ref(&owned_value)
12546         , is_rvalue(true)
12547     {}
12548 
12549     template <
12550         class... Args,
12551         enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)12552     json_ref(Args && ... args)
12553         : owned_value(std::forward<Args>(args)...)
12554         , value_ref(&owned_value)
12555         , is_rvalue(true)
12556     {}
12557 
12558     // class should be movable only
12559     json_ref(json_ref&&) = default;
12560     json_ref(const json_ref&) = delete;
12561     json_ref& operator=(const json_ref&) = delete;
12562     json_ref& operator=(json_ref&&) = delete;
12563     ~json_ref() = default;
12564 
moved_or_copied() const12565     value_type moved_or_copied() const
12566     {
12567         if (is_rvalue)
12568         {
12569             return std::move(*value_ref);
12570         }
12571         return *value_ref;
12572     }
12573 
operator *() const12574     value_type const& operator*() const
12575     {
12576         return *static_cast<value_type const*>(value_ref);
12577     }
12578 
operator ->() const12579     value_type const* operator->() const
12580     {
12581         return static_cast<value_type const*>(value_ref);
12582     }
12583 
12584   private:
12585     mutable value_type owned_value = nullptr;
12586     value_type* value_ref = nullptr;
12587     const bool is_rvalue = true;
12588 };
12589 }  // namespace detail
12590 }  // namespace nlohmann
12591 
12592 // #include <nlohmann/detail/macro_scope.hpp>
12593 
12594 // #include <nlohmann/detail/meta/cpp_future.hpp>
12595 
12596 // #include <nlohmann/detail/meta/type_traits.hpp>
12597 
12598 // #include <nlohmann/detail/output/binary_writer.hpp>
12599 
12600 
12601 #include <algorithm> // reverse
12602 #include <array> // array
12603 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12604 #include <cstring> // memcpy
12605 #include <limits> // numeric_limits
12606 #include <string> // string
12607 #include <cmath> // isnan, isinf
12608 
12609 // #include <nlohmann/detail/input/binary_reader.hpp>
12610 
12611 // #include <nlohmann/detail/macro_scope.hpp>
12612 
12613 // #include <nlohmann/detail/output/output_adapters.hpp>
12614 
12615 
12616 #include <algorithm> // copy
12617 #include <cstddef> // size_t
12618 #include <ios> // streamsize
12619 #include <iterator> // back_inserter
12620 #include <memory> // shared_ptr, make_shared
12621 #include <ostream> // basic_ostream
12622 #include <string> // basic_string
12623 #include <vector> // vector
12624 // #include <nlohmann/detail/macro_scope.hpp>
12625 
12626 
12627 namespace nlohmann
12628 {
12629 namespace detail
12630 {
12631 /// abstract output adapter interface
12632 template<typename CharType> struct output_adapter_protocol
12633 {
12634     virtual void write_character(CharType c) = 0;
12635     virtual void write_characters(const CharType* s, std::size_t length) = 0;
12636     virtual ~output_adapter_protocol() = default;
12637 };
12638 
12639 /// a type to simplify interfaces
12640 template<typename CharType>
12641 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12642 
12643 /// output adapter for byte vectors
12644 template<typename CharType>
12645 class output_vector_adapter : public output_adapter_protocol<CharType>
12646 {
12647   public:
output_vector_adapter(std::vector<CharType> & vec)12648     explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12649         : v(vec)
12650     {}
12651 
write_character(CharType c)12652     void write_character(CharType c) override
12653     {
12654         v.push_back(c);
12655     }
12656 
12657     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)12658     void write_characters(const CharType* s, std::size_t length) override
12659     {
12660         std::copy(s, s + length, std::back_inserter(v));
12661     }
12662 
12663   private:
12664     std::vector<CharType>& v;
12665 };
12666 
12667 /// output adapter for output streams
12668 template<typename CharType>
12669 class output_stream_adapter : public output_adapter_protocol<CharType>
12670 {
12671   public:
output_stream_adapter(std::basic_ostream<CharType> & s)12672     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12673         : stream(s)
12674     {}
12675 
write_character(CharType c)12676     void write_character(CharType c) override
12677     {
12678         stream.put(c);
12679     }
12680 
12681     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)12682     void write_characters(const CharType* s, std::size_t length) override
12683     {
12684         stream.write(s, static_cast<std::streamsize>(length));
12685     }
12686 
12687   private:
12688     std::basic_ostream<CharType>& stream;
12689 };
12690 
12691 /// output adapter for basic_string
12692 template<typename CharType, typename StringType = std::basic_string<CharType>>
12693 class output_string_adapter : public output_adapter_protocol<CharType>
12694 {
12695   public:
output_string_adapter(StringType & s)12696     explicit output_string_adapter(StringType& s) noexcept
12697         : str(s)
12698     {}
12699 
write_character(CharType c)12700     void write_character(CharType c) override
12701     {
12702         str.push_back(c);
12703     }
12704 
12705     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)12706     void write_characters(const CharType* s, std::size_t length) override
12707     {
12708         str.append(s, length);
12709     }
12710 
12711   private:
12712     StringType& str;
12713 };
12714 
12715 template<typename CharType, typename StringType = std::basic_string<CharType>>
12716 class output_adapter
12717 {
12718   public:
output_adapter(std::vector<CharType> & vec)12719     output_adapter(std::vector<CharType>& vec)
12720         : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12721 
output_adapter(std::basic_ostream<CharType> & s)12722     output_adapter(std::basic_ostream<CharType>& s)
12723         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12724 
output_adapter(StringType & s)12725     output_adapter(StringType& s)
12726         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12727 
operator output_adapter_t<CharType>()12728     operator output_adapter_t<CharType>()
12729     {
12730         return oa;
12731     }
12732 
12733   private:
12734     output_adapter_t<CharType> oa = nullptr;
12735 };
12736 }  // namespace detail
12737 }  // namespace nlohmann
12738 
12739 
12740 namespace nlohmann
12741 {
12742 namespace detail
12743 {
12744 ///////////////////
12745 // binary writer //
12746 ///////////////////
12747 
12748 /*!
12749 @brief serialization to CBOR and MessagePack values
12750 */
12751 template<typename BasicJsonType, typename CharType>
12752 class binary_writer
12753 {
12754     using string_t = typename BasicJsonType::string_t;
12755     using binary_t = typename BasicJsonType::binary_t;
12756     using number_float_t = typename BasicJsonType::number_float_t;
12757 
12758   public:
12759     /*!
12760     @brief create a binary writer
12761 
12762     @param[in] adapter  output adapter to write to
12763     */
binary_writer(output_adapter_t<CharType> adapter)12764     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12765     {
12766         JSON_ASSERT(oa);
12767     }
12768 
12769     /*!
12770     @param[in] j  JSON value to serialize
12771     @pre       j.type() == value_t::object
12772     */
write_bson(const BasicJsonType & j)12773     void write_bson(const BasicJsonType& j)
12774     {
12775         switch (j.type())
12776         {
12777             case value_t::object:
12778             {
12779                 write_bson_object(*j.m_value.object);
12780                 break;
12781             }
12782 
12783             default:
12784             {
12785                 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12786             }
12787         }
12788     }
12789 
12790     /*!
12791     @param[in] j  JSON value to serialize
12792     */
write_cbor(const BasicJsonType & j)12793     void write_cbor(const BasicJsonType& j)
12794     {
12795         switch (j.type())
12796         {
12797             case value_t::null:
12798             {
12799                 oa->write_character(to_char_type(0xF6));
12800                 break;
12801             }
12802 
12803             case value_t::boolean:
12804             {
12805                 oa->write_character(j.m_value.boolean
12806                                     ? to_char_type(0xF5)
12807                                     : to_char_type(0xF4));
12808                 break;
12809             }
12810 
12811             case value_t::number_integer:
12812             {
12813                 if (j.m_value.number_integer >= 0)
12814                 {
12815                     // CBOR does not differentiate between positive signed
12816                     // integers and unsigned integers. Therefore, we used the
12817                     // code from the value_t::number_unsigned case here.
12818                     if (j.m_value.number_integer <= 0x17)
12819                     {
12820                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12821                     }
12822                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12823                     {
12824                         oa->write_character(to_char_type(0x18));
12825                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12826                     }
12827                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12828                     {
12829                         oa->write_character(to_char_type(0x19));
12830                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12831                     }
12832                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12833                     {
12834                         oa->write_character(to_char_type(0x1A));
12835                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12836                     }
12837                     else
12838                     {
12839                         oa->write_character(to_char_type(0x1B));
12840                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12841                     }
12842                 }
12843                 else
12844                 {
12845                     // The conversions below encode the sign in the first
12846                     // byte, and the value is converted to a positive number.
12847                     const auto positive_number = -1 - j.m_value.number_integer;
12848                     if (j.m_value.number_integer >= -24)
12849                     {
12850                         write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12851                     }
12852                     else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12853                     {
12854                         oa->write_character(to_char_type(0x38));
12855                         write_number(static_cast<std::uint8_t>(positive_number));
12856                     }
12857                     else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12858                     {
12859                         oa->write_character(to_char_type(0x39));
12860                         write_number(static_cast<std::uint16_t>(positive_number));
12861                     }
12862                     else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12863                     {
12864                         oa->write_character(to_char_type(0x3A));
12865                         write_number(static_cast<std::uint32_t>(positive_number));
12866                     }
12867                     else
12868                     {
12869                         oa->write_character(to_char_type(0x3B));
12870                         write_number(static_cast<std::uint64_t>(positive_number));
12871                     }
12872                 }
12873                 break;
12874             }
12875 
12876             case value_t::number_unsigned:
12877             {
12878                 if (j.m_value.number_unsigned <= 0x17)
12879                 {
12880                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12881                 }
12882                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12883                 {
12884                     oa->write_character(to_char_type(0x18));
12885                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12886                 }
12887                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12888                 {
12889                     oa->write_character(to_char_type(0x19));
12890                     write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12891                 }
12892                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12893                 {
12894                     oa->write_character(to_char_type(0x1A));
12895                     write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12896                 }
12897                 else
12898                 {
12899                     oa->write_character(to_char_type(0x1B));
12900                     write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12901                 }
12902                 break;
12903             }
12904 
12905             case value_t::number_float:
12906             {
12907                 if (std::isnan(j.m_value.number_float))
12908                 {
12909                     // NaN is 0xf97e00 in CBOR
12910                     oa->write_character(to_char_type(0xF9));
12911                     oa->write_character(to_char_type(0x7E));
12912                     oa->write_character(to_char_type(0x00));
12913                 }
12914                 else if (std::isinf(j.m_value.number_float))
12915                 {
12916                     // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12917                     oa->write_character(to_char_type(0xf9));
12918                     oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12919                     oa->write_character(to_char_type(0x00));
12920                 }
12921                 else
12922                 {
12923                     write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12924                 }
12925                 break;
12926             }
12927 
12928             case value_t::string:
12929             {
12930                 // step 1: write control byte and the string length
12931                 const auto N = j.m_value.string->size();
12932                 if (N <= 0x17)
12933                 {
12934                     write_number(static_cast<std::uint8_t>(0x60 + N));
12935                 }
12936                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12937                 {
12938                     oa->write_character(to_char_type(0x78));
12939                     write_number(static_cast<std::uint8_t>(N));
12940                 }
12941                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12942                 {
12943                     oa->write_character(to_char_type(0x79));
12944                     write_number(static_cast<std::uint16_t>(N));
12945                 }
12946                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12947                 {
12948                     oa->write_character(to_char_type(0x7A));
12949                     write_number(static_cast<std::uint32_t>(N));
12950                 }
12951                 // LCOV_EXCL_START
12952                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12953                 {
12954                     oa->write_character(to_char_type(0x7B));
12955                     write_number(static_cast<std::uint64_t>(N));
12956                 }
12957                 // LCOV_EXCL_STOP
12958 
12959                 // step 2: write the string
12960                 oa->write_characters(
12961                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
12962                     j.m_value.string->size());
12963                 break;
12964             }
12965 
12966             case value_t::array:
12967             {
12968                 // step 1: write control byte and the array size
12969                 const auto N = j.m_value.array->size();
12970                 if (N <= 0x17)
12971                 {
12972                     write_number(static_cast<std::uint8_t>(0x80 + N));
12973                 }
12974                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
12975                 {
12976                     oa->write_character(to_char_type(0x98));
12977                     write_number(static_cast<std::uint8_t>(N));
12978                 }
12979                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
12980                 {
12981                     oa->write_character(to_char_type(0x99));
12982                     write_number(static_cast<std::uint16_t>(N));
12983                 }
12984                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
12985                 {
12986                     oa->write_character(to_char_type(0x9A));
12987                     write_number(static_cast<std::uint32_t>(N));
12988                 }
12989                 // LCOV_EXCL_START
12990                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
12991                 {
12992                     oa->write_character(to_char_type(0x9B));
12993                     write_number(static_cast<std::uint64_t>(N));
12994                 }
12995                 // LCOV_EXCL_STOP
12996 
12997                 // step 2: write each element
12998                 for (const auto& el : *j.m_value.array)
12999                 {
13000                     write_cbor(el);
13001                 }
13002                 break;
13003             }
13004 
13005             case value_t::binary:
13006             {
13007                 if (j.m_value.binary->has_subtype())
13008                 {
13009                     write_number(static_cast<std::uint8_t>(0xd8));
13010                     write_number(j.m_value.binary->subtype());
13011                 }
13012 
13013                 // step 1: write control byte and the binary array size
13014                 const auto N = j.m_value.binary->size();
13015                 if (N <= 0x17)
13016                 {
13017                     write_number(static_cast<std::uint8_t>(0x40 + N));
13018                 }
13019                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13020                 {
13021                     oa->write_character(to_char_type(0x58));
13022                     write_number(static_cast<std::uint8_t>(N));
13023                 }
13024                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13025                 {
13026                     oa->write_character(to_char_type(0x59));
13027                     write_number(static_cast<std::uint16_t>(N));
13028                 }
13029                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13030                 {
13031                     oa->write_character(to_char_type(0x5A));
13032                     write_number(static_cast<std::uint32_t>(N));
13033                 }
13034                 // LCOV_EXCL_START
13035                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13036                 {
13037                     oa->write_character(to_char_type(0x5B));
13038                     write_number(static_cast<std::uint64_t>(N));
13039                 }
13040                 // LCOV_EXCL_STOP
13041 
13042                 // step 2: write each element
13043                 oa->write_characters(
13044                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13045                     N);
13046 
13047                 break;
13048             }
13049 
13050             case value_t::object:
13051             {
13052                 // step 1: write control byte and the object size
13053                 const auto N = j.m_value.object->size();
13054                 if (N <= 0x17)
13055                 {
13056                     write_number(static_cast<std::uint8_t>(0xA0 + N));
13057                 }
13058                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13059                 {
13060                     oa->write_character(to_char_type(0xB8));
13061                     write_number(static_cast<std::uint8_t>(N));
13062                 }
13063                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13064                 {
13065                     oa->write_character(to_char_type(0xB9));
13066                     write_number(static_cast<std::uint16_t>(N));
13067                 }
13068                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13069                 {
13070                     oa->write_character(to_char_type(0xBA));
13071                     write_number(static_cast<std::uint32_t>(N));
13072                 }
13073                 // LCOV_EXCL_START
13074                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13075                 {
13076                     oa->write_character(to_char_type(0xBB));
13077                     write_number(static_cast<std::uint64_t>(N));
13078                 }
13079                 // LCOV_EXCL_STOP
13080 
13081                 // step 2: write each element
13082                 for (const auto& el : *j.m_value.object)
13083                 {
13084                     write_cbor(el.first);
13085                     write_cbor(el.second);
13086                 }
13087                 break;
13088             }
13089 
13090             default:
13091                 break;
13092         }
13093     }
13094 
13095     /*!
13096     @param[in] j  JSON value to serialize
13097     */
write_msgpack(const BasicJsonType & j)13098     void write_msgpack(const BasicJsonType& j)
13099     {
13100         switch (j.type())
13101         {
13102             case value_t::null: // nil
13103             {
13104                 oa->write_character(to_char_type(0xC0));
13105                 break;
13106             }
13107 
13108             case value_t::boolean: // true and false
13109             {
13110                 oa->write_character(j.m_value.boolean
13111                                     ? to_char_type(0xC3)
13112                                     : to_char_type(0xC2));
13113                 break;
13114             }
13115 
13116             case value_t::number_integer:
13117             {
13118                 if (j.m_value.number_integer >= 0)
13119                 {
13120                     // MessagePack does not differentiate between positive
13121                     // signed integers and unsigned integers. Therefore, we used
13122                     // the code from the value_t::number_unsigned case here.
13123                     if (j.m_value.number_unsigned < 128)
13124                     {
13125                         // positive fixnum
13126                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13127                     }
13128                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13129                     {
13130                         // uint 8
13131                         oa->write_character(to_char_type(0xCC));
13132                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13133                     }
13134                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13135                     {
13136                         // uint 16
13137                         oa->write_character(to_char_type(0xCD));
13138                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13139                     }
13140                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13141                     {
13142                         // uint 32
13143                         oa->write_character(to_char_type(0xCE));
13144                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13145                     }
13146                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13147                     {
13148                         // uint 64
13149                         oa->write_character(to_char_type(0xCF));
13150                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13151                     }
13152                 }
13153                 else
13154                 {
13155                     if (j.m_value.number_integer >= -32)
13156                     {
13157                         // negative fixnum
13158                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13159                     }
13160                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13161                              j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13162                     {
13163                         // int 8
13164                         oa->write_character(to_char_type(0xD0));
13165                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13166                     }
13167                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13168                              j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13169                     {
13170                         // int 16
13171                         oa->write_character(to_char_type(0xD1));
13172                         write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13173                     }
13174                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13175                              j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13176                     {
13177                         // int 32
13178                         oa->write_character(to_char_type(0xD2));
13179                         write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13180                     }
13181                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13182                              j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13183                     {
13184                         // int 64
13185                         oa->write_character(to_char_type(0xD3));
13186                         write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13187                     }
13188                 }
13189                 break;
13190             }
13191 
13192             case value_t::number_unsigned:
13193             {
13194                 if (j.m_value.number_unsigned < 128)
13195                 {
13196                     // positive fixnum
13197                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13198                 }
13199                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13200                 {
13201                     // uint 8
13202                     oa->write_character(to_char_type(0xCC));
13203                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13204                 }
13205                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13206                 {
13207                     // uint 16
13208                     oa->write_character(to_char_type(0xCD));
13209                     write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13210                 }
13211                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13212                 {
13213                     // uint 32
13214                     oa->write_character(to_char_type(0xCE));
13215                     write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13216                 }
13217                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13218                 {
13219                     // uint 64
13220                     oa->write_character(to_char_type(0xCF));
13221                     write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13222                 }
13223                 break;
13224             }
13225 
13226             case value_t::number_float:
13227             {
13228                 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13229                 break;
13230             }
13231 
13232             case value_t::string:
13233             {
13234                 // step 1: write control byte and the string length
13235                 const auto N = j.m_value.string->size();
13236                 if (N <= 31)
13237                 {
13238                     // fixstr
13239                     write_number(static_cast<std::uint8_t>(0xA0 | N));
13240                 }
13241                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13242                 {
13243                     // str 8
13244                     oa->write_character(to_char_type(0xD9));
13245                     write_number(static_cast<std::uint8_t>(N));
13246                 }
13247                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13248                 {
13249                     // str 16
13250                     oa->write_character(to_char_type(0xDA));
13251                     write_number(static_cast<std::uint16_t>(N));
13252                 }
13253                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13254                 {
13255                     // str 32
13256                     oa->write_character(to_char_type(0xDB));
13257                     write_number(static_cast<std::uint32_t>(N));
13258                 }
13259 
13260                 // step 2: write the string
13261                 oa->write_characters(
13262                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13263                     j.m_value.string->size());
13264                 break;
13265             }
13266 
13267             case value_t::array:
13268             {
13269                 // step 1: write control byte and the array size
13270                 const auto N = j.m_value.array->size();
13271                 if (N <= 15)
13272                 {
13273                     // fixarray
13274                     write_number(static_cast<std::uint8_t>(0x90 | N));
13275                 }
13276                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13277                 {
13278                     // array 16
13279                     oa->write_character(to_char_type(0xDC));
13280                     write_number(static_cast<std::uint16_t>(N));
13281                 }
13282                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13283                 {
13284                     // array 32
13285                     oa->write_character(to_char_type(0xDD));
13286                     write_number(static_cast<std::uint32_t>(N));
13287                 }
13288 
13289                 // step 2: write each element
13290                 for (const auto& el : *j.m_value.array)
13291                 {
13292                     write_msgpack(el);
13293                 }
13294                 break;
13295             }
13296 
13297             case value_t::binary:
13298             {
13299                 // step 0: determine if the binary type has a set subtype to
13300                 // determine whether or not to use the ext or fixext types
13301                 const bool use_ext = j.m_value.binary->has_subtype();
13302 
13303                 // step 1: write control byte and the byte string length
13304                 const auto N = j.m_value.binary->size();
13305                 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13306                 {
13307                     std::uint8_t output_type{};
13308                     bool fixed = true;
13309                     if (use_ext)
13310                     {
13311                         switch (N)
13312                         {
13313                             case 1:
13314                                 output_type = 0xD4; // fixext 1
13315                                 break;
13316                             case 2:
13317                                 output_type = 0xD5; // fixext 2
13318                                 break;
13319                             case 4:
13320                                 output_type = 0xD6; // fixext 4
13321                                 break;
13322                             case 8:
13323                                 output_type = 0xD7; // fixext 8
13324                                 break;
13325                             case 16:
13326                                 output_type = 0xD8; // fixext 16
13327                                 break;
13328                             default:
13329                                 output_type = 0xC7; // ext 8
13330                                 fixed = false;
13331                                 break;
13332                         }
13333 
13334                     }
13335                     else
13336                     {
13337                         output_type = 0xC4; // bin 8
13338                         fixed = false;
13339                     }
13340 
13341                     oa->write_character(to_char_type(output_type));
13342                     if (!fixed)
13343                     {
13344                         write_number(static_cast<std::uint8_t>(N));
13345                     }
13346                 }
13347                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13348                 {
13349                     std::uint8_t output_type = use_ext
13350                                                ? 0xC8 // ext 16
13351                                                : 0xC5; // bin 16
13352 
13353                     oa->write_character(to_char_type(output_type));
13354                     write_number(static_cast<std::uint16_t>(N));
13355                 }
13356                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13357                 {
13358                     std::uint8_t output_type = use_ext
13359                                                ? 0xC9 // ext 32
13360                                                : 0xC6; // bin 32
13361 
13362                     oa->write_character(to_char_type(output_type));
13363                     write_number(static_cast<std::uint32_t>(N));
13364                 }
13365 
13366                 // step 1.5: if this is an ext type, write the subtype
13367                 if (use_ext)
13368                 {
13369                     write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13370                 }
13371 
13372                 // step 2: write the byte string
13373                 oa->write_characters(
13374                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13375                     N);
13376 
13377                 break;
13378             }
13379 
13380             case value_t::object:
13381             {
13382                 // step 1: write control byte and the object size
13383                 const auto N = j.m_value.object->size();
13384                 if (N <= 15)
13385                 {
13386                     // fixmap
13387                     write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13388                 }
13389                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13390                 {
13391                     // map 16
13392                     oa->write_character(to_char_type(0xDE));
13393                     write_number(static_cast<std::uint16_t>(N));
13394                 }
13395                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13396                 {
13397                     // map 32
13398                     oa->write_character(to_char_type(0xDF));
13399                     write_number(static_cast<std::uint32_t>(N));
13400                 }
13401 
13402                 // step 2: write each element
13403                 for (const auto& el : *j.m_value.object)
13404                 {
13405                     write_msgpack(el.first);
13406                     write_msgpack(el.second);
13407                 }
13408                 break;
13409             }
13410 
13411             default:
13412                 break;
13413         }
13414     }
13415 
13416     /*!
13417     @param[in] j  JSON value to serialize
13418     @param[in] use_count   whether to use '#' prefixes (optimized format)
13419     @param[in] use_type    whether to use '$' prefixes (optimized format)
13420     @param[in] add_prefix  whether prefixes need to be used for this value
13421     */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)13422     void write_ubjson(const BasicJsonType& j, const bool use_count,
13423                       const bool use_type, const bool add_prefix = true)
13424     {
13425         switch (j.type())
13426         {
13427             case value_t::null:
13428             {
13429                 if (add_prefix)
13430                 {
13431                     oa->write_character(to_char_type('Z'));
13432                 }
13433                 break;
13434             }
13435 
13436             case value_t::boolean:
13437             {
13438                 if (add_prefix)
13439                 {
13440                     oa->write_character(j.m_value.boolean
13441                                         ? to_char_type('T')
13442                                         : to_char_type('F'));
13443                 }
13444                 break;
13445             }
13446 
13447             case value_t::number_integer:
13448             {
13449                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13450                 break;
13451             }
13452 
13453             case value_t::number_unsigned:
13454             {
13455                 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13456                 break;
13457             }
13458 
13459             case value_t::number_float:
13460             {
13461                 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13462                 break;
13463             }
13464 
13465             case value_t::string:
13466             {
13467                 if (add_prefix)
13468                 {
13469                     oa->write_character(to_char_type('S'));
13470                 }
13471                 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13472                 oa->write_characters(
13473                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13474                     j.m_value.string->size());
13475                 break;
13476             }
13477 
13478             case value_t::array:
13479             {
13480                 if (add_prefix)
13481                 {
13482                     oa->write_character(to_char_type('['));
13483                 }
13484 
13485                 bool prefix_required = true;
13486                 if (use_type && !j.m_value.array->empty())
13487                 {
13488                     JSON_ASSERT(use_count);
13489                     const CharType first_prefix = ubjson_prefix(j.front());
13490                     const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13491                                                          [this, first_prefix](const BasicJsonType & v)
13492                     {
13493                         return ubjson_prefix(v) == first_prefix;
13494                     });
13495 
13496                     if (same_prefix)
13497                     {
13498                         prefix_required = false;
13499                         oa->write_character(to_char_type('$'));
13500                         oa->write_character(first_prefix);
13501                     }
13502                 }
13503 
13504                 if (use_count)
13505                 {
13506                     oa->write_character(to_char_type('#'));
13507                     write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13508                 }
13509 
13510                 for (const auto& el : *j.m_value.array)
13511                 {
13512                     write_ubjson(el, use_count, use_type, prefix_required);
13513                 }
13514 
13515                 if (!use_count)
13516                 {
13517                     oa->write_character(to_char_type(']'));
13518                 }
13519 
13520                 break;
13521             }
13522 
13523             case value_t::binary:
13524             {
13525                 if (add_prefix)
13526                 {
13527                     oa->write_character(to_char_type('['));
13528                 }
13529 
13530                 if (use_type && !j.m_value.binary->empty())
13531                 {
13532                     JSON_ASSERT(use_count);
13533                     oa->write_character(to_char_type('$'));
13534                     oa->write_character('U');
13535                 }
13536 
13537                 if (use_count)
13538                 {
13539                     oa->write_character(to_char_type('#'));
13540                     write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13541                 }
13542 
13543                 if (use_type)
13544                 {
13545                     oa->write_characters(
13546                         reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13547                         j.m_value.binary->size());
13548                 }
13549                 else
13550                 {
13551                     for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13552                     {
13553                         oa->write_character(to_char_type('U'));
13554                         oa->write_character(j.m_value.binary->data()[i]);
13555                     }
13556                 }
13557 
13558                 if (!use_count)
13559                 {
13560                     oa->write_character(to_char_type(']'));
13561                 }
13562 
13563                 break;
13564             }
13565 
13566             case value_t::object:
13567             {
13568                 if (add_prefix)
13569                 {
13570                     oa->write_character(to_char_type('{'));
13571                 }
13572 
13573                 bool prefix_required = true;
13574                 if (use_type && !j.m_value.object->empty())
13575                 {
13576                     JSON_ASSERT(use_count);
13577                     const CharType first_prefix = ubjson_prefix(j.front());
13578                     const bool same_prefix = std::all_of(j.begin(), j.end(),
13579                                                          [this, first_prefix](const BasicJsonType & v)
13580                     {
13581                         return ubjson_prefix(v) == first_prefix;
13582                     });
13583 
13584                     if (same_prefix)
13585                     {
13586                         prefix_required = false;
13587                         oa->write_character(to_char_type('$'));
13588                         oa->write_character(first_prefix);
13589                     }
13590                 }
13591 
13592                 if (use_count)
13593                 {
13594                     oa->write_character(to_char_type('#'));
13595                     write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13596                 }
13597 
13598                 for (const auto& el : *j.m_value.object)
13599                 {
13600                     write_number_with_ubjson_prefix(el.first.size(), true);
13601                     oa->write_characters(
13602                         reinterpret_cast<const CharType*>(el.first.c_str()),
13603                         el.first.size());
13604                     write_ubjson(el.second, use_count, use_type, prefix_required);
13605                 }
13606 
13607                 if (!use_count)
13608                 {
13609                     oa->write_character(to_char_type('}'));
13610                 }
13611 
13612                 break;
13613             }
13614 
13615             default:
13616                 break;
13617         }
13618     }
13619 
13620   private:
13621     //////////
13622     // BSON //
13623     //////////
13624 
13625     /*!
13626     @return The size of a BSON document entry header, including the id marker
13627             and the entry name size (and its null-terminator).
13628     */
calc_bson_entry_header_size(const string_t & name)13629     static std::size_t calc_bson_entry_header_size(const string_t& name)
13630     {
13631         const auto it = name.find(static_cast<typename string_t::value_type>(0));
13632         if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13633         {
13634             JSON_THROW(out_of_range::create(409,
13635                                             "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13636         }
13637 
13638         return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13639     }
13640 
13641     /*!
13642     @brief Writes the given @a element_type and @a name to the output adapter
13643     */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)13644     void write_bson_entry_header(const string_t& name,
13645                                  const std::uint8_t element_type)
13646     {
13647         oa->write_character(to_char_type(element_type)); // boolean
13648         oa->write_characters(
13649             reinterpret_cast<const CharType*>(name.c_str()),
13650             name.size() + 1u);
13651     }
13652 
13653     /*!
13654     @brief Writes a BSON element with key @a name and boolean value @a value
13655     */
write_bson_boolean(const string_t & name,const bool value)13656     void write_bson_boolean(const string_t& name,
13657                             const bool value)
13658     {
13659         write_bson_entry_header(name, 0x08);
13660         oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13661     }
13662 
13663     /*!
13664     @brief Writes a BSON element with key @a name and double value @a value
13665     */
write_bson_double(const string_t & name,const double value)13666     void write_bson_double(const string_t& name,
13667                            const double value)
13668     {
13669         write_bson_entry_header(name, 0x01);
13670         write_number<double, true>(value);
13671     }
13672 
13673     /*!
13674     @return The size of the BSON-encoded string in @a value
13675     */
calc_bson_string_size(const string_t & value)13676     static std::size_t calc_bson_string_size(const string_t& value)
13677     {
13678         return sizeof(std::int32_t) + value.size() + 1ul;
13679     }
13680 
13681     /*!
13682     @brief Writes a BSON element with key @a name and string value @a value
13683     */
write_bson_string(const string_t & name,const string_t & value)13684     void write_bson_string(const string_t& name,
13685                            const string_t& value)
13686     {
13687         write_bson_entry_header(name, 0x02);
13688 
13689         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13690         oa->write_characters(
13691             reinterpret_cast<const CharType*>(value.c_str()),
13692             value.size() + 1);
13693     }
13694 
13695     /*!
13696     @brief Writes a BSON element with key @a name and null value
13697     */
write_bson_null(const string_t & name)13698     void write_bson_null(const string_t& name)
13699     {
13700         write_bson_entry_header(name, 0x0A);
13701     }
13702 
13703     /*!
13704     @return The size of the BSON-encoded integer @a value
13705     */
calc_bson_integer_size(const std::int64_t value)13706     static std::size_t calc_bson_integer_size(const std::int64_t value)
13707     {
13708         return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
13709                ? sizeof(std::int32_t)
13710                : sizeof(std::int64_t);
13711     }
13712 
13713     /*!
13714     @brief Writes a BSON element with key @a name and integer @a value
13715     */
write_bson_integer(const string_t & name,const std::int64_t value)13716     void write_bson_integer(const string_t& name,
13717                             const std::int64_t value)
13718     {
13719         if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
13720         {
13721             write_bson_entry_header(name, 0x10); // int32
13722             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13723         }
13724         else
13725         {
13726             write_bson_entry_header(name, 0x12); // int64
13727             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13728         }
13729     }
13730 
13731     /*!
13732     @return The size of the BSON-encoded unsigned integer in @a j
13733     */
calc_bson_unsigned_size(const std::uint64_t value)13734     static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13735     {
13736         return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13737                ? sizeof(std::int32_t)
13738                : sizeof(std::int64_t);
13739     }
13740 
13741     /*!
13742     @brief Writes a BSON element with key @a name and unsigned @a value
13743     */
write_bson_unsigned(const string_t & name,const std::uint64_t value)13744     void write_bson_unsigned(const string_t& name,
13745                              const std::uint64_t value)
13746     {
13747         if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13748         {
13749             write_bson_entry_header(name, 0x10 /* int32 */);
13750             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13751         }
13752         else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13753         {
13754             write_bson_entry_header(name, 0x12 /* int64 */);
13755             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13756         }
13757         else
13758         {
13759             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13760         }
13761     }
13762 
13763     /*!
13764     @brief Writes a BSON element with key @a name and object @a value
13765     */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)13766     void write_bson_object_entry(const string_t& name,
13767                                  const typename BasicJsonType::object_t& value)
13768     {
13769         write_bson_entry_header(name, 0x03); // object
13770         write_bson_object(value);
13771     }
13772 
13773     /*!
13774     @return The size of the BSON-encoded array @a value
13775     */
calc_bson_array_size(const typename BasicJsonType::array_t & value)13776     static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13777     {
13778         std::size_t array_index = 0ul;
13779 
13780         const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
13781         {
13782             return result + calc_bson_element_size(std::to_string(array_index++), el);
13783         });
13784 
13785         return sizeof(std::int32_t) + embedded_document_size + 1ul;
13786     }
13787 
13788     /*!
13789     @return The size of the BSON-encoded binary array @a value
13790     */
calc_bson_binary_size(const typename BasicJsonType::binary_t & value)13791     static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13792     {
13793         return sizeof(std::int32_t) + value.size() + 1ul;
13794     }
13795 
13796     /*!
13797     @brief Writes a BSON element with key @a name and array @a value
13798     */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)13799     void write_bson_array(const string_t& name,
13800                           const typename BasicJsonType::array_t& value)
13801     {
13802         write_bson_entry_header(name, 0x04); // array
13803         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13804 
13805         std::size_t array_index = 0ul;
13806 
13807         for (const auto& el : value)
13808         {
13809             write_bson_element(std::to_string(array_index++), el);
13810         }
13811 
13812         oa->write_character(to_char_type(0x00));
13813     }
13814 
13815     /*!
13816     @brief Writes a BSON element with key @a name and binary value @a value
13817     */
write_bson_binary(const string_t & name,const binary_t & value)13818     void write_bson_binary(const string_t& name,
13819                            const binary_t& value)
13820     {
13821         write_bson_entry_header(name, 0x05);
13822 
13823         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13824         write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13825 
13826         oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13827     }
13828 
13829     /*!
13830     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
13831     @return The calculated size for the BSON document entry for @a j with the given @a name.
13832     */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)13833     static std::size_t calc_bson_element_size(const string_t& name,
13834             const BasicJsonType& j)
13835     {
13836         const auto header_size = calc_bson_entry_header_size(name);
13837         switch (j.type())
13838         {
13839             case value_t::object:
13840                 return header_size + calc_bson_object_size(*j.m_value.object);
13841 
13842             case value_t::array:
13843                 return header_size + calc_bson_array_size(*j.m_value.array);
13844 
13845             case value_t::binary:
13846                 return header_size + calc_bson_binary_size(*j.m_value.binary);
13847 
13848             case value_t::boolean:
13849                 return header_size + 1ul;
13850 
13851             case value_t::number_float:
13852                 return header_size + 8ul;
13853 
13854             case value_t::number_integer:
13855                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13856 
13857             case value_t::number_unsigned:
13858                 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13859 
13860             case value_t::string:
13861                 return header_size + calc_bson_string_size(*j.m_value.string);
13862 
13863             case value_t::null:
13864                 return header_size + 0ul;
13865 
13866             // LCOV_EXCL_START
13867             default:
13868                 JSON_ASSERT(false);
13869                 return 0ul;
13870                 // LCOV_EXCL_STOP
13871         }
13872     }
13873 
13874     /*!
13875     @brief Serializes the JSON value @a j to BSON and associates it with the
13876            key @a name.
13877     @param name The name to associate with the JSON entity @a j within the
13878                 current BSON document
13879     @return The size of the BSON entry
13880     */
write_bson_element(const string_t & name,const BasicJsonType & j)13881     void write_bson_element(const string_t& name,
13882                             const BasicJsonType& j)
13883     {
13884         switch (j.type())
13885         {
13886             case value_t::object:
13887                 return write_bson_object_entry(name, *j.m_value.object);
13888 
13889             case value_t::array:
13890                 return write_bson_array(name, *j.m_value.array);
13891 
13892             case value_t::binary:
13893                 return write_bson_binary(name, *j.m_value.binary);
13894 
13895             case value_t::boolean:
13896                 return write_bson_boolean(name, j.m_value.boolean);
13897 
13898             case value_t::number_float:
13899                 return write_bson_double(name, j.m_value.number_float);
13900 
13901             case value_t::number_integer:
13902                 return write_bson_integer(name, j.m_value.number_integer);
13903 
13904             case value_t::number_unsigned:
13905                 return write_bson_unsigned(name, j.m_value.number_unsigned);
13906 
13907             case value_t::string:
13908                 return write_bson_string(name, *j.m_value.string);
13909 
13910             case value_t::null:
13911                 return write_bson_null(name);
13912 
13913             // LCOV_EXCL_START
13914             default:
13915                 JSON_ASSERT(false);
13916                 return;
13917                 // LCOV_EXCL_STOP
13918         }
13919     }
13920 
13921     /*!
13922     @brief Calculates the size of the BSON serialization of the given
13923            JSON-object @a j.
13924     @param[in] j  JSON value to serialize
13925     @pre       j.type() == value_t::object
13926     */
calc_bson_object_size(const typename BasicJsonType::object_t & value)13927     static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
13928     {
13929         std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
13930                                     [](size_t result, const typename BasicJsonType::object_t::value_type & el)
13931         {
13932             return result += calc_bson_element_size(el.first, el.second);
13933         });
13934 
13935         return sizeof(std::int32_t) + document_size + 1ul;
13936     }
13937 
13938     /*!
13939     @param[in] j  JSON value to serialize
13940     @pre       j.type() == value_t::object
13941     */
write_bson_object(const typename BasicJsonType::object_t & value)13942     void write_bson_object(const typename BasicJsonType::object_t& value)
13943     {
13944         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
13945 
13946         for (const auto& el : value)
13947         {
13948             write_bson_element(el.first, el.second);
13949         }
13950 
13951         oa->write_character(to_char_type(0x00));
13952     }
13953 
13954     //////////
13955     // CBOR //
13956     //////////
13957 
get_cbor_float_prefix(float)13958     static constexpr CharType get_cbor_float_prefix(float /*unused*/)
13959     {
13960         return to_char_type(0xFA);  // Single-Precision Float
13961     }
13962 
get_cbor_float_prefix(double)13963     static constexpr CharType get_cbor_float_prefix(double /*unused*/)
13964     {
13965         return to_char_type(0xFB);  // Double-Precision Float
13966     }
13967 
13968     /////////////
13969     // MsgPack //
13970     /////////////
13971 
get_msgpack_float_prefix(float)13972     static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
13973     {
13974         return to_char_type(0xCA);  // float 32
13975     }
13976 
get_msgpack_float_prefix(double)13977     static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
13978     {
13979         return to_char_type(0xCB);  // float 64
13980     }
13981 
13982     ////////////
13983     // UBJSON //
13984     ////////////
13985 
13986     // UBJSON: write number (floating point)
13987     template<typename NumberType, typename std::enable_if<
13988                  std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)13989     void write_number_with_ubjson_prefix(const NumberType n,
13990                                          const bool add_prefix)
13991     {
13992         if (add_prefix)
13993         {
13994             oa->write_character(get_ubjson_float_prefix(n));
13995         }
13996         write_number(n);
13997     }
13998 
13999     // UBJSON: write number (unsigned integer)
14000     template<typename NumberType, typename std::enable_if<
14001                  std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14002     void write_number_with_ubjson_prefix(const NumberType n,
14003                                          const bool add_prefix)
14004     {
14005         if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14006         {
14007             if (add_prefix)
14008             {
14009                 oa->write_character(to_char_type('i'));  // int8
14010             }
14011             write_number(static_cast<std::uint8_t>(n));
14012         }
14013         else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14014         {
14015             if (add_prefix)
14016             {
14017                 oa->write_character(to_char_type('U'));  // uint8
14018             }
14019             write_number(static_cast<std::uint8_t>(n));
14020         }
14021         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14022         {
14023             if (add_prefix)
14024             {
14025                 oa->write_character(to_char_type('I'));  // int16
14026             }
14027             write_number(static_cast<std::int16_t>(n));
14028         }
14029         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14030         {
14031             if (add_prefix)
14032             {
14033                 oa->write_character(to_char_type('l'));  // int32
14034             }
14035             write_number(static_cast<std::int32_t>(n));
14036         }
14037         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14038         {
14039             if (add_prefix)
14040             {
14041                 oa->write_character(to_char_type('L'));  // int64
14042             }
14043             write_number(static_cast<std::int64_t>(n));
14044         }
14045         else
14046         {
14047             if (add_prefix)
14048             {
14049                 oa->write_character(to_char_type('H'));  // high-precision number
14050             }
14051 
14052             const auto number = BasicJsonType(n).dump();
14053             write_number_with_ubjson_prefix(number.size(), true);
14054             for (std::size_t i = 0; i < number.size(); ++i)
14055             {
14056                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14057             }
14058         }
14059     }
14060 
14061     // UBJSON: write number (signed integer)
14062     template < typename NumberType, typename std::enable_if <
14063                    std::is_signed<NumberType>::value&&
14064                    !std::is_floating_point<NumberType>::value, int >::type = 0 >
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14065     void write_number_with_ubjson_prefix(const NumberType n,
14066                                          const bool add_prefix)
14067     {
14068         if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14069         {
14070             if (add_prefix)
14071             {
14072                 oa->write_character(to_char_type('i'));  // int8
14073             }
14074             write_number(static_cast<std::int8_t>(n));
14075         }
14076         else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
14077         {
14078             if (add_prefix)
14079             {
14080                 oa->write_character(to_char_type('U'));  // uint8
14081             }
14082             write_number(static_cast<std::uint8_t>(n));
14083         }
14084         else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14085         {
14086             if (add_prefix)
14087             {
14088                 oa->write_character(to_char_type('I'));  // int16
14089             }
14090             write_number(static_cast<std::int16_t>(n));
14091         }
14092         else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14093         {
14094             if (add_prefix)
14095             {
14096                 oa->write_character(to_char_type('l'));  // int32
14097             }
14098             write_number(static_cast<std::int32_t>(n));
14099         }
14100         else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14101         {
14102             if (add_prefix)
14103             {
14104                 oa->write_character(to_char_type('L'));  // int64
14105             }
14106             write_number(static_cast<std::int64_t>(n));
14107         }
14108         // LCOV_EXCL_START
14109         else
14110         {
14111             if (add_prefix)
14112             {
14113                 oa->write_character(to_char_type('H'));  // high-precision number
14114             }
14115 
14116             const auto number = BasicJsonType(n).dump();
14117             write_number_with_ubjson_prefix(number.size(), true);
14118             for (std::size_t i = 0; i < number.size(); ++i)
14119             {
14120                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14121             }
14122         }
14123         // LCOV_EXCL_STOP
14124     }
14125 
14126     /*!
14127     @brief determine the type prefix of container values
14128     */
ubjson_prefix(const BasicJsonType & j) const14129     CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14130     {
14131         switch (j.type())
14132         {
14133             case value_t::null:
14134                 return 'Z';
14135 
14136             case value_t::boolean:
14137                 return j.m_value.boolean ? 'T' : 'F';
14138 
14139             case value_t::number_integer:
14140             {
14141                 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14142                 {
14143                     return 'i';
14144                 }
14145                 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14146                 {
14147                     return 'U';
14148                 }
14149                 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14150                 {
14151                     return 'I';
14152                 }
14153                 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14154                 {
14155                     return 'l';
14156                 }
14157                 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14158                 {
14159                     return 'L';
14160                 }
14161                 // anything else is treated as high-precision number
14162                 return 'H'; // LCOV_EXCL_LINE
14163             }
14164 
14165             case value_t::number_unsigned:
14166             {
14167                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14168                 {
14169                     return 'i';
14170                 }
14171                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14172                 {
14173                     return 'U';
14174                 }
14175                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14176                 {
14177                     return 'I';
14178                 }
14179                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14180                 {
14181                     return 'l';
14182                 }
14183                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14184                 {
14185                     return 'L';
14186                 }
14187                 // anything else is treated as high-precision number
14188                 return 'H'; // LCOV_EXCL_LINE
14189             }
14190 
14191             case value_t::number_float:
14192                 return get_ubjson_float_prefix(j.m_value.number_float);
14193 
14194             case value_t::string:
14195                 return 'S';
14196 
14197             case value_t::array: // fallthrough
14198             case value_t::binary:
14199                 return '[';
14200 
14201             case value_t::object:
14202                 return '{';
14203 
14204             default:  // discarded values
14205                 return 'N';
14206         }
14207     }
14208 
get_ubjson_float_prefix(float)14209     static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14210     {
14211         return 'd';  // float 32
14212     }
14213 
get_ubjson_float_prefix(double)14214     static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14215     {
14216         return 'D';  // float 64
14217     }
14218 
14219     ///////////////////////
14220     // Utility functions //
14221     ///////////////////////
14222 
14223     /*
14224     @brief write a number to output input
14225     @param[in] n number of type @a NumberType
14226     @tparam NumberType the type of the number
14227     @tparam OutputIsLittleEndian Set to true if output data is
14228                                  required to be little endian
14229 
14230     @note This function needs to respect the system's endianess, because bytes
14231           in CBOR, MessagePack, and UBJSON are stored in network order (big
14232           endian) and therefore need reordering on little endian systems.
14233     */
14234     template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)14235     void write_number(const NumberType n)
14236     {
14237         // step 1: write number to array of length NumberType
14238         std::array<CharType, sizeof(NumberType)> vec;
14239         std::memcpy(vec.data(), &n, sizeof(NumberType));
14240 
14241         // step 2: write array to output (with possible reordering)
14242         if (is_little_endian != OutputIsLittleEndian)
14243         {
14244             // reverse byte order prior to conversion if necessary
14245             std::reverse(vec.begin(), vec.end());
14246         }
14247 
14248         oa->write_characters(vec.data(), sizeof(NumberType));
14249     }
14250 
write_compact_float(const number_float_t n,detail::input_format_t format)14251     void write_compact_float(const number_float_t n, detail::input_format_t format)
14252     {
14253         if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14254                 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14255                 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14256         {
14257             oa->write_character(format == detail::input_format_t::cbor
14258                                 ? get_cbor_float_prefix(static_cast<float>(n))
14259                                 : get_msgpack_float_prefix(static_cast<float>(n)));
14260             write_number(static_cast<float>(n));
14261         }
14262         else
14263         {
14264             oa->write_character(format == detail::input_format_t::cbor
14265                                 ? get_cbor_float_prefix(n)
14266                                 : get_msgpack_float_prefix(n));
14267             write_number(n);
14268         }
14269     }
14270 
14271   public:
14272     // The following to_char_type functions are implement the conversion
14273     // between uint8_t and CharType. In case CharType is not unsigned,
14274     // such a conversion is required to allow values greater than 128.
14275     // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14276     template < typename C = CharType,
14277                enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)14278     static constexpr CharType to_char_type(std::uint8_t x) noexcept
14279     {
14280         return *reinterpret_cast<char*>(&x);
14281     }
14282 
14283     template < typename C = CharType,
14284                enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)14285     static CharType to_char_type(std::uint8_t x) noexcept
14286     {
14287         static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14288         static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14289         CharType result;
14290         std::memcpy(&result, &x, sizeof(x));
14291         return result;
14292     }
14293 
14294     template<typename C = CharType,
14295              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)14296     static constexpr CharType to_char_type(std::uint8_t x) noexcept
14297     {
14298         return x;
14299     }
14300 
14301     template < typename InputCharType, typename C = CharType,
14302                enable_if_t <
14303                    std::is_signed<C>::value &&
14304                    std::is_signed<char>::value &&
14305                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14306                    > * = nullptr >
to_char_type(InputCharType x)14307     static constexpr CharType to_char_type(InputCharType x) noexcept
14308     {
14309         return x;
14310     }
14311 
14312   private:
14313     /// whether we can assume little endianess
14314     const bool is_little_endian = little_endianess();
14315 
14316     /// the output
14317     output_adapter_t<CharType> oa = nullptr;
14318 };
14319 }  // namespace detail
14320 }  // namespace nlohmann
14321 
14322 // #include <nlohmann/detail/output/output_adapters.hpp>
14323 
14324 // #include <nlohmann/detail/output/serializer.hpp>
14325 
14326 
14327 #include <algorithm> // reverse, remove, fill, find, none_of
14328 #include <array> // array
14329 #include <clocale> // localeconv, lconv
14330 #include <cmath> // labs, isfinite, isnan, signbit
14331 #include <cstddef> // size_t, ptrdiff_t
14332 #include <cstdint> // uint8_t
14333 #include <cstdio> // snprintf
14334 #include <limits> // numeric_limits
14335 #include <string> // string, char_traits
14336 #include <type_traits> // is_same
14337 #include <utility> // move
14338 
14339 // #include <nlohmann/detail/conversions/to_chars.hpp>
14340 
14341 
14342 #include <array> // array
14343 #include <cmath>   // signbit, isfinite
14344 #include <cstdint> // intN_t, uintN_t
14345 #include <cstring> // memcpy, memmove
14346 #include <limits> // numeric_limits
14347 #include <type_traits> // conditional
14348 
14349 // #include <nlohmann/detail/macro_scope.hpp>
14350 
14351 
14352 namespace nlohmann
14353 {
14354 namespace detail
14355 {
14356 
14357 /*!
14358 @brief implements the Grisu2 algorithm for binary to decimal floating-point
14359 conversion.
14360 
14361 This implementation is a slightly modified version of the reference
14362 implementation which may be obtained from
14363 http://florian.loitsch.com/publications (bench.tar.gz).
14364 
14365 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
14366 
14367 For a detailed description of the algorithm see:
14368 
14369 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
14370     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
14371     Language Design and Implementation, PLDI 2010
14372 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
14373     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
14374     Design and Implementation, PLDI 1996
14375 */
14376 namespace dtoa_impl
14377 {
14378 
14379 template<typename Target, typename Source>
14380 Target reinterpret_bits(const Source source)
14381 {
14382     static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14383 
14384     Target target;
14385     std::memcpy(&target, &source, sizeof(Source));
14386     return target;
14387 }
14388 
14389 struct diyfp // f * 2^e
14390 {
14391     static constexpr int kPrecision = 64; // = q
14392 
14393     std::uint64_t f = 0;
14394     int e = 0;
14395 
diyfpnlohmann::detail::dtoa_impl::diyfp14396     constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14397 
14398     /*!
14399     @brief returns x - y
14400     @pre x.e == y.e and x.f >= y.f
14401     */
subnlohmann::detail::dtoa_impl::diyfp14402     static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14403     {
14404         JSON_ASSERT(x.e == y.e);
14405         JSON_ASSERT(x.f >= y.f);
14406 
14407         return {x.f - y.f, x.e};
14408     }
14409 
14410     /*!
14411     @brief returns x * y
14412     @note The result is rounded. (Only the upper q bits are returned.)
14413     */
mulnlohmann::detail::dtoa_impl::diyfp14414     static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14415     {
14416         static_assert(kPrecision == 64, "internal error");
14417 
14418         // Computes:
14419         //  f = round((x.f * y.f) / 2^q)
14420         //  e = x.e + y.e + q
14421 
14422         // Emulate the 64-bit * 64-bit multiplication:
14423         //
14424         // p = u * v
14425         //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14426         //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
14427         //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
14428         //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
14429         //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
14430         //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
14431         //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
14432         //
14433         // (Since Q might be larger than 2^32 - 1)
14434         //
14435         //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14436         //
14437         // (Q_hi + H does not overflow a 64-bit int)
14438         //
14439         //   = p_lo + 2^64 p_hi
14440 
14441         const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14442         const std::uint64_t u_hi = x.f >> 32u;
14443         const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14444         const std::uint64_t v_hi = y.f >> 32u;
14445 
14446         const std::uint64_t p0 = u_lo * v_lo;
14447         const std::uint64_t p1 = u_lo * v_hi;
14448         const std::uint64_t p2 = u_hi * v_lo;
14449         const std::uint64_t p3 = u_hi * v_hi;
14450 
14451         const std::uint64_t p0_hi = p0 >> 32u;
14452         const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14453         const std::uint64_t p1_hi = p1 >> 32u;
14454         const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14455         const std::uint64_t p2_hi = p2 >> 32u;
14456 
14457         std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14458 
14459         // The full product might now be computed as
14460         //
14461         // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14462         // p_lo = p0_lo + (Q << 32)
14463         //
14464         // But in this particular case here, the full p_lo is not required.
14465         // Effectively we only need to add the highest bit in p_lo to p_hi (and
14466         // Q_hi + 1 does not overflow).
14467 
14468         Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14469 
14470         const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14471 
14472         return {h, x.e + y.e + 64};
14473     }
14474 
14475     /*!
14476     @brief normalize x such that the significand is >= 2^(q-1)
14477     @pre x.f != 0
14478     */
normalizenlohmann::detail::dtoa_impl::diyfp14479     static diyfp normalize(diyfp x) noexcept
14480     {
14481         JSON_ASSERT(x.f != 0);
14482 
14483         while ((x.f >> 63u) == 0)
14484         {
14485             x.f <<= 1u;
14486             x.e--;
14487         }
14488 
14489         return x;
14490     }
14491 
14492     /*!
14493     @brief normalize x such that the result has the exponent E
14494     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
14495     */
normalize_tonlohmann::detail::dtoa_impl::diyfp14496     static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14497     {
14498         const int delta = x.e - target_exponent;
14499 
14500         JSON_ASSERT(delta >= 0);
14501         JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14502 
14503         return {x.f << delta, target_exponent};
14504     }
14505 };
14506 
14507 struct boundaries
14508 {
14509     diyfp w;
14510     diyfp minus;
14511     diyfp plus;
14512 };
14513 
14514 /*!
14515 Compute the (normalized) diyfp representing the input number 'value' and its
14516 boundaries.
14517 
14518 @pre value must be finite and positive
14519 */
14520 template<typename FloatType>
compute_boundaries(FloatType value)14521 boundaries compute_boundaries(FloatType value)
14522 {
14523     JSON_ASSERT(std::isfinite(value));
14524     JSON_ASSERT(value > 0);
14525 
14526     // Convert the IEEE representation into a diyfp.
14527     //
14528     // If v is denormal:
14529     //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
14530     // If v is normalized:
14531     //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14532 
14533     static_assert(std::numeric_limits<FloatType>::is_iec559,
14534                   "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14535 
14536     constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14537     constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14538     constexpr int      kMinExp    = 1 - kBias;
14539     constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14540 
14541     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14542 
14543     const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14544     const std::uint64_t E = bits >> (kPrecision - 1);
14545     const std::uint64_t F = bits & (kHiddenBit - 1);
14546 
14547     const bool is_denormal = E == 0;
14548     const diyfp v = is_denormal
14549                     ? diyfp(F, kMinExp)
14550                     : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14551 
14552     // Compute the boundaries m- and m+ of the floating-point value
14553     // v = f * 2^e.
14554     //
14555     // Determine v- and v+, the floating-point predecessor and successor if v,
14556     // respectively.
14557     //
14558     //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
14559     //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
14560     //
14561     //      v+ = v + 2^e
14562     //
14563     // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14564     // between m- and m+ round to v, regardless of how the input rounding
14565     // algorithm breaks ties.
14566     //
14567     //      ---+-------------+-------------+-------------+-------------+---  (A)
14568     //         v-            m-            v             m+            v+
14569     //
14570     //      -----------------+------+------+-------------+-------------+---  (B)
14571     //                       v-     m-     v             m+            v+
14572 
14573     const bool lower_boundary_is_closer = F == 0 && E > 1;
14574     const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14575     const diyfp m_minus = lower_boundary_is_closer
14576                           ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
14577                           : diyfp(2 * v.f - 1, v.e - 1); // (A)
14578 
14579     // Determine the normalized w+ = m+.
14580     const diyfp w_plus = diyfp::normalize(m_plus);
14581 
14582     // Determine w- = m- such that e_(w-) = e_(w+).
14583     const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14584 
14585     return {diyfp::normalize(v), w_minus, w_plus};
14586 }
14587 
14588 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14589 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14590 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14591 //
14592 //      alpha <= e = e_c + e_w + q <= gamma
14593 //
14594 // or
14595 //
14596 //      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14597 //                          <= f_c * f_w * 2^gamma
14598 //
14599 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14600 //
14601 //      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14602 //
14603 // or
14604 //
14605 //      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14606 //
14607 // The choice of (alpha,gamma) determines the size of the table and the form of
14608 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14609 // in practice:
14610 //
14611 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14612 // processed independently: An integral part p1, and a fractional part p2:
14613 //
14614 //      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14615 //              = (f div 2^-e) + (f mod 2^-e) * 2^e
14616 //              = p1 + p2 * 2^e
14617 //
14618 // The conversion of p1 into decimal form requires a series of divisions and
14619 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14620 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14621 // achieved by choosing
14622 //
14623 //      -e >= 32   or   e <= -32 := gamma
14624 //
14625 // In order to convert the fractional part
14626 //
14627 //      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14628 //
14629 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14630 // d[-i] are extracted in order:
14631 //
14632 //      (10 * p2) div 2^-e = d[-1]
14633 //      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14634 //
14635 // The multiplication by 10 must not overflow. It is sufficient to choose
14636 //
14637 //      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14638 //
14639 // Since p2 = f mod 2^-e < 2^-e,
14640 //
14641 //      -e <= 60   or   e >= -60 := alpha
14642 
14643 constexpr int kAlpha = -60;
14644 constexpr int kGamma = -32;
14645 
14646 struct cached_power // c = f * 2^e ~= 10^k
14647 {
14648     std::uint64_t f;
14649     int e;
14650     int k;
14651 };
14652 
14653 /*!
14654 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
14655 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
14656 satisfies (Definition 3.2 from [1])
14657 
14658      alpha <= e_c + e + q <= gamma.
14659 */
get_cached_power_for_binary_exponent(int e)14660 inline cached_power get_cached_power_for_binary_exponent(int e)
14661 {
14662     // Now
14663     //
14664     //      alpha <= e_c + e + q <= gamma                                    (1)
14665     //      ==> f_c * 2^alpha <= c * 2^e * 2^q
14666     //
14667     // and since the c's are normalized, 2^(q-1) <= f_c,
14668     //
14669     //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14670     //      ==> 2^(alpha - e - 1) <= c
14671     //
14672     // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14673     //
14674     //      k = ceil( log_10( 2^(alpha - e - 1) ) )
14675     //        = ceil( (alpha - e - 1) * log_10(2) )
14676     //
14677     // From the paper:
14678     // "In theory the result of the procedure could be wrong since c is rounded,
14679     //  and the computation itself is approximated [...]. In practice, however,
14680     //  this simple function is sufficient."
14681     //
14682     // For IEEE double precision floating-point numbers converted into
14683     // normalized diyfp's w = f * 2^e, with q = 64,
14684     //
14685     //      e >= -1022      (min IEEE exponent)
14686     //           -52        (p - 1)
14687     //           -52        (p - 1, possibly normalize denormal IEEE numbers)
14688     //           -11        (normalize the diyfp)
14689     //         = -1137
14690     //
14691     // and
14692     //
14693     //      e <= +1023      (max IEEE exponent)
14694     //           -52        (p - 1)
14695     //           -11        (normalize the diyfp)
14696     //         = 960
14697     //
14698     // This binary exponent range [-1137,960] results in a decimal exponent
14699     // range [-307,324]. One does not need to store a cached power for each
14700     // k in this range. For each such k it suffices to find a cached power
14701     // such that the exponent of the product lies in [alpha,gamma].
14702     // This implies that the difference of the decimal exponents of adjacent
14703     // table entries must be less than or equal to
14704     //
14705     //      floor( (gamma - alpha) * log_10(2) ) = 8.
14706     //
14707     // (A smaller distance gamma-alpha would require a larger table.)
14708 
14709     // NB:
14710     // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14711 
14712     constexpr int kCachedPowersMinDecExp = -300;
14713     constexpr int kCachedPowersDecStep = 8;
14714 
14715     static constexpr std::array<cached_power, 79> kCachedPowers =
14716     {
14717         {
14718             { 0xAB70FE17C79AC6CA, -1060, -300 },
14719             { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14720             { 0xBE5691EF416BD60C, -1007, -284 },
14721             { 0x8DD01FAD907FFC3C,  -980, -276 },
14722             { 0xD3515C2831559A83,  -954, -268 },
14723             { 0x9D71AC8FADA6C9B5,  -927, -260 },
14724             { 0xEA9C227723EE8BCB,  -901, -252 },
14725             { 0xAECC49914078536D,  -874, -244 },
14726             { 0x823C12795DB6CE57,  -847, -236 },
14727             { 0xC21094364DFB5637,  -821, -228 },
14728             { 0x9096EA6F3848984F,  -794, -220 },
14729             { 0xD77485CB25823AC7,  -768, -212 },
14730             { 0xA086CFCD97BF97F4,  -741, -204 },
14731             { 0xEF340A98172AACE5,  -715, -196 },
14732             { 0xB23867FB2A35B28E,  -688, -188 },
14733             { 0x84C8D4DFD2C63F3B,  -661, -180 },
14734             { 0xC5DD44271AD3CDBA,  -635, -172 },
14735             { 0x936B9FCEBB25C996,  -608, -164 },
14736             { 0xDBAC6C247D62A584,  -582, -156 },
14737             { 0xA3AB66580D5FDAF6,  -555, -148 },
14738             { 0xF3E2F893DEC3F126,  -529, -140 },
14739             { 0xB5B5ADA8AAFF80B8,  -502, -132 },
14740             { 0x87625F056C7C4A8B,  -475, -124 },
14741             { 0xC9BCFF6034C13053,  -449, -116 },
14742             { 0x964E858C91BA2655,  -422, -108 },
14743             { 0xDFF9772470297EBD,  -396, -100 },
14744             { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
14745             { 0xF8A95FCF88747D94,  -343,  -84 },
14746             { 0xB94470938FA89BCF,  -316,  -76 },
14747             { 0x8A08F0F8BF0F156B,  -289,  -68 },
14748             { 0xCDB02555653131B6,  -263,  -60 },
14749             { 0x993FE2C6D07B7FAC,  -236,  -52 },
14750             { 0xE45C10C42A2B3B06,  -210,  -44 },
14751             { 0xAA242499697392D3,  -183,  -36 },
14752             { 0xFD87B5F28300CA0E,  -157,  -28 },
14753             { 0xBCE5086492111AEB,  -130,  -20 },
14754             { 0x8CBCCC096F5088CC,  -103,  -12 },
14755             { 0xD1B71758E219652C,   -77,   -4 },
14756             { 0x9C40000000000000,   -50,    4 },
14757             { 0xE8D4A51000000000,   -24,   12 },
14758             { 0xAD78EBC5AC620000,     3,   20 },
14759             { 0x813F3978F8940984,    30,   28 },
14760             { 0xC097CE7BC90715B3,    56,   36 },
14761             { 0x8F7E32CE7BEA5C70,    83,   44 },
14762             { 0xD5D238A4ABE98068,   109,   52 },
14763             { 0x9F4F2726179A2245,   136,   60 },
14764             { 0xED63A231D4C4FB27,   162,   68 },
14765             { 0xB0DE65388CC8ADA8,   189,   76 },
14766             { 0x83C7088E1AAB65DB,   216,   84 },
14767             { 0xC45D1DF942711D9A,   242,   92 },
14768             { 0x924D692CA61BE758,   269,  100 },
14769             { 0xDA01EE641A708DEA,   295,  108 },
14770             { 0xA26DA3999AEF774A,   322,  116 },
14771             { 0xF209787BB47D6B85,   348,  124 },
14772             { 0xB454E4A179DD1877,   375,  132 },
14773             { 0x865B86925B9BC5C2,   402,  140 },
14774             { 0xC83553C5C8965D3D,   428,  148 },
14775             { 0x952AB45CFA97A0B3,   455,  156 },
14776             { 0xDE469FBD99A05FE3,   481,  164 },
14777             { 0xA59BC234DB398C25,   508,  172 },
14778             { 0xF6C69A72A3989F5C,   534,  180 },
14779             { 0xB7DCBF5354E9BECE,   561,  188 },
14780             { 0x88FCF317F22241E2,   588,  196 },
14781             { 0xCC20CE9BD35C78A5,   614,  204 },
14782             { 0x98165AF37B2153DF,   641,  212 },
14783             { 0xE2A0B5DC971F303A,   667,  220 },
14784             { 0xA8D9D1535CE3B396,   694,  228 },
14785             { 0xFB9B7CD9A4A7443C,   720,  236 },
14786             { 0xBB764C4CA7A44410,   747,  244 },
14787             { 0x8BAB8EEFB6409C1A,   774,  252 },
14788             { 0xD01FEF10A657842C,   800,  260 },
14789             { 0x9B10A4E5E9913129,   827,  268 },
14790             { 0xE7109BFBA19C0C9D,   853,  276 },
14791             { 0xAC2820D9623BF429,   880,  284 },
14792             { 0x80444B5E7AA7CF85,   907,  292 },
14793             { 0xBF21E44003ACDD2D,   933,  300 },
14794             { 0x8E679C2F5E44FF8F,   960,  308 },
14795             { 0xD433179D9C8CB841,   986,  316 },
14796             { 0x9E19DB92B4E31BA9,  1013,  324 },
14797         }
14798     };
14799 
14800     // This computation gives exactly the same results for k as
14801     //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14802     // for |e| <= 1500, but doesn't require floating-point operations.
14803     // NB: log_10(2) ~= 78913 / 2^18
14804     JSON_ASSERT(e >= -1500);
14805     JSON_ASSERT(e <=  1500);
14806     const int f = kAlpha - e - 1;
14807     const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14808 
14809     const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14810     JSON_ASSERT(index >= 0);
14811     JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14812 
14813     const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14814     JSON_ASSERT(kAlpha <= cached.e + e + 64);
14815     JSON_ASSERT(kGamma >= cached.e + e + 64);
14816 
14817     return cached;
14818 }
14819 
14820 /*!
14821 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
14822 For n == 0, returns 1 and sets pow10 := 1.
14823 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)14824 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14825 {
14826     // LCOV_EXCL_START
14827     if (n >= 1000000000)
14828     {
14829         pow10 = 1000000000;
14830         return 10;
14831     }
14832     // LCOV_EXCL_STOP
14833     else if (n >= 100000000)
14834     {
14835         pow10 = 100000000;
14836         return  9;
14837     }
14838     else if (n >= 10000000)
14839     {
14840         pow10 = 10000000;
14841         return  8;
14842     }
14843     else if (n >= 1000000)
14844     {
14845         pow10 = 1000000;
14846         return  7;
14847     }
14848     else if (n >= 100000)
14849     {
14850         pow10 = 100000;
14851         return  6;
14852     }
14853     else if (n >= 10000)
14854     {
14855         pow10 = 10000;
14856         return  5;
14857     }
14858     else if (n >= 1000)
14859     {
14860         pow10 = 1000;
14861         return  4;
14862     }
14863     else if (n >= 100)
14864     {
14865         pow10 = 100;
14866         return  3;
14867     }
14868     else if (n >= 10)
14869     {
14870         pow10 = 10;
14871         return  2;
14872     }
14873     else
14874     {
14875         pow10 = 1;
14876         return 1;
14877     }
14878 }
14879 
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)14880 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14881                          std::uint64_t rest, std::uint64_t ten_k)
14882 {
14883     JSON_ASSERT(len >= 1);
14884     JSON_ASSERT(dist <= delta);
14885     JSON_ASSERT(rest <= delta);
14886     JSON_ASSERT(ten_k > 0);
14887 
14888     //               <--------------------------- delta ---->
14889     //                                  <---- dist --------->
14890     // --------------[------------------+-------------------]--------------
14891     //               M-                 w                   M+
14892     //
14893     //                                  ten_k
14894     //                                <------>
14895     //                                       <---- rest ---->
14896     // --------------[------------------+----+--------------]--------------
14897     //                                  w    V
14898     //                                       = buf * 10^k
14899     //
14900     // ten_k represents a unit-in-the-last-place in the decimal representation
14901     // stored in buf.
14902     // Decrement buf by ten_k while this takes buf closer to w.
14903 
14904     // The tests are written in this order to avoid overflow in unsigned
14905     // integer arithmetic.
14906 
14907     while (rest < dist
14908             && delta - rest >= ten_k
14909             && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14910     {
14911         JSON_ASSERT(buf[len - 1] != '0');
14912         buf[len - 1]--;
14913         rest += ten_k;
14914     }
14915 }
14916 
14917 /*!
14918 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
14919 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
14920 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)14921 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14922                              diyfp M_minus, diyfp w, diyfp M_plus)
14923 {
14924     static_assert(kAlpha >= -60, "internal error");
14925     static_assert(kGamma <= -32, "internal error");
14926 
14927     // Generates the digits (and the exponent) of a decimal floating-point
14928     // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
14929     // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
14930     //
14931     //               <--------------------------- delta ---->
14932     //                                  <---- dist --------->
14933     // --------------[------------------+-------------------]--------------
14934     //               M-                 w                   M+
14935     //
14936     // Grisu2 generates the digits of M+ from left to right and stops as soon as
14937     // V is in [M-,M+].
14938 
14939     JSON_ASSERT(M_plus.e >= kAlpha);
14940     JSON_ASSERT(M_plus.e <= kGamma);
14941 
14942     std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
14943     std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
14944 
14945     // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
14946     //
14947     //      M+ = f * 2^e
14948     //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
14949     //         = ((p1        ) * 2^-e + (p2        )) * 2^e
14950     //         = p1 + p2 * 2^e
14951 
14952     const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
14953 
14954     auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
14955     std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
14956 
14957     // 1)
14958     //
14959     // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
14960 
14961     JSON_ASSERT(p1 > 0);
14962 
14963     std::uint32_t pow10;
14964     const int k = find_largest_pow10(p1, pow10);
14965 
14966     //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
14967     //
14968     //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
14969     //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
14970     //
14971     //      M+ = p1                                             + p2 * 2^e
14972     //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
14973     //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
14974     //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
14975     //
14976     // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
14977     //
14978     //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
14979     //
14980     // but stop as soon as
14981     //
14982     //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
14983 
14984     int n = k;
14985     while (n > 0)
14986     {
14987         // Invariants:
14988         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
14989         //      pow10 = 10^(n-1) <= p1 < 10^n
14990         //
14991         const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
14992         const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
14993         //
14994         //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
14995         //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
14996         //
14997         JSON_ASSERT(d <= 9);
14998         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
14999         //
15000         //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15001         //
15002         p1 = r;
15003         n--;
15004         //
15005         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
15006         //      pow10 = 10^n
15007         //
15008 
15009         // Now check if enough digits have been generated.
15010         // Compute
15011         //
15012         //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15013         //
15014         // Note:
15015         // Since rest and delta share the same exponent e, it suffices to
15016         // compare the significands.
15017         const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15018         if (rest <= delta)
15019         {
15020             // V = buffer * 10^n, with M- <= V <= M+.
15021 
15022             decimal_exponent += n;
15023 
15024             // We may now just stop. But instead look if the buffer could be
15025             // decremented to bring V closer to w.
15026             //
15027             // pow10 = 10^n is now 1 ulp in the decimal representation V.
15028             // The rounding procedure works with diyfp's with an implicit
15029             // exponent of e.
15030             //
15031             //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15032             //
15033             const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15034             grisu2_round(buffer, length, dist, delta, rest, ten_n);
15035 
15036             return;
15037         }
15038 
15039         pow10 /= 10;
15040         //
15041         //      pow10 = 10^(n-1) <= p1 < 10^n
15042         // Invariants restored.
15043     }
15044 
15045     // 2)
15046     //
15047     // The digits of the integral part have been generated:
15048     //
15049     //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15050     //         = buffer            + p2 * 2^e
15051     //
15052     // Now generate the digits of the fractional part p2 * 2^e.
15053     //
15054     // Note:
15055     // No decimal point is generated: the exponent is adjusted instead.
15056     //
15057     // p2 actually represents the fraction
15058     //
15059     //      p2 * 2^e
15060     //          = p2 / 2^-e
15061     //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
15062     //
15063     // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15064     //
15065     //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15066     //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15067     //
15068     // using
15069     //
15070     //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15071     //                = (                   d) * 2^-e + (                   r)
15072     //
15073     // or
15074     //      10^m * p2 * 2^e = d + r * 2^e
15075     //
15076     // i.e.
15077     //
15078     //      M+ = buffer + p2 * 2^e
15079     //         = buffer + 10^-m * (d + r * 2^e)
15080     //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15081     //
15082     // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15083 
15084     JSON_ASSERT(p2 > delta);
15085 
15086     int m = 0;
15087     for (;;)
15088     {
15089         // Invariant:
15090         //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15091         //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
15092         //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
15093         //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15094         //
15095         JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15096         p2 *= 10;
15097         const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
15098         const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15099         //
15100         //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15101         //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15102         //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15103         //
15104         JSON_ASSERT(d <= 9);
15105         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15106         //
15107         //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15108         //
15109         p2 = r;
15110         m++;
15111         //
15112         //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15113         // Invariant restored.
15114 
15115         // Check if enough digits have been generated.
15116         //
15117         //      10^-m * p2 * 2^e <= delta * 2^e
15118         //              p2 * 2^e <= 10^m * delta * 2^e
15119         //                    p2 <= 10^m * delta
15120         delta *= 10;
15121         dist  *= 10;
15122         if (p2 <= delta)
15123         {
15124             break;
15125         }
15126     }
15127 
15128     // V = buffer * 10^-m, with M- <= V <= M+.
15129 
15130     decimal_exponent -= m;
15131 
15132     // 1 ulp in the decimal representation is now 10^-m.
15133     // Since delta and dist are now scaled by 10^m, we need to do the
15134     // same with ulp in order to keep the units in sync.
15135     //
15136     //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15137     //
15138     const std::uint64_t ten_m = one.f;
15139     grisu2_round(buffer, length, dist, delta, p2, ten_m);
15140 
15141     // By construction this algorithm generates the shortest possible decimal
15142     // number (Loitsch, Theorem 6.2) which rounds back to w.
15143     // For an input number of precision p, at least
15144     //
15145     //      N = 1 + ceil(p * log_10(2))
15146     //
15147     // decimal digits are sufficient to identify all binary floating-point
15148     // numbers (Matula, "In-and-Out conversions").
15149     // This implies that the algorithm does not produce more than N decimal
15150     // digits.
15151     //
15152     //      N = 17 for p = 53 (IEEE double precision)
15153     //      N = 9  for p = 24 (IEEE single precision)
15154 }
15155 
15156 /*!
15157 v = buf * 10^decimal_exponent
15158 len is the length of the buffer (number of decimal digits)
15159 The buffer must be large enough, i.e. >= max_digits10.
15160 */
15161 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)15162 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15163                    diyfp m_minus, diyfp v, diyfp m_plus)
15164 {
15165     JSON_ASSERT(m_plus.e == m_minus.e);
15166     JSON_ASSERT(m_plus.e == v.e);
15167 
15168     //  --------(-----------------------+-----------------------)--------    (A)
15169     //          m-                      v                       m+
15170     //
15171     //  --------------------(-----------+-----------------------)--------    (B)
15172     //                      m-          v                       m+
15173     //
15174     // First scale v (and m- and m+) such that the exponent is in the range
15175     // [alpha, gamma].
15176 
15177     const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15178 
15179     const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15180 
15181     // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15182     const diyfp w       = diyfp::mul(v,       c_minus_k);
15183     const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15184     const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
15185 
15186     //  ----(---+---)---------------(---+---)---------------(---+---)----
15187     //          w-                      w                       w+
15188     //          = c*m-                  = c*v                   = c*m+
15189     //
15190     // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15191     // w+ are now off by a small amount.
15192     // In fact:
15193     //
15194     //      w - v * 10^k < 1 ulp
15195     //
15196     // To account for this inaccuracy, add resp. subtract 1 ulp.
15197     //
15198     //  --------+---[---------------(---+---)---------------]---+--------
15199     //          w-  M-                  w                   M+  w+
15200     //
15201     // Now any number in [M-, M+] (bounds included) will round to w when input,
15202     // regardless of how the input rounding algorithm breaks ties.
15203     //
15204     // And digit_gen generates the shortest possible such number in [M-, M+].
15205     // Note that this does not mean that Grisu2 always generates the shortest
15206     // possible number in the interval (m-, m+).
15207     const diyfp M_minus(w_minus.f + 1, w_minus.e);
15208     const diyfp M_plus (w_plus.f  - 1, w_plus.e );
15209 
15210     decimal_exponent = -cached.k; // = -(-k) = k
15211 
15212     grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15213 }
15214 
15215 /*!
15216 v = buf * 10^decimal_exponent
15217 len is the length of the buffer (number of decimal digits)
15218 The buffer must be large enough, i.e. >= max_digits10.
15219 */
15220 template<typename FloatType>
15221 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)15222 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15223 {
15224     static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15225                   "internal error: not enough precision");
15226 
15227     JSON_ASSERT(std::isfinite(value));
15228     JSON_ASSERT(value > 0);
15229 
15230     // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15231     // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15232     // decimal representations are not exactly "short".
15233     //
15234     // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15235     // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15236     // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15237     // does.
15238     // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15239     // representation using the corresponding std::from_chars function recovers value exactly". That
15240     // indicates that single precision floating-point numbers should be recovered using
15241     // 'std::strtof'.
15242     //
15243     // NB: If the neighbors are computed for single-precision numbers, there is a single float
15244     //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15245     //     value is off by 1 ulp.
15246 #if 0
15247     const boundaries w = compute_boundaries(static_cast<double>(value));
15248 #else
15249     const boundaries w = compute_boundaries(value);
15250 #endif
15251 
15252     grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15253 }
15254 
15255 /*!
15256 @brief appends a decimal representation of e to buf
15257 @return a pointer to the element following the exponent.
15258 @pre -1000 < e < 1000
15259 */
15260 JSON_HEDLEY_NON_NULL(1)
15261 JSON_HEDLEY_RETURNS_NON_NULL
append_exponent(char * buf,int e)15262 inline char* append_exponent(char* buf, int e)
15263 {
15264     JSON_ASSERT(e > -1000);
15265     JSON_ASSERT(e <  1000);
15266 
15267     if (e < 0)
15268     {
15269         e = -e;
15270         *buf++ = '-';
15271     }
15272     else
15273     {
15274         *buf++ = '+';
15275     }
15276 
15277     auto k = static_cast<std::uint32_t>(e);
15278     if (k < 10)
15279     {
15280         // Always print at least two digits in the exponent.
15281         // This is for compatibility with printf("%g").
15282         *buf++ = '0';
15283         *buf++ = static_cast<char>('0' + k);
15284     }
15285     else if (k < 100)
15286     {
15287         *buf++ = static_cast<char>('0' + k / 10);
15288         k %= 10;
15289         *buf++ = static_cast<char>('0' + k);
15290     }
15291     else
15292     {
15293         *buf++ = static_cast<char>('0' + k / 100);
15294         k %= 100;
15295         *buf++ = static_cast<char>('0' + k / 10);
15296         k %= 10;
15297         *buf++ = static_cast<char>('0' + k);
15298     }
15299 
15300     return buf;
15301 }
15302 
15303 /*!
15304 @brief prettify v = buf * 10^decimal_exponent
15305 
15306 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
15307 notation. Otherwise it will be printed in exponential notation.
15308 
15309 @pre min_exp < 0
15310 @pre max_exp > 0
15311 */
15312 JSON_HEDLEY_NON_NULL(1)
15313 JSON_HEDLEY_RETURNS_NON_NULL
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)15314 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15315                            int min_exp, int max_exp)
15316 {
15317     JSON_ASSERT(min_exp < 0);
15318     JSON_ASSERT(max_exp > 0);
15319 
15320     const int k = len;
15321     const int n = len + decimal_exponent;
15322 
15323     // v = buf * 10^(n-k)
15324     // k is the length of the buffer (number of decimal digits)
15325     // n is the position of the decimal point relative to the start of the buffer.
15326 
15327     if (k <= n && n <= max_exp)
15328     {
15329         // digits[000]
15330         // len <= max_exp + 2
15331 
15332         std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15333         // Make it look like a floating-point number (#362, #378)
15334         buf[n + 0] = '.';
15335         buf[n + 1] = '0';
15336         return buf + (static_cast<size_t>(n) + 2);
15337     }
15338 
15339     if (0 < n && n <= max_exp)
15340     {
15341         // dig.its
15342         // len <= max_digits10 + 1
15343 
15344         JSON_ASSERT(k > n);
15345 
15346         std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15347         buf[n] = '.';
15348         return buf + (static_cast<size_t>(k) + 1U);
15349     }
15350 
15351     if (min_exp < n && n <= 0)
15352     {
15353         // 0.[000]digits
15354         // len <= 2 + (-min_exp - 1) + max_digits10
15355 
15356         std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15357         buf[0] = '0';
15358         buf[1] = '.';
15359         std::memset(buf + 2, '0', static_cast<size_t>(-n));
15360         return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15361     }
15362 
15363     if (k == 1)
15364     {
15365         // dE+123
15366         // len <= 1 + 5
15367 
15368         buf += 1;
15369     }
15370     else
15371     {
15372         // d.igitsE+123
15373         // len <= max_digits10 + 1 + 5
15374 
15375         std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15376         buf[1] = '.';
15377         buf += 1 + static_cast<size_t>(k);
15378     }
15379 
15380     *buf++ = 'e';
15381     return append_exponent(buf, n - 1);
15382 }
15383 
15384 } // namespace dtoa_impl
15385 
15386 /*!
15387 @brief generates a decimal representation of the floating-point number value in [first, last).
15388 
15389 The format of the resulting decimal representation is similar to printf's %g
15390 format. Returns an iterator pointing past-the-end of the decimal representation.
15391 
15392 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
15393 @note The buffer must be large enough.
15394 @note The result is NOT null-terminated.
15395 */
15396 template<typename FloatType>
15397 JSON_HEDLEY_NON_NULL(1, 2)
15398 JSON_HEDLEY_RETURNS_NON_NULL
to_chars(char * first,const char * last,FloatType value)15399 char* to_chars(char* first, const char* last, FloatType value)
15400 {
15401     static_cast<void>(last); // maybe unused - fix warning
15402     JSON_ASSERT(std::isfinite(value));
15403 
15404     // Use signbit(value) instead of (value < 0) since signbit works for -0.
15405     if (std::signbit(value))
15406     {
15407         value = -value;
15408         *first++ = '-';
15409     }
15410 
15411     if (value == 0) // +-0
15412     {
15413         *first++ = '0';
15414         // Make it look like a floating-point number (#362, #378)
15415         *first++ = '.';
15416         *first++ = '0';
15417         return first;
15418     }
15419 
15420     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15421 
15422     // Compute v = buffer * 10^decimal_exponent.
15423     // The decimal digits are stored in the buffer, which needs to be interpreted
15424     // as an unsigned decimal integer.
15425     // len is the length of the buffer, i.e. the number of decimal digits.
15426     int len = 0;
15427     int decimal_exponent = 0;
15428     dtoa_impl::grisu2(first, len, decimal_exponent, value);
15429 
15430     JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15431 
15432     // Format the buffer like printf("%.*g", prec, value)
15433     constexpr int kMinExp = -4;
15434     // Use digits10 here to increase compatibility with version 2.
15435     constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15436 
15437     JSON_ASSERT(last - first >= kMaxExp + 2);
15438     JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15439     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15440 
15441     return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15442 }
15443 
15444 } // namespace detail
15445 } // namespace nlohmann
15446 
15447 // #include <nlohmann/detail/exceptions.hpp>
15448 
15449 // #include <nlohmann/detail/macro_scope.hpp>
15450 
15451 // #include <nlohmann/detail/meta/cpp_future.hpp>
15452 
15453 // #include <nlohmann/detail/output/binary_writer.hpp>
15454 
15455 // #include <nlohmann/detail/output/output_adapters.hpp>
15456 
15457 // #include <nlohmann/detail/value_t.hpp>
15458 
15459 
15460 namespace nlohmann
15461 {
15462 namespace detail
15463 {
15464 ///////////////////
15465 // serialization //
15466 ///////////////////
15467 
15468 /// how to treat decoding errors
15469 enum class error_handler_t
15470 {
15471     strict,  ///< throw a type_error exception in case of invalid UTF-8
15472     replace, ///< replace invalid UTF-8 sequences with U+FFFD
15473     ignore   ///< ignore invalid UTF-8 sequences
15474 };
15475 
15476 template<typename BasicJsonType>
15477 class serializer
15478 {
15479     using string_t = typename BasicJsonType::string_t;
15480     using number_float_t = typename BasicJsonType::number_float_t;
15481     using number_integer_t = typename BasicJsonType::number_integer_t;
15482     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15483     using binary_char_t = typename BasicJsonType::binary_t::value_type;
15484     static constexpr std::uint8_t UTF8_ACCEPT = 0;
15485     static constexpr std::uint8_t UTF8_REJECT = 1;
15486 
15487   public:
15488     /*!
15489     @param[in] s  output stream to serialize to
15490     @param[in] ichar  indentation character to use
15491     @param[in] error_handler_  how to react on decoding errors
15492     */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)15493     serializer(output_adapter_t<char> s, const char ichar,
15494                error_handler_t error_handler_ = error_handler_t::strict)
15495         : o(std::move(s))
15496         , loc(std::localeconv())
15497         , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15498         , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15499         , indent_char(ichar)
15500         , indent_string(512, indent_char)
15501         , error_handler(error_handler_)
15502     {}
15503 
15504     // delete because of pointer members
15505     serializer(const serializer&) = delete;
15506     serializer& operator=(const serializer&) = delete;
15507     serializer(serializer&&) = delete;
15508     serializer& operator=(serializer&&) = delete;
15509     ~serializer() = default;
15510 
15511     /*!
15512     @brief internal implementation of the serialization function
15513 
15514     This function is called by the public member function dump and organizes
15515     the serialization internally. The indentation level is propagated as
15516     additional parameter. In case of arrays and objects, the function is
15517     called recursively.
15518 
15519     - strings and object keys are escaped using `escape_string()`
15520     - integer numbers are converted implicitly via `operator<<`
15521     - floating-point numbers are converted to a string using `"%g"` format
15522     - binary values are serialized as objects containing the subtype and the
15523       byte array
15524 
15525     @param[in] val               value to serialize
15526     @param[in] pretty_print      whether the output shall be pretty-printed
15527     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
15528     in the output are escaped with `\uXXXX` sequences, and the result consists
15529     of ASCII characters only.
15530     @param[in] indent_step       the indent level
15531     @param[in] current_indent    the current indent level (only used internally)
15532     */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)15533     void dump(const BasicJsonType& val,
15534               const bool pretty_print,
15535               const bool ensure_ascii,
15536               const unsigned int indent_step,
15537               const unsigned int current_indent = 0)
15538     {
15539         switch (val.m_type)
15540         {
15541             case value_t::object:
15542             {
15543                 if (val.m_value.object->empty())
15544                 {
15545                     o->write_characters("{}", 2);
15546                     return;
15547                 }
15548 
15549                 if (pretty_print)
15550                 {
15551                     o->write_characters("{\n", 2);
15552 
15553                     // variable to hold indentation for recursive calls
15554                     const auto new_indent = current_indent + indent_step;
15555                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15556                     {
15557                         indent_string.resize(indent_string.size() * 2, ' ');
15558                     }
15559 
15560                     // first n-1 elements
15561                     auto i = val.m_value.object->cbegin();
15562                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15563                     {
15564                         o->write_characters(indent_string.c_str(), new_indent);
15565                         o->write_character('\"');
15566                         dump_escaped(i->first, ensure_ascii);
15567                         o->write_characters("\": ", 3);
15568                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
15569                         o->write_characters(",\n", 2);
15570                     }
15571 
15572                     // last element
15573                     JSON_ASSERT(i != val.m_value.object->cend());
15574                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15575                     o->write_characters(indent_string.c_str(), new_indent);
15576                     o->write_character('\"');
15577                     dump_escaped(i->first, ensure_ascii);
15578                     o->write_characters("\": ", 3);
15579                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
15580 
15581                     o->write_character('\n');
15582                     o->write_characters(indent_string.c_str(), current_indent);
15583                     o->write_character('}');
15584                 }
15585                 else
15586                 {
15587                     o->write_character('{');
15588 
15589                     // first n-1 elements
15590                     auto i = val.m_value.object->cbegin();
15591                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15592                     {
15593                         o->write_character('\"');
15594                         dump_escaped(i->first, ensure_ascii);
15595                         o->write_characters("\":", 2);
15596                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
15597                         o->write_character(',');
15598                     }
15599 
15600                     // last element
15601                     JSON_ASSERT(i != val.m_value.object->cend());
15602                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15603                     o->write_character('\"');
15604                     dump_escaped(i->first, ensure_ascii);
15605                     o->write_characters("\":", 2);
15606                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
15607 
15608                     o->write_character('}');
15609                 }
15610 
15611                 return;
15612             }
15613 
15614             case value_t::array:
15615             {
15616                 if (val.m_value.array->empty())
15617                 {
15618                     o->write_characters("[]", 2);
15619                     return;
15620                 }
15621 
15622                 if (pretty_print)
15623                 {
15624                     o->write_characters("[\n", 2);
15625 
15626                     // variable to hold indentation for recursive calls
15627                     const auto new_indent = current_indent + indent_step;
15628                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15629                     {
15630                         indent_string.resize(indent_string.size() * 2, ' ');
15631                     }
15632 
15633                     // first n-1 elements
15634                     for (auto i = val.m_value.array->cbegin();
15635                             i != val.m_value.array->cend() - 1; ++i)
15636                     {
15637                         o->write_characters(indent_string.c_str(), new_indent);
15638                         dump(*i, true, ensure_ascii, indent_step, new_indent);
15639                         o->write_characters(",\n", 2);
15640                     }
15641 
15642                     // last element
15643                     JSON_ASSERT(!val.m_value.array->empty());
15644                     o->write_characters(indent_string.c_str(), new_indent);
15645                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15646 
15647                     o->write_character('\n');
15648                     o->write_characters(indent_string.c_str(), current_indent);
15649                     o->write_character(']');
15650                 }
15651                 else
15652                 {
15653                     o->write_character('[');
15654 
15655                     // first n-1 elements
15656                     for (auto i = val.m_value.array->cbegin();
15657                             i != val.m_value.array->cend() - 1; ++i)
15658                     {
15659                         dump(*i, false, ensure_ascii, indent_step, current_indent);
15660                         o->write_character(',');
15661                     }
15662 
15663                     // last element
15664                     JSON_ASSERT(!val.m_value.array->empty());
15665                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15666 
15667                     o->write_character(']');
15668                 }
15669 
15670                 return;
15671             }
15672 
15673             case value_t::string:
15674             {
15675                 o->write_character('\"');
15676                 dump_escaped(*val.m_value.string, ensure_ascii);
15677                 o->write_character('\"');
15678                 return;
15679             }
15680 
15681             case value_t::binary:
15682             {
15683                 if (pretty_print)
15684                 {
15685                     o->write_characters("{\n", 2);
15686 
15687                     // variable to hold indentation for recursive calls
15688                     const auto new_indent = current_indent + indent_step;
15689                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15690                     {
15691                         indent_string.resize(indent_string.size() * 2, ' ');
15692                     }
15693 
15694                     o->write_characters(indent_string.c_str(), new_indent);
15695 
15696                     o->write_characters("\"bytes\": [", 10);
15697 
15698                     if (!val.m_value.binary->empty())
15699                     {
15700                         for (auto i = val.m_value.binary->cbegin();
15701                                 i != val.m_value.binary->cend() - 1; ++i)
15702                         {
15703                             dump_integer(*i);
15704                             o->write_characters(", ", 2);
15705                         }
15706                         dump_integer(val.m_value.binary->back());
15707                     }
15708 
15709                     o->write_characters("],\n", 3);
15710                     o->write_characters(indent_string.c_str(), new_indent);
15711 
15712                     o->write_characters("\"subtype\": ", 11);
15713                     if (val.m_value.binary->has_subtype())
15714                     {
15715                         dump_integer(val.m_value.binary->subtype());
15716                     }
15717                     else
15718                     {
15719                         o->write_characters("null", 4);
15720                     }
15721                     o->write_character('\n');
15722                     o->write_characters(indent_string.c_str(), current_indent);
15723                     o->write_character('}');
15724                 }
15725                 else
15726                 {
15727                     o->write_characters("{\"bytes\":[", 10);
15728 
15729                     if (!val.m_value.binary->empty())
15730                     {
15731                         for (auto i = val.m_value.binary->cbegin();
15732                                 i != val.m_value.binary->cend() - 1; ++i)
15733                         {
15734                             dump_integer(*i);
15735                             o->write_character(',');
15736                         }
15737                         dump_integer(val.m_value.binary->back());
15738                     }
15739 
15740                     o->write_characters("],\"subtype\":", 12);
15741                     if (val.m_value.binary->has_subtype())
15742                     {
15743                         dump_integer(val.m_value.binary->subtype());
15744                         o->write_character('}');
15745                     }
15746                     else
15747                     {
15748                         o->write_characters("null}", 5);
15749                     }
15750                 }
15751                 return;
15752             }
15753 
15754             case value_t::boolean:
15755             {
15756                 if (val.m_value.boolean)
15757                 {
15758                     o->write_characters("true", 4);
15759                 }
15760                 else
15761                 {
15762                     o->write_characters("false", 5);
15763                 }
15764                 return;
15765             }
15766 
15767             case value_t::number_integer:
15768             {
15769                 dump_integer(val.m_value.number_integer);
15770                 return;
15771             }
15772 
15773             case value_t::number_unsigned:
15774             {
15775                 dump_integer(val.m_value.number_unsigned);
15776                 return;
15777             }
15778 
15779             case value_t::number_float:
15780             {
15781                 dump_float(val.m_value.number_float);
15782                 return;
15783             }
15784 
15785             case value_t::discarded:
15786             {
15787                 o->write_characters("<discarded>", 11);
15788                 return;
15789             }
15790 
15791             case value_t::null:
15792             {
15793                 o->write_characters("null", 4);
15794                 return;
15795             }
15796 
15797             default:            // LCOV_EXCL_LINE
15798                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
15799         }
15800     }
15801 
15802   private:
15803     /*!
15804     @brief dump escaped string
15805 
15806     Escape a string by replacing certain special characters by a sequence of an
15807     escape character (backslash) and another character and other control
15808     characters by a sequence of "\u" followed by a four-digit hex
15809     representation. The escaped string is written to output stream @a o.
15810 
15811     @param[in] s  the string to escape
15812     @param[in] ensure_ascii  whether to escape non-ASCII characters with
15813                              \uXXXX sequences
15814 
15815     @complexity Linear in the length of string @a s.
15816     */
dump_escaped(const string_t & s,const bool ensure_ascii)15817     void dump_escaped(const string_t& s, const bool ensure_ascii)
15818     {
15819         std::uint32_t codepoint;
15820         std::uint8_t state = UTF8_ACCEPT;
15821         std::size_t bytes = 0;  // number of bytes written to string_buffer
15822 
15823         // number of bytes written at the point of the last valid byte
15824         std::size_t bytes_after_last_accept = 0;
15825         std::size_t undumped_chars = 0;
15826 
15827         for (std::size_t i = 0; i < s.size(); ++i)
15828         {
15829             const auto byte = static_cast<uint8_t>(s[i]);
15830 
15831             switch (decode(state, codepoint, byte))
15832             {
15833                 case UTF8_ACCEPT:  // decode found a new code point
15834                 {
15835                     switch (codepoint)
15836                     {
15837                         case 0x08: // backspace
15838                         {
15839                             string_buffer[bytes++] = '\\';
15840                             string_buffer[bytes++] = 'b';
15841                             break;
15842                         }
15843 
15844                         case 0x09: // horizontal tab
15845                         {
15846                             string_buffer[bytes++] = '\\';
15847                             string_buffer[bytes++] = 't';
15848                             break;
15849                         }
15850 
15851                         case 0x0A: // newline
15852                         {
15853                             string_buffer[bytes++] = '\\';
15854                             string_buffer[bytes++] = 'n';
15855                             break;
15856                         }
15857 
15858                         case 0x0C: // formfeed
15859                         {
15860                             string_buffer[bytes++] = '\\';
15861                             string_buffer[bytes++] = 'f';
15862                             break;
15863                         }
15864 
15865                         case 0x0D: // carriage return
15866                         {
15867                             string_buffer[bytes++] = '\\';
15868                             string_buffer[bytes++] = 'r';
15869                             break;
15870                         }
15871 
15872                         case 0x22: // quotation mark
15873                         {
15874                             string_buffer[bytes++] = '\\';
15875                             string_buffer[bytes++] = '\"';
15876                             break;
15877                         }
15878 
15879                         case 0x5C: // reverse solidus
15880                         {
15881                             string_buffer[bytes++] = '\\';
15882                             string_buffer[bytes++] = '\\';
15883                             break;
15884                         }
15885 
15886                         default:
15887                         {
15888                             // escape control characters (0x00..0x1F) or, if
15889                             // ensure_ascii parameter is used, non-ASCII characters
15890                             if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15891                             {
15892                                 if (codepoint <= 0xFFFF)
15893                                 {
15894                                     (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15895                                                     static_cast<std::uint16_t>(codepoint));
15896                                     bytes += 6;
15897                                 }
15898                                 else
15899                                 {
15900                                     (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15901                                                     static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15902                                                     static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15903                                     bytes += 12;
15904                                 }
15905                             }
15906                             else
15907                             {
15908                                 // copy byte to buffer (all previous bytes
15909                                 // been copied have in default case above)
15910                                 string_buffer[bytes++] = s[i];
15911                             }
15912                             break;
15913                         }
15914                     }
15915 
15916                     // write buffer and reset index; there must be 13 bytes
15917                     // left, as this is the maximal number of bytes to be
15918                     // written ("\uxxxx\uxxxx\0") for one code point
15919                     if (string_buffer.size() - bytes < 13)
15920                     {
15921                         o->write_characters(string_buffer.data(), bytes);
15922                         bytes = 0;
15923                     }
15924 
15925                     // remember the byte position of this accept
15926                     bytes_after_last_accept = bytes;
15927                     undumped_chars = 0;
15928                     break;
15929                 }
15930 
15931                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
15932                 {
15933                     switch (error_handler)
15934                     {
15935                         case error_handler_t::strict:
15936                         {
15937                             std::string sn(3, '\0');
15938                             (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
15939                             JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
15940                         }
15941 
15942                         case error_handler_t::ignore:
15943                         case error_handler_t::replace:
15944                         {
15945                             // in case we saw this character the first time, we
15946                             // would like to read it again, because the byte
15947                             // may be OK for itself, but just not OK for the
15948                             // previous sequence
15949                             if (undumped_chars > 0)
15950                             {
15951                                 --i;
15952                             }
15953 
15954                             // reset length buffer to the last accepted index;
15955                             // thus removing/ignoring the invalid characters
15956                             bytes = bytes_after_last_accept;
15957 
15958                             if (error_handler == error_handler_t::replace)
15959                             {
15960                                 // add a replacement character
15961                                 if (ensure_ascii)
15962                                 {
15963                                     string_buffer[bytes++] = '\\';
15964                                     string_buffer[bytes++] = 'u';
15965                                     string_buffer[bytes++] = 'f';
15966                                     string_buffer[bytes++] = 'f';
15967                                     string_buffer[bytes++] = 'f';
15968                                     string_buffer[bytes++] = 'd';
15969                                 }
15970                                 else
15971                                 {
15972                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
15973                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
15974                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
15975                                 }
15976 
15977                                 // write buffer and reset index; there must be 13 bytes
15978                                 // left, as this is the maximal number of bytes to be
15979                                 // written ("\uxxxx\uxxxx\0") for one code point
15980                                 if (string_buffer.size() - bytes < 13)
15981                                 {
15982                                     o->write_characters(string_buffer.data(), bytes);
15983                                     bytes = 0;
15984                                 }
15985 
15986                                 bytes_after_last_accept = bytes;
15987                             }
15988 
15989                             undumped_chars = 0;
15990 
15991                             // continue processing the string
15992                             state = UTF8_ACCEPT;
15993                             break;
15994                         }
15995 
15996                         default:            // LCOV_EXCL_LINE
15997                             JSON_ASSERT(false);  // LCOV_EXCL_LINE
15998                     }
15999                     break;
16000                 }
16001 
16002                 default:  // decode found yet incomplete multi-byte code point
16003                 {
16004                     if (!ensure_ascii)
16005                     {
16006                         // code point will not be escaped - copy byte to buffer
16007                         string_buffer[bytes++] = s[i];
16008                     }
16009                     ++undumped_chars;
16010                     break;
16011                 }
16012             }
16013         }
16014 
16015         // we finished processing the string
16016         if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16017         {
16018             // write buffer
16019             if (bytes > 0)
16020             {
16021                 o->write_characters(string_buffer.data(), bytes);
16022             }
16023         }
16024         else
16025         {
16026             // we finish reading, but do not accept: string was incomplete
16027             switch (error_handler)
16028             {
16029                 case error_handler_t::strict:
16030                 {
16031                     std::string sn(3, '\0');
16032                     (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16033                     JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16034                 }
16035 
16036                 case error_handler_t::ignore:
16037                 {
16038                     // write all accepted bytes
16039                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
16040                     break;
16041                 }
16042 
16043                 case error_handler_t::replace:
16044                 {
16045                     // write all accepted bytes
16046                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
16047                     // add a replacement character
16048                     if (ensure_ascii)
16049                     {
16050                         o->write_characters("\\ufffd", 6);
16051                     }
16052                     else
16053                     {
16054                         o->write_characters("\xEF\xBF\xBD", 3);
16055                     }
16056                     break;
16057                 }
16058 
16059                 default:            // LCOV_EXCL_LINE
16060                     JSON_ASSERT(false);  // LCOV_EXCL_LINE
16061             }
16062         }
16063     }
16064 
16065     /*!
16066     @brief count digits
16067 
16068     Count the number of decimal (base 10) digits for an input unsigned integer.
16069 
16070     @param[in] x  unsigned integer number to count its digits
16071     @return    number of decimal digits
16072     */
count_digits(number_unsigned_t x)16073     inline unsigned int count_digits(number_unsigned_t x) noexcept
16074     {
16075         unsigned int n_digits = 1;
16076         for (;;)
16077         {
16078             if (x < 10)
16079             {
16080                 return n_digits;
16081             }
16082             if (x < 100)
16083             {
16084                 return n_digits + 1;
16085             }
16086             if (x < 1000)
16087             {
16088                 return n_digits + 2;
16089             }
16090             if (x < 10000)
16091             {
16092                 return n_digits + 3;
16093             }
16094             x = x / 10000u;
16095             n_digits += 4;
16096         }
16097     }
16098 
16099     /*!
16100     @brief dump an integer
16101 
16102     Dump a given integer to output stream @a o. Works internally with
16103     @a number_buffer.
16104 
16105     @param[in] x  integer number (signed or unsigned) to dump
16106     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
16107     */
16108     template < typename NumberType, detail::enable_if_t <
16109                    std::is_same<NumberType, number_unsigned_t>::value ||
16110                    std::is_same<NumberType, number_integer_t>::value ||
16111                    std::is_same<NumberType, binary_char_t>::value,
16112                    int > = 0 >
dump_integer(NumberType x)16113     void dump_integer(NumberType x)
16114     {
16115         static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16116         {
16117             {
16118                 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16119                 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16120                 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16121                 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16122                 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16123                 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16124                 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16125                 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16126                 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16127                 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16128             }
16129         };
16130 
16131         // special case for "0"
16132         if (x == 0)
16133         {
16134             o->write_character('0');
16135             return;
16136         }
16137 
16138         // use a pointer to fill the buffer
16139         auto buffer_ptr = number_buffer.begin();
16140 
16141         const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16142         number_unsigned_t abs_value;
16143 
16144         unsigned int n_chars;
16145 
16146         if (is_negative)
16147         {
16148             *buffer_ptr = '-';
16149             abs_value = remove_sign(static_cast<number_integer_t>(x));
16150 
16151             // account one more byte for the minus sign
16152             n_chars = 1 + count_digits(abs_value);
16153         }
16154         else
16155         {
16156             abs_value = static_cast<number_unsigned_t>(x);
16157             n_chars = count_digits(abs_value);
16158         }
16159 
16160         // spare 1 byte for '\0'
16161         JSON_ASSERT(n_chars < number_buffer.size() - 1);
16162 
16163         // jump to the end to generate the string from backward
16164         // so we later avoid reversing the result
16165         buffer_ptr += n_chars;
16166 
16167         // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16168         // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16169         while (abs_value >= 100)
16170         {
16171             const auto digits_index = static_cast<unsigned>((abs_value % 100));
16172             abs_value /= 100;
16173             *(--buffer_ptr) = digits_to_99[digits_index][1];
16174             *(--buffer_ptr) = digits_to_99[digits_index][0];
16175         }
16176 
16177         if (abs_value >= 10)
16178         {
16179             const auto digits_index = static_cast<unsigned>(abs_value);
16180             *(--buffer_ptr) = digits_to_99[digits_index][1];
16181             *(--buffer_ptr) = digits_to_99[digits_index][0];
16182         }
16183         else
16184         {
16185             *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16186         }
16187 
16188         o->write_characters(number_buffer.data(), n_chars);
16189     }
16190 
16191     /*!
16192     @brief dump a floating-point number
16193 
16194     Dump a given floating-point number to output stream @a o. Works internally
16195     with @a number_buffer.
16196 
16197     @param[in] x  floating-point number to dump
16198     */
dump_float(number_float_t x)16199     void dump_float(number_float_t x)
16200     {
16201         // NaN / inf
16202         if (!std::isfinite(x))
16203         {
16204             o->write_characters("null", 4);
16205             return;
16206         }
16207 
16208         // If number_float_t is an IEEE-754 single or double precision number,
16209         // use the Grisu2 algorithm to produce short numbers which are
16210         // guaranteed to round-trip, using strtof and strtod, resp.
16211         //
16212         // NB: The test below works if <long double> == <double>.
16213         static constexpr bool is_ieee_single_or_double
16214             = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
16215               (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
16216 
16217         dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16218     }
16219 
dump_float(number_float_t x,std::true_type)16220     void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16221     {
16222         char* begin = number_buffer.data();
16223         char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16224 
16225         o->write_characters(begin, static_cast<size_t>(end - begin));
16226     }
16227 
dump_float(number_float_t x,std::false_type)16228     void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16229     {
16230         // get number of digits for a float -> text -> float round-trip
16231         static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16232 
16233         // the actual conversion
16234         std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16235 
16236         // negative value indicates an error
16237         JSON_ASSERT(len > 0);
16238         // check if buffer was large enough
16239         JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16240 
16241         // erase thousands separator
16242         if (thousands_sep != '\0')
16243         {
16244             const auto end = std::remove(number_buffer.begin(),
16245                                          number_buffer.begin() + len, thousands_sep);
16246             std::fill(end, number_buffer.end(), '\0');
16247             JSON_ASSERT((end - number_buffer.begin()) <= len);
16248             len = (end - number_buffer.begin());
16249         }
16250 
16251         // convert decimal point to '.'
16252         if (decimal_point != '\0' && decimal_point != '.')
16253         {
16254             const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16255             if (dec_pos != number_buffer.end())
16256             {
16257                 *dec_pos = '.';
16258             }
16259         }
16260 
16261         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16262 
16263         // determine if need to append ".0"
16264         const bool value_is_int_like =
16265             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16266                          [](char c)
16267         {
16268             return c == '.' || c == 'e';
16269         });
16270 
16271         if (value_is_int_like)
16272         {
16273             o->write_characters(".0", 2);
16274         }
16275     }
16276 
16277     /*!
16278     @brief check whether a string is UTF-8 encoded
16279 
16280     The function checks each byte of a string whether it is UTF-8 encoded. The
16281     result of the check is stored in the @a state parameter. The function must
16282     be called initially with state 0 (accept). State 1 means the string must
16283     be rejected, because the current byte is not allowed. If the string is
16284     completely processed, but the state is non-zero, the string ended
16285     prematurely; that is, the last byte indicated more bytes should have
16286     followed.
16287 
16288     @param[in,out] state  the state of the decoding
16289     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
16290     @param[in] byte       next byte to decode
16291     @return               new state
16292 
16293     @note The function has been edited: a std::array is used.
16294 
16295     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
16296     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
16297     */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)16298     static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16299     {
16300         static const std::array<std::uint8_t, 400> utf8d =
16301         {
16302             {
16303                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
16304                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
16305                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
16306                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
16307                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
16308                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
16309                 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
16310                 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16311                 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16312                 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16313                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
16314                 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
16315                 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
16316                 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
16317             }
16318         };
16319 
16320         const std::uint8_t type = utf8d[byte];
16321 
16322         codep = (state != UTF8_ACCEPT)
16323                 ? (byte & 0x3fu) | (codep << 6u)
16324                 : (0xFFu >> type) & (byte);
16325 
16326         std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16327         JSON_ASSERT(index < 400);
16328         state = utf8d[index];
16329         return state;
16330     }
16331 
16332     /*
16333      * Overload to make the compiler happy while it is instantiating
16334      * dump_integer for number_unsigned_t.
16335      * Must never be called.
16336      */
remove_sign(number_unsigned_t x)16337     number_unsigned_t remove_sign(number_unsigned_t x)
16338     {
16339         JSON_ASSERT(false); // LCOV_EXCL_LINE
16340         return x; // LCOV_EXCL_LINE
16341     }
16342 
16343     /*
16344      * Helper function for dump_integer
16345      *
16346      * This function takes a negative signed integer and returns its absolute
16347      * value as unsigned integer. The plus/minus shuffling is necessary as we can
16348      * not directly remove the sign of an arbitrary signed integer as the
16349      * absolute values of INT_MIN and INT_MAX are usually not the same. See
16350      * #1708 for details.
16351      */
remove_sign(number_integer_t x)16352     inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16353     {
16354         JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
16355         return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16356     }
16357 
16358   private:
16359     /// the output of the serializer
16360     output_adapter_t<char> o = nullptr;
16361 
16362     /// a (hopefully) large enough character buffer
16363     std::array<char, 64> number_buffer{{}};
16364 
16365     /// the locale
16366     const std::lconv* loc = nullptr;
16367     /// the locale's thousand separator character
16368     const char thousands_sep = '\0';
16369     /// the locale's decimal point character
16370     const char decimal_point = '\0';
16371 
16372     /// string buffer
16373     std::array<char, 512> string_buffer{{}};
16374 
16375     /// the indentation character
16376     const char indent_char;
16377     /// the indentation string
16378     string_t indent_string;
16379 
16380     /// error_handler how to react on decoding errors
16381     const error_handler_t error_handler;
16382 };
16383 }  // namespace detail
16384 }  // namespace nlohmann
16385 
16386 // #include <nlohmann/detail/value_t.hpp>
16387 
16388 // #include <nlohmann/json_fwd.hpp>
16389 
16390 // #include <nlohmann/ordered_map.hpp>
16391 
16392 
16393 #include <functional> // less
16394 #include <memory> // allocator
16395 #include <utility> // pair
16396 #include <vector> // vector
16397 
16398 namespace nlohmann
16399 {
16400 
16401 /// ordered_map: a minimal map-like container that preserves insertion order
16402 /// for use within nlohmann::basic_json<ordered_map>
16403 template <class Key, class T, class IgnoredLess = std::less<Key>,
16404           class Allocator = std::allocator<std::pair<const Key, T>>>
16405                   struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16406 {
16407     using key_type = Key;
16408     using mapped_type = T;
16409     using Container = std::vector<std::pair<const Key, T>, Allocator>;
16410     using typename Container::iterator;
16411     using typename Container::size_type;
16412     using typename Container::value_type;
16413 
16414     // Explicit constructors instead of `using Container::Container`
16415     // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_mapnlohmann::ordered_map16416     ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16417     template <class It>
ordered_mapnlohmann::ordered_map16418     ordered_map(It first, It last, const Allocator& alloc = Allocator())
16419         : Container{first, last, alloc} {}
ordered_mapnlohmann::ordered_map16420     ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16421         : Container{init, alloc} {}
16422 
emplacenlohmann::ordered_map16423     std::pair<iterator, bool> emplace(key_type&& key, T&& t)
16424     {
16425         for (auto it = this->begin(); it != this->end(); ++it)
16426         {
16427             if (it->first == key)
16428             {
16429                 return {it, false};
16430             }
16431         }
16432         Container::emplace_back(key, t);
16433         return {--this->end(), true};
16434     }
16435 
operator []nlohmann::ordered_map16436     T& operator[](Key&& key)
16437     {
16438         return emplace(std::move(key), T{}).first->second;
16439     }
16440 
erasenlohmann::ordered_map16441     size_type erase(const Key& key)
16442     {
16443         for (auto it = this->begin(); it != this->end(); ++it)
16444         {
16445             if (it->first == key)
16446             {
16447                 // Since we cannot move const Keys, re-construct them in place
16448                 for (auto next = it; ++next != this->end(); ++it)
16449                 {
16450                     it->~value_type(); // Destroy but keep allocation
16451                     new (&*it) value_type{std::move(*next)};
16452                 }
16453                 Container::pop_back();
16454                 return 1;
16455             }
16456         }
16457         return 0;
16458     }
16459 };
16460 
16461 }  // namespace nlohmann
16462 
16463 
16464 /*!
16465 @brief namespace for Niels Lohmann
16466 @see https://github.com/nlohmann
16467 @since version 1.0.0
16468 */
16469 namespace nlohmann
16470 {
16471 
16472 /*!
16473 @brief a class to store JSON values
16474 
16475 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
16476 in @ref object_t)
16477 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
16478 in @ref array_t)
16479 @tparam StringType type for JSON strings and object keys (`std::string` by
16480 default; will be used in @ref string_t)
16481 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
16482 in @ref boolean_t)
16483 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
16484 default; will be used in @ref number_integer_t)
16485 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
16486 `uint64_t` by default; will be used in @ref number_unsigned_t)
16487 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
16488 default; will be used in @ref number_float_t)
16489 @tparam BinaryType type for packed binary data for compatibility with binary
16490 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
16491 @ref binary_t)
16492 @tparam AllocatorType type of the allocator to use (`std::allocator` by
16493 default)
16494 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
16495 and `from_json()` (@ref adl_serializer by default)
16496 
16497 @requirement The class satisfies the following concept requirements:
16498 - Basic
16499  - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
16500    JSON values can be default constructed. The result will be a JSON null
16501    value.
16502  - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
16503    A JSON value can be constructed from an rvalue argument.
16504  - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
16505    A JSON value can be copy-constructed from an lvalue expression.
16506  - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
16507    A JSON value van be assigned from an rvalue argument.
16508  - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
16509    A JSON value can be copy-assigned from an lvalue expression.
16510  - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
16511    JSON values can be destructed.
16512 - Layout
16513  - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
16514    JSON values have
16515    [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
16516    All non-static data members are private and standard layout types, the
16517    class has no virtual functions or (virtual) base classes.
16518 - Library-wide
16519  - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
16520    JSON values can be compared with `==`, see @ref
16521    operator==(const_reference,const_reference).
16522  - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
16523    JSON values can be compared with `<`, see @ref
16524    operator<(const_reference,const_reference).
16525  - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
16526    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
16527    other compatible types, using unqualified function call @ref swap().
16528  - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
16529    JSON values can be compared against `std::nullptr_t` objects which are used
16530    to model the `null` value.
16531 - Container
16532  - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
16533    JSON values can be used like STL containers and provide iterator access.
16534  - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
16535    JSON values can be used like STL containers and provide reverse iterator
16536    access.
16537 
16538 @invariant The member variables @a m_value and @a m_type have the following
16539 relationship:
16540 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
16541 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
16542 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
16543 The invariants are checked by member function assert_invariant().
16544 
16545 @internal
16546 @note ObjectType trick from https://stackoverflow.com/a/9860911
16547 @endinternal
16548 
16549 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
16550 Format](http://rfc7159.net/rfc7159)
16551 
16552 @since version 1.0.0
16553 
16554 @nosubgrouping
16555 */
16556 NLOHMANN_BASIC_JSON_TPL_DECLARATION
16557 class basic_json
16558 {
16559   private:
16560     template<detail::value_t> friend struct detail::external_constructor;
16561     friend ::nlohmann::json_pointer<basic_json>;
16562 
16563     template<typename BasicJsonType, typename InputType>
16564     friend class ::nlohmann::detail::parser;
16565     friend ::nlohmann::detail::serializer<basic_json>;
16566     template<typename BasicJsonType>
16567     friend class ::nlohmann::detail::iter_impl;
16568     template<typename BasicJsonType, typename CharType>
16569     friend class ::nlohmann::detail::binary_writer;
16570     template<typename BasicJsonType, typename InputType, typename SAX>
16571     friend class ::nlohmann::detail::binary_reader;
16572     template<typename BasicJsonType>
16573     friend class ::nlohmann::detail::json_sax_dom_parser;
16574     template<typename BasicJsonType>
16575     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16576 
16577     /// workaround type for MSVC
16578     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16579 
16580     // convenience aliases for types residing in namespace detail;
16581     using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16582 
16583     template<typename InputAdapterType>
parser(InputAdapterType adapter,detail::parser_callback_t<basic_json> cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)16584     static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16585         InputAdapterType adapter,
16586         detail::parser_callback_t<basic_json>cb = nullptr,
16587         const bool allow_exceptions = true,
16588         const bool ignore_comments = false
16589                                  )
16590     {
16591         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16592                 std::move(cb), allow_exceptions, ignore_comments);
16593     }
16594 
16595     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16596     template<typename BasicJsonType>
16597     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16598     template<typename BasicJsonType>
16599     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16600     template<typename Iterator>
16601     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16602     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16603 
16604     template<typename CharType>
16605     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16606 
16607     template<typename InputType>
16608     using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16609     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16610 
16611     using serializer = ::nlohmann::detail::serializer<basic_json>;
16612 
16613   public:
16614     using value_t = detail::value_t;
16615     /// JSON Pointer, see @ref nlohmann::json_pointer
16616     using json_pointer = ::nlohmann::json_pointer<basic_json>;
16617     template<typename T, typename SFINAE>
16618     using json_serializer = JSONSerializer<T, SFINAE>;
16619     /// how to treat decoding errors
16620     using error_handler_t = detail::error_handler_t;
16621     /// how to treat CBOR tags
16622     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16623     /// helper type for initializer lists of basic_json values
16624     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16625 
16626     using input_format_t = detail::input_format_t;
16627     /// SAX interface type, see @ref nlohmann::json_sax
16628     using json_sax_t = json_sax<basic_json>;
16629 
16630     ////////////////
16631     // exceptions //
16632     ////////////////
16633 
16634     /// @name exceptions
16635     /// Classes to implement user-defined exceptions.
16636     /// @{
16637 
16638     /// @copydoc detail::exception
16639     using exception = detail::exception;
16640     /// @copydoc detail::parse_error
16641     using parse_error = detail::parse_error;
16642     /// @copydoc detail::invalid_iterator
16643     using invalid_iterator = detail::invalid_iterator;
16644     /// @copydoc detail::type_error
16645     using type_error = detail::type_error;
16646     /// @copydoc detail::out_of_range
16647     using out_of_range = detail::out_of_range;
16648     /// @copydoc detail::other_error
16649     using other_error = detail::other_error;
16650 
16651     /// @}
16652 
16653 
16654     /////////////////////
16655     // container types //
16656     /////////////////////
16657 
16658     /// @name container types
16659     /// The canonic container types to use @ref basic_json like any other STL
16660     /// container.
16661     /// @{
16662 
16663     /// the type of elements in a basic_json container
16664     using value_type = basic_json;
16665 
16666     /// the type of an element reference
16667     using reference = value_type&;
16668     /// the type of an element const reference
16669     using const_reference = const value_type&;
16670 
16671     /// a type to represent differences between iterators
16672     using difference_type = std::ptrdiff_t;
16673     /// a type to represent container sizes
16674     using size_type = std::size_t;
16675 
16676     /// the allocator type
16677     using allocator_type = AllocatorType<basic_json>;
16678 
16679     /// the type of an element pointer
16680     using pointer = typename std::allocator_traits<allocator_type>::pointer;
16681     /// the type of an element const pointer
16682     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16683 
16684     /// an iterator for a basic_json container
16685     using iterator = iter_impl<basic_json>;
16686     /// a const iterator for a basic_json container
16687     using const_iterator = iter_impl<const basic_json>;
16688     /// a reverse iterator for a basic_json container
16689     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16690     /// a const reverse iterator for a basic_json container
16691     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16692 
16693     /// @}
16694 
16695 
16696     /*!
16697     @brief returns the allocator associated with the container
16698     */
get_allocator()16699     static allocator_type get_allocator()
16700     {
16701         return allocator_type();
16702     }
16703 
16704     /*!
16705     @brief returns version information on the library
16706 
16707     This function returns a JSON object with information about the library,
16708     including the version number and information on the platform and compiler.
16709 
16710     @return JSON object holding version information
16711     key         | description
16712     ----------- | ---------------
16713     `compiler`  | Information on the used compiler. It is an object with the following keys: `c++` (the used C++ standard), `family` (the compiler family; possible values are `clang`, `icc`, `gcc`, `ilecpp`, `msvc`, `pgcpp`, `sunpro`, and `unknown`), and `version` (the compiler version).
16714     `copyright` | The copyright line for the library as string.
16715     `name`      | The name of the library as string.
16716     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
16717     `url`       | The URL of the project as string.
16718     `version`   | The version of the library. It is an object with the following keys: `major`, `minor`, and `patch` as defined by [Semantic Versioning](http://semver.org), and `string` (the version string).
16719 
16720     @liveexample{The following code shows an example output of the `meta()`
16721     function.,meta}
16722 
16723     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16724     changes to any JSON value.
16725 
16726     @complexity Constant.
16727 
16728     @since 2.1.0
16729     */
16730     JSON_HEDLEY_WARN_UNUSED_RESULT
meta()16731     static basic_json meta()
16732     {
16733         basic_json result;
16734 
16735         result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16736         result["name"] = "JSON for Modern C++";
16737         result["url"] = "https://github.com/nlohmann/json";
16738         result["version"]["string"] =
16739             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16740             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16741             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16742         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16743         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16744         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16745 
16746 #ifdef _WIN32
16747         result["platform"] = "win32";
16748 #elif defined __linux__
16749         result["platform"] = "linux";
16750 #elif defined __APPLE__
16751         result["platform"] = "apple";
16752 #elif defined __unix__
16753         result["platform"] = "unix";
16754 #else
16755         result["platform"] = "unknown";
16756 #endif
16757 
16758 #if defined(__ICC) || defined(__INTEL_COMPILER)
16759         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16760 #elif defined(__clang__)
16761         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16762 #elif defined(__GNUC__) || defined(__GNUG__)
16763         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16764 #elif defined(__HP_cc) || defined(__HP_aCC)
16765         result["compiler"] = "hp"
16766 #elif defined(__IBMCPP__)
16767         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16768 #elif defined(_MSC_VER)
16769         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16770 #elif defined(__PGI)
16771         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16772 #elif defined(__SUNPRO_CC)
16773         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16774 #else
16775         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16776 #endif
16777 
16778 #ifdef __cplusplus
16779         result["compiler"]["c++"] = std::to_string(__cplusplus);
16780 #else
16781         result["compiler"]["c++"] = "unknown";
16782 #endif
16783         return result;
16784     }
16785 
16786 
16787     ///////////////////////////
16788     // JSON value data types //
16789     ///////////////////////////
16790 
16791     /// @name JSON value data types
16792     /// The data types to store a JSON value. These types are derived from
16793     /// the template arguments passed to class @ref basic_json.
16794     /// @{
16795 
16796 #if defined(JSON_HAS_CPP_14)
16797     // Use transparent comparator if possible, combined with perfect forwarding
16798     // on find() and count() calls prevents unnecessary string construction.
16799     using object_comparator_t = std::less<>;
16800 #else
16801     using object_comparator_t = std::less<StringType>;
16802 #endif
16803 
16804     /*!
16805     @brief a type for an object
16806 
16807     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
16808     > An object is an unordered collection of zero or more name/value pairs,
16809     > where a name is a string and a value is a string, number, boolean, null,
16810     > object, or array.
16811 
16812     To store objects in C++, a type is defined by the template parameters
16813     described below.
16814 
16815     @tparam ObjectType  the container to store objects (e.g., `std::map` or
16816     `std::unordered_map`)
16817     @tparam StringType the type of the keys or names (e.g., `std::string`).
16818     The comparison function `std::less<StringType>` is used to order elements
16819     inside the container.
16820     @tparam AllocatorType the allocator to use for objects (e.g.,
16821     `std::allocator`)
16822 
16823     #### Default type
16824 
16825     With the default values for @a ObjectType (`std::map`), @a StringType
16826     (`std::string`), and @a AllocatorType (`std::allocator`), the default
16827     value for @a object_t is:
16828 
16829     @code {.cpp}
16830     std::map<
16831       std::string, // key_type
16832       basic_json, // value_type
16833       std::less<std::string>, // key_compare
16834       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
16835     >
16836     @endcode
16837 
16838     #### Behavior
16839 
16840     The choice of @a object_t influences the behavior of the JSON class. With
16841     the default type, objects have the following behavior:
16842 
16843     - When all names are unique, objects will be interoperable in the sense
16844       that all software implementations receiving that object will agree on
16845       the name-value mappings.
16846     - When the names within an object are not unique, it is unspecified which
16847       one of the values for a given key will be chosen. For instance,
16848       `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
16849       `{"key": 2}`.
16850     - Internally, name/value pairs are stored in lexicographical order of the
16851       names. Objects will also be serialized (see @ref dump) in this order.
16852       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
16853       and serialized as `{"a": 2, "b": 1}`.
16854     - When comparing objects, the order of the name/value pairs is irrelevant.
16855       This makes objects interoperable in the sense that they will not be
16856       affected by these differences. For instance, `{"b": 1, "a": 2}` and
16857       `{"a": 2, "b": 1}` will be treated as equal.
16858 
16859     #### Limits
16860 
16861     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
16862     > An implementation may set limits on the maximum depth of nesting.
16863 
16864     In this class, the object's limit of nesting is not explicitly constrained.
16865     However, a maximum depth of nesting may be introduced by the compiler or
16866     runtime environment. A theoretical limit can be queried by calling the
16867     @ref max_size function of a JSON object.
16868 
16869     #### Storage
16870 
16871     Objects are stored as pointers in a @ref basic_json type. That is, for any
16872     access to object values, a pointer of type `object_t*` must be
16873     dereferenced.
16874 
16875     @sa @ref array_t -- type for an array value
16876 
16877     @since version 1.0.0
16878 
16879     @note The order name/value pairs are added to the object is *not*
16880     preserved by the library. Therefore, iterating an object may return
16881     name/value pairs in a different order than they were originally stored. In
16882     fact, keys will be traversed in alphabetical order as `std::map` with
16883     `std::less` is used by default. Please note this behavior conforms to [RFC
16884     7159](http://rfc7159.net/rfc7159), because any order implements the
16885     specified "unordered" nature of JSON objects.
16886     */
16887     using object_t = ObjectType<StringType,
16888           basic_json,
16889           object_comparator_t,
16890           AllocatorType<std::pair<const StringType,
16891           basic_json>>>;
16892 
16893     /*!
16894     @brief a type for an array
16895 
16896     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
16897     > An array is an ordered sequence of zero or more values.
16898 
16899     To store objects in C++, a type is defined by the template parameters
16900     explained below.
16901 
16902     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
16903     `std::list`)
16904     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
16905 
16906     #### Default type
16907 
16908     With the default values for @a ArrayType (`std::vector`) and @a
16909     AllocatorType (`std::allocator`), the default value for @a array_t is:
16910 
16911     @code {.cpp}
16912     std::vector<
16913       basic_json, // value_type
16914       std::allocator<basic_json> // allocator_type
16915     >
16916     @endcode
16917 
16918     #### Limits
16919 
16920     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
16921     > An implementation may set limits on the maximum depth of nesting.
16922 
16923     In this class, the array's limit of nesting is not explicitly constrained.
16924     However, a maximum depth of nesting may be introduced by the compiler or
16925     runtime environment. A theoretical limit can be queried by calling the
16926     @ref max_size function of a JSON array.
16927 
16928     #### Storage
16929 
16930     Arrays are stored as pointers in a @ref basic_json type. That is, for any
16931     access to array values, a pointer of type `array_t*` must be dereferenced.
16932 
16933     @sa @ref object_t -- type for an object value
16934 
16935     @since version 1.0.0
16936     */
16937     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
16938 
16939     /*!
16940     @brief a type for a string
16941 
16942     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
16943     > A string is a sequence of zero or more Unicode characters.
16944 
16945     To store objects in C++, a type is defined by the template parameter
16946     described below. Unicode values are split by the JSON class into
16947     byte-sized characters during deserialization.
16948 
16949     @tparam StringType  the container to store strings (e.g., `std::string`).
16950     Note this container is used for keys/names in objects, see @ref object_t.
16951 
16952     #### Default type
16953 
16954     With the default values for @a StringType (`std::string`), the default
16955     value for @a string_t is:
16956 
16957     @code {.cpp}
16958     std::string
16959     @endcode
16960 
16961     #### Encoding
16962 
16963     Strings are stored in UTF-8 encoding. Therefore, functions like
16964     `std::string::size()` or `std::string::length()` return the number of
16965     bytes in the string rather than the number of characters or glyphs.
16966 
16967     #### String comparison
16968 
16969     [RFC 7159](http://rfc7159.net/rfc7159) states:
16970     > Software implementations are typically required to test names of object
16971     > members for equality. Implementations that transform the textual
16972     > representation into sequences of Unicode code units and then perform the
16973     > comparison numerically, code unit by code unit, are interoperable in the
16974     > sense that implementations will agree in all cases on equality or
16975     > inequality of two strings. For example, implementations that compare
16976     > strings with escaped characters unconverted may incorrectly find that
16977     > `"a\\b"` and `"a\u005Cb"` are not equal.
16978 
16979     This implementation is interoperable as it does compare strings code unit
16980     by code unit.
16981 
16982     #### Storage
16983 
16984     String values are stored as pointers in a @ref basic_json type. That is,
16985     for any access to string values, a pointer of type `string_t*` must be
16986     dereferenced.
16987 
16988     @since version 1.0.0
16989     */
16990     using string_t = StringType;
16991 
16992     /*!
16993     @brief a type for a boolean
16994 
16995     [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
16996     type which differentiates the two literals `true` and `false`.
16997 
16998     To store objects in C++, a type is defined by the template parameter @a
16999     BooleanType which chooses the type to use.
17000 
17001     #### Default type
17002 
17003     With the default values for @a BooleanType (`bool`), the default value for
17004     @a boolean_t is:
17005 
17006     @code {.cpp}
17007     bool
17008     @endcode
17009 
17010     #### Storage
17011 
17012     Boolean values are stored directly inside a @ref basic_json type.
17013 
17014     @since version 1.0.0
17015     */
17016     using boolean_t = BooleanType;
17017 
17018     /*!
17019     @brief a type for a number (integer)
17020 
17021     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17022     > The representation of numbers is similar to that used in most
17023     > programming languages. A number is represented in base 10 using decimal
17024     > digits. It contains an integer component that may be prefixed with an
17025     > optional minus sign, which may be followed by a fraction part and/or an
17026     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17027     > cannot be represented in the grammar below (such as Infinity and NaN)
17028     > are not permitted.
17029 
17030     This description includes both integer and floating-point numbers.
17031     However, C++ allows more precise storage if it is known whether the number
17032     is a signed integer, an unsigned integer or a floating-point number.
17033     Therefore, three different types, @ref number_integer_t, @ref
17034     number_unsigned_t and @ref number_float_t are used.
17035 
17036     To store integer numbers in C++, a type is defined by the template
17037     parameter @a NumberIntegerType which chooses the type to use.
17038 
17039     #### Default type
17040 
17041     With the default values for @a NumberIntegerType (`int64_t`), the default
17042     value for @a number_integer_t is:
17043 
17044     @code {.cpp}
17045     int64_t
17046     @endcode
17047 
17048     #### Default behavior
17049 
17050     - The restrictions about leading zeros is not enforced in C++. Instead,
17051       leading zeros in integer literals lead to an interpretation as octal
17052       number. Internally, the value will be stored as decimal number. For
17053       instance, the C++ integer literal `010` will be serialized to `8`.
17054       During deserialization, leading zeros yield an error.
17055     - Not-a-number (NaN) values will be serialized to `null`.
17056 
17057     #### Limits
17058 
17059     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17060     > An implementation may set limits on the range and precision of numbers.
17061 
17062     When the default type is used, the maximal integer number that can be
17063     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
17064     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
17065     that are out of range will yield over/underflow when used in a
17066     constructor. During deserialization, too large or small integer numbers
17067     will be automatically be stored as @ref number_unsigned_t or @ref
17068     number_float_t.
17069 
17070     [RFC 7159](http://rfc7159.net/rfc7159) further states:
17071     > Note that when such software is used, numbers that are integers and are
17072     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17073     > that implementations will agree exactly on their numeric values.
17074 
17075     As this range is a subrange of the exactly supported range [INT64_MIN,
17076     INT64_MAX], this class's integer type is interoperable.
17077 
17078     #### Storage
17079 
17080     Integer number values are stored directly inside a @ref basic_json type.
17081 
17082     @sa @ref number_float_t -- type for number values (floating-point)
17083 
17084     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17085 
17086     @since version 1.0.0
17087     */
17088     using number_integer_t = NumberIntegerType;
17089 
17090     /*!
17091     @brief a type for a number (unsigned)
17092 
17093     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17094     > The representation of numbers is similar to that used in most
17095     > programming languages. A number is represented in base 10 using decimal
17096     > digits. It contains an integer component that may be prefixed with an
17097     > optional minus sign, which may be followed by a fraction part and/or an
17098     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17099     > cannot be represented in the grammar below (such as Infinity and NaN)
17100     > are not permitted.
17101 
17102     This description includes both integer and floating-point numbers.
17103     However, C++ allows more precise storage if it is known whether the number
17104     is a signed integer, an unsigned integer or a floating-point number.
17105     Therefore, three different types, @ref number_integer_t, @ref
17106     number_unsigned_t and @ref number_float_t are used.
17107 
17108     To store unsigned integer numbers in C++, a type is defined by the
17109     template parameter @a NumberUnsignedType which chooses the type to use.
17110 
17111     #### Default type
17112 
17113     With the default values for @a NumberUnsignedType (`uint64_t`), the
17114     default value for @a number_unsigned_t is:
17115 
17116     @code {.cpp}
17117     uint64_t
17118     @endcode
17119 
17120     #### Default behavior
17121 
17122     - The restrictions about leading zeros is not enforced in C++. Instead,
17123       leading zeros in integer literals lead to an interpretation as octal
17124       number. Internally, the value will be stored as decimal number. For
17125       instance, the C++ integer literal `010` will be serialized to `8`.
17126       During deserialization, leading zeros yield an error.
17127     - Not-a-number (NaN) values will be serialized to `null`.
17128 
17129     #### Limits
17130 
17131     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17132     > An implementation may set limits on the range and precision of numbers.
17133 
17134     When the default type is used, the maximal integer number that can be
17135     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
17136     number that can be stored is `0`. Integer numbers that are out of range
17137     will yield over/underflow when used in a constructor. During
17138     deserialization, too large or small integer numbers will be automatically
17139     be stored as @ref number_integer_t or @ref number_float_t.
17140 
17141     [RFC 7159](http://rfc7159.net/rfc7159) further states:
17142     > Note that when such software is used, numbers that are integers and are
17143     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17144     > that implementations will agree exactly on their numeric values.
17145 
17146     As this range is a subrange (when considered in conjunction with the
17147     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
17148     this class's integer type is interoperable.
17149 
17150     #### Storage
17151 
17152     Integer number values are stored directly inside a @ref basic_json type.
17153 
17154     @sa @ref number_float_t -- type for number values (floating-point)
17155     @sa @ref number_integer_t -- type for number values (integer)
17156 
17157     @since version 2.0.0
17158     */
17159     using number_unsigned_t = NumberUnsignedType;
17160 
17161     /*!
17162     @brief a type for a number (floating-point)
17163 
17164     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17165     > The representation of numbers is similar to that used in most
17166     > programming languages. A number is represented in base 10 using decimal
17167     > digits. It contains an integer component that may be prefixed with an
17168     > optional minus sign, which may be followed by a fraction part and/or an
17169     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17170     > cannot be represented in the grammar below (such as Infinity and NaN)
17171     > are not permitted.
17172 
17173     This description includes both integer and floating-point numbers.
17174     However, C++ allows more precise storage if it is known whether the number
17175     is a signed integer, an unsigned integer or a floating-point number.
17176     Therefore, three different types, @ref number_integer_t, @ref
17177     number_unsigned_t and @ref number_float_t are used.
17178 
17179     To store floating-point numbers in C++, a type is defined by the template
17180     parameter @a NumberFloatType which chooses the type to use.
17181 
17182     #### Default type
17183 
17184     With the default values for @a NumberFloatType (`double`), the default
17185     value for @a number_float_t is:
17186 
17187     @code {.cpp}
17188     double
17189     @endcode
17190 
17191     #### Default behavior
17192 
17193     - The restrictions about leading zeros is not enforced in C++. Instead,
17194       leading zeros in floating-point literals will be ignored. Internally,
17195       the value will be stored as decimal number. For instance, the C++
17196       floating-point literal `01.2` will be serialized to `1.2`. During
17197       deserialization, leading zeros yield an error.
17198     - Not-a-number (NaN) values will be serialized to `null`.
17199 
17200     #### Limits
17201 
17202     [RFC 7159](http://rfc7159.net/rfc7159) states:
17203     > This specification allows implementations to set limits on the range and
17204     > precision of numbers accepted. Since software that implements IEEE
17205     > 754-2008 binary64 (double precision) numbers is generally available and
17206     > widely used, good interoperability can be achieved by implementations
17207     > that expect no more precision or range than these provide, in the sense
17208     > that implementations will approximate JSON numbers within the expected
17209     > precision.
17210 
17211     This implementation does exactly follow this approach, as it uses double
17212     precision floating-point numbers. Note values smaller than
17213     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
17214     will be stored as NaN internally and be serialized to `null`.
17215 
17216     #### Storage
17217 
17218     Floating-point number values are stored directly inside a @ref basic_json
17219     type.
17220 
17221     @sa @ref number_integer_t -- type for number values (integer)
17222 
17223     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17224 
17225     @since version 1.0.0
17226     */
17227     using number_float_t = NumberFloatType;
17228 
17229     /*!
17230     @brief a type for a packed binary type
17231 
17232     This type is a type designed to carry binary data that appears in various
17233     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
17234     BSON's generic binary subtype. This type is NOT a part of standard JSON and
17235     exists solely for compatibility with these binary types. As such, it is
17236     simply defined as an ordered sequence of zero or more byte values.
17237 
17238     Additionally, as an implementation detail, the subtype of the binary data is
17239     carried around as a `std::uint8_t`, which is compatible with both of the
17240     binary data formats that use binary subtyping, (though the specific
17241     numbering is incompatible with each other, and it is up to the user to
17242     translate between them).
17243 
17244     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
17245     as:
17246     > Major type 2: a byte string. The string's length in bytes is represented
17247     > following the rules for positive integers (major type 0).
17248 
17249     [MessagePack's documentation on the bin type
17250     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
17251     describes this type as:
17252     > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
17253     > in addition to the size of the byte array.
17254 
17255     [BSON's specifications](http://bsonspec.org/spec.html) describe several
17256     binary types; however, this type is intended to represent the generic binary
17257     type which has the description:
17258     > Generic binary subtype - This is the most commonly used binary subtype and
17259     > should be the 'default' for drivers and tools.
17260 
17261     None of these impose any limitations on the internal representation other
17262     than the basic unit of storage be some type of array whose parts are
17263     decomposable into bytes.
17264 
17265     The default representation of this binary format is a
17266     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
17267     array in modern C++.
17268 
17269     #### Default type
17270 
17271     The default values for @a BinaryType is `std::vector<std::uint8_t>`
17272 
17273     #### Storage
17274 
17275     Binary Arrays are stored as pointers in a @ref basic_json type. That is,
17276     for any access to array values, a pointer of the type `binary_t*` must be
17277     dereferenced.
17278 
17279     #### Notes on subtypes
17280 
17281     - CBOR
17282        - Binary values are represented as byte strings. No subtypes are
17283          supported and will be ignored when CBOR is written.
17284     - MessagePack
17285        - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
17286          or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
17287          is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
17288          The subtype is then added as singed 8-bit integer.
17289        - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
17290     - BSON
17291        - If a subtype is given, it is used and added as unsigned 8-bit integer.
17292        - If no subtype is given, the generic binary subtype 0x00 is used.
17293 
17294     @sa @ref binary -- create a binary array
17295 
17296     @since version 3.8.0
17297     */
17298     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17299     /// @}
17300 
17301   private:
17302 
17303     /// helper for exception-safe object creation
17304     template<typename T, typename... Args>
17305     JSON_HEDLEY_RETURNS_NON_NULL
create(Args &&...args)17306     static T* create(Args&& ... args)
17307     {
17308         AllocatorType<T> alloc;
17309         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17310 
17311         auto deleter = [&](T * object)
17312         {
17313             AllocatorTraits::deallocate(alloc, object, 1);
17314         };
17315         std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17316         AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17317         JSON_ASSERT(object != nullptr);
17318         return object.release();
17319     }
17320 
17321     ////////////////////////
17322     // JSON value storage //
17323     ////////////////////////
17324 
17325     /*!
17326     @brief a JSON value
17327 
17328     The actual storage for a JSON value of the @ref basic_json class. This
17329     union combines the different storage types for the JSON value types
17330     defined in @ref value_t.
17331 
17332     JSON type | value_t type    | used type
17333     --------- | --------------- | ------------------------
17334     object    | object          | pointer to @ref object_t
17335     array     | array           | pointer to @ref array_t
17336     string    | string          | pointer to @ref string_t
17337     boolean   | boolean         | @ref boolean_t
17338     number    | number_integer  | @ref number_integer_t
17339     number    | number_unsigned | @ref number_unsigned_t
17340     number    | number_float    | @ref number_float_t
17341     binary    | binary          | pointer to @ref binary_t
17342     null      | null            | *no value is stored*
17343 
17344     @note Variable-length types (objects, arrays, and strings) are stored as
17345     pointers. The size of the union should not exceed 64 bits if the default
17346     value types are used.
17347 
17348     @since version 1.0.0
17349     */
17350     union json_value
17351     {
17352         /// object (stored with pointer to save storage)
17353         object_t* object;
17354         /// array (stored with pointer to save storage)
17355         array_t* array;
17356         /// string (stored with pointer to save storage)
17357         string_t* string;
17358         /// binary (stored with pointer to save storage)
17359         binary_t* binary;
17360         /// boolean
17361         boolean_t boolean;
17362         /// number (integer)
17363         number_integer_t number_integer;
17364         /// number (unsigned integer)
17365         number_unsigned_t number_unsigned;
17366         /// number (floating-point)
17367         number_float_t number_float;
17368 
17369         /// default constructor (for null values)
17370         json_value() = default;
17371         /// constructor for booleans
json_value(boolean_t v)17372         json_value(boolean_t v) noexcept : boolean(v) {}
17373         /// constructor for numbers (integer)
json_value(number_integer_t v)17374         json_value(number_integer_t v) noexcept : number_integer(v) {}
17375         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)17376         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17377         /// constructor for numbers (floating-point)
json_value(number_float_t v)17378         json_value(number_float_t v) noexcept : number_float(v) {}
17379         /// constructor for empty values of a given type
json_value(value_t t)17380         json_value(value_t t)
17381         {
17382             switch (t)
17383             {
17384                 case value_t::object:
17385                 {
17386                     object = create<object_t>();
17387                     break;
17388                 }
17389 
17390                 case value_t::array:
17391                 {
17392                     array = create<array_t>();
17393                     break;
17394                 }
17395 
17396                 case value_t::string:
17397                 {
17398                     string = create<string_t>("");
17399                     break;
17400                 }
17401 
17402                 case value_t::binary:
17403                 {
17404                     binary = create<binary_t>();
17405                     break;
17406                 }
17407 
17408                 case value_t::boolean:
17409                 {
17410                     boolean = boolean_t(false);
17411                     break;
17412                 }
17413 
17414                 case value_t::number_integer:
17415                 {
17416                     number_integer = number_integer_t(0);
17417                     break;
17418                 }
17419 
17420                 case value_t::number_unsigned:
17421                 {
17422                     number_unsigned = number_unsigned_t(0);
17423                     break;
17424                 }
17425 
17426                 case value_t::number_float:
17427                 {
17428                     number_float = number_float_t(0.0);
17429                     break;
17430                 }
17431 
17432                 case value_t::null:
17433                 {
17434                     object = nullptr;  // silence warning, see #821
17435                     break;
17436                 }
17437 
17438                 default:
17439                 {
17440                     object = nullptr;  // silence warning, see #821
17441                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17442                     {
17443                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.0")); // LCOV_EXCL_LINE
17444                     }
17445                     break;
17446                 }
17447             }
17448         }
17449 
17450         /// constructor for strings
json_value(const string_t & value)17451         json_value(const string_t& value)
17452         {
17453             string = create<string_t>(value);
17454         }
17455 
17456         /// constructor for rvalue strings
json_value(string_t && value)17457         json_value(string_t&& value)
17458         {
17459             string = create<string_t>(std::move(value));
17460         }
17461 
17462         /// constructor for objects
json_value(const object_t & value)17463         json_value(const object_t& value)
17464         {
17465             object = create<object_t>(value);
17466         }
17467 
17468         /// constructor for rvalue objects
json_value(object_t && value)17469         json_value(object_t&& value)
17470         {
17471             object = create<object_t>(std::move(value));
17472         }
17473 
17474         /// constructor for arrays
json_value(const array_t & value)17475         json_value(const array_t& value)
17476         {
17477             array = create<array_t>(value);
17478         }
17479 
17480         /// constructor for rvalue arrays
json_value(array_t && value)17481         json_value(array_t&& value)
17482         {
17483             array = create<array_t>(std::move(value));
17484         }
17485 
17486         /// constructor for binary arrays
json_value(const typename binary_t::container_type & value)17487         json_value(const typename binary_t::container_type& value)
17488         {
17489             binary = create<binary_t>(value);
17490         }
17491 
17492         /// constructor for rvalue binary arrays
json_value(typename binary_t::container_type && value)17493         json_value(typename binary_t::container_type&& value)
17494         {
17495             binary = create<binary_t>(std::move(value));
17496         }
17497 
17498         /// constructor for binary arrays (internal type)
json_value(const binary_t & value)17499         json_value(const binary_t& value)
17500         {
17501             binary = create<binary_t>(value);
17502         }
17503 
17504         /// constructor for rvalue binary arrays (internal type)
json_value(binary_t && value)17505         json_value(binary_t&& value)
17506         {
17507             binary = create<binary_t>(std::move(value));
17508         }
17509 
destroy(value_t t)17510         void destroy(value_t t) noexcept
17511         {
17512             // flatten the current json_value to a heap-allocated stack
17513             std::vector<basic_json> stack;
17514 
17515             // move the top-level items to stack
17516             if (t == value_t::array)
17517             {
17518                 stack.reserve(array->size());
17519                 std::move(array->begin(), array->end(), std::back_inserter(stack));
17520             }
17521             else if (t == value_t::object)
17522             {
17523                 stack.reserve(object->size());
17524                 for (auto&& it : *object)
17525                 {
17526                     stack.push_back(std::move(it.second));
17527                 }
17528             }
17529 
17530             while (!stack.empty())
17531             {
17532                 // move the last item to local variable to be processed
17533                 basic_json current_item(std::move(stack.back()));
17534                 stack.pop_back();
17535 
17536                 // if current_item is array/object, move
17537                 // its children to the stack to be processed later
17538                 if (current_item.is_array())
17539                 {
17540                     std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17541                               std::back_inserter(stack));
17542 
17543                     current_item.m_value.array->clear();
17544                 }
17545                 else if (current_item.is_object())
17546                 {
17547                     for (auto&& it : *current_item.m_value.object)
17548                     {
17549                         stack.push_back(std::move(it.second));
17550                     }
17551 
17552                     current_item.m_value.object->clear();
17553                 }
17554 
17555                 // it's now safe that current_item get destructed
17556                 // since it doesn't have any children
17557             }
17558 
17559             switch (t)
17560             {
17561                 case value_t::object:
17562                 {
17563                     AllocatorType<object_t> alloc;
17564                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17565                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17566                     break;
17567                 }
17568 
17569                 case value_t::array:
17570                 {
17571                     AllocatorType<array_t> alloc;
17572                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17573                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17574                     break;
17575                 }
17576 
17577                 case value_t::string:
17578                 {
17579                     AllocatorType<string_t> alloc;
17580                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17581                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17582                     break;
17583                 }
17584 
17585                 case value_t::binary:
17586                 {
17587                     AllocatorType<binary_t> alloc;
17588                     std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17589                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17590                     break;
17591                 }
17592 
17593                 default:
17594                 {
17595                     break;
17596                 }
17597             }
17598         }
17599     };
17600 
17601     /*!
17602     @brief checks the class invariants
17603 
17604     This function asserts the class invariants. It needs to be called at the
17605     end of every constructor to make sure that created objects respect the
17606     invariant. Furthermore, it has to be called each time the type of a JSON
17607     value is changed, because the invariant expresses a relationship between
17608     @a m_type and @a m_value.
17609     */
assert_invariant() const17610     void assert_invariant() const noexcept
17611     {
17612         JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17613         JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17614         JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17615         JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17616     }
17617 
17618   public:
17619     //////////////////////////
17620     // JSON parser callback //
17621     //////////////////////////
17622 
17623     /*!
17624     @brief parser event types
17625 
17626     The parser callback distinguishes the following events:
17627     - `object_start`: the parser read `{` and started to process a JSON object
17628     - `key`: the parser read a key of a value in an object
17629     - `object_end`: the parser read `}` and finished processing a JSON object
17630     - `array_start`: the parser read `[` and started to process a JSON array
17631     - `array_end`: the parser read `]` and finished processing a JSON array
17632     - `value`: the parser finished reading a JSON value
17633 
17634     @image html callback_events.png "Example when certain parse events are triggered"
17635 
17636     @sa @ref parser_callback_t for more information and examples
17637     */
17638     using parse_event_t = detail::parse_event_t;
17639 
17640     /*!
17641     @brief per-element parser callback type
17642 
17643     With a parser callback function, the result of parsing a JSON text can be
17644     influenced. When passed to @ref parse, it is called on certain events
17645     (passed as @ref parse_event_t via parameter @a event) with a set recursion
17646     depth @a depth and context JSON value @a parsed. The return value of the
17647     callback function is a boolean indicating whether the element that emitted
17648     the callback shall be kept or not.
17649 
17650     We distinguish six scenarios (determined by the event type) in which the
17651     callback function can be called. The following table describes the values
17652     of the parameters @a depth, @a event, and @a parsed.
17653 
17654     parameter @a event | description | parameter @a depth | parameter @a parsed
17655     ------------------ | ----------- | ------------------ | -------------------
17656     parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
17657     parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
17658     parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
17659     parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
17660     parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
17661     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
17662 
17663     @image html callback_events.png "Example when certain parse events are triggered"
17664 
17665     Discarding a value (i.e., returning `false`) has different effects
17666     depending on the context in which function was called:
17667 
17668     - Discarded values in structured types are skipped. That is, the parser
17669       will behave as if the discarded value was never read.
17670     - In case a value outside a structured type is skipped, it is replaced
17671       with `null`. This case happens if the top-level element is skipped.
17672 
17673     @param[in] depth  the depth of the recursion during parsing
17674 
17675     @param[in] event  an event of type parse_event_t indicating the context in
17676     the callback function has been called
17677 
17678     @param[in,out] parsed  the current intermediate parse result; note that
17679     writing to this value has no effect for parse_event_t::key events
17680 
17681     @return Whether the JSON value which called the function during parsing
17682     should be kept (`true`) or not (`false`). In the latter case, it is either
17683     skipped completely or replaced by an empty discarded object.
17684 
17685     @sa @ref parse for examples
17686 
17687     @since version 1.0.0
17688     */
17689     using parser_callback_t = detail::parser_callback_t<basic_json>;
17690 
17691     //////////////////
17692     // constructors //
17693     //////////////////
17694 
17695     /// @name constructors and destructors
17696     /// Constructors of class @ref basic_json, copy/move constructor, copy
17697     /// assignment, static functions creating objects, and the destructor.
17698     /// @{
17699 
17700     /*!
17701     @brief create an empty value with a given type
17702 
17703     Create an empty JSON value with a given type. The value will be default
17704     initialized with an empty value which depends on the type:
17705 
17706     Value type  | initial value
17707     ----------- | -------------
17708     null        | `null`
17709     boolean     | `false`
17710     string      | `""`
17711     number      | `0`
17712     object      | `{}`
17713     array       | `[]`
17714     binary      | empty array
17715 
17716     @param[in] v  the type of the value to create
17717 
17718     @complexity Constant.
17719 
17720     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17721     changes to any JSON value.
17722 
17723     @liveexample{The following code shows the constructor for different @ref
17724     value_t values,basic_json__value_t}
17725 
17726     @sa @ref clear() -- restores the postcondition of this constructor
17727 
17728     @since version 1.0.0
17729     */
basic_json(const value_t v)17730     basic_json(const value_t v)
17731         : m_type(v), m_value(v)
17732     {
17733         assert_invariant();
17734     }
17735 
17736     /*!
17737     @brief create a null object
17738 
17739     Create a `null` JSON value. It either takes a null pointer as parameter
17740     (explicitly creating `null`) or no parameter (implicitly creating `null`).
17741     The passed null pointer itself is not read -- it is only used to choose
17742     the right constructor.
17743 
17744     @complexity Constant.
17745 
17746     @exceptionsafety No-throw guarantee: this constructor never throws
17747     exceptions.
17748 
17749     @liveexample{The following code shows the constructor with and without a
17750     null pointer parameter.,basic_json__nullptr_t}
17751 
17752     @since version 1.0.0
17753     */
basic_json(std::nullptr_t=nullptr)17754     basic_json(std::nullptr_t = nullptr) noexcept
17755         : basic_json(value_t::null)
17756     {
17757         assert_invariant();
17758     }
17759 
17760     /*!
17761     @brief create a JSON value
17762 
17763     This is a "catch all" constructor for all compatible JSON types; that is,
17764     types for which a `to_json()` method exists. The constructor forwards the
17765     parameter @a val to that method (to `json_serializer<U>::to_json` method
17766     with `U = uncvref_t<CompatibleType>`, to be exact).
17767 
17768     Template type @a CompatibleType includes, but is not limited to, the
17769     following types:
17770     - **arrays**: @ref array_t and all kinds of compatible containers such as
17771       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
17772       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
17773       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
17774       which a @ref basic_json value can be constructed.
17775     - **objects**: @ref object_t and all kinds of compatible associative
17776       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
17777       and `std::unordered_multimap` with a `key_type` compatible to
17778       @ref string_t and a `value_type` from which a @ref basic_json value can
17779       be constructed.
17780     - **strings**: @ref string_t, string literals, and all compatible string
17781       containers can be used.
17782     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
17783       @ref number_float_t, and all convertible number types such as `int`,
17784       `size_t`, `int64_t`, `float` or `double` can be used.
17785     - **boolean**: @ref boolean_t / `bool` can be used.
17786     - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
17787       unfortunately because string literals cannot be distinguished from binary
17788       character arrays by the C++ type system, all types compatible with `const
17789       char*` will be directed to the string constructor instead.  This is both
17790       for backwards compatibility, and due to the fact that a binary type is not
17791       a standard JSON type.
17792 
17793     See the examples below.
17794 
17795     @tparam CompatibleType a type such that:
17796     - @a CompatibleType is not derived from `std::istream`,
17797     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
17798          constructors),
17799     - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
17800     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
17801          @ref json_pointer, @ref iterator, etc ...)
17802     - @ref @ref json_serializer<U> has a
17803          `to_json(basic_json_t&, CompatibleType&&)` method
17804 
17805     @tparam U = `uncvref_t<CompatibleType>`
17806 
17807     @param[in] val the value to be forwarded to the respective constructor
17808 
17809     @complexity Usually linear in the size of the passed @a val, also
17810                 depending on the implementation of the called `to_json()`
17811                 method.
17812 
17813     @exceptionsafety Depends on the called constructor. For types directly
17814     supported by the library (i.e., all types for which no `to_json()` function
17815     was provided), strong guarantee holds: if an exception is thrown, there are
17816     no changes to any JSON value.
17817 
17818     @liveexample{The following code shows the constructor with several
17819     compatible types.,basic_json__CompatibleType}
17820 
17821     @since version 2.1.0
17822     */
17823     template < typename CompatibleType,
17824                typename U = detail::uncvref_t<CompatibleType>,
17825                detail::enable_if_t <
17826                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val)17827     basic_json(CompatibleType && val) noexcept(noexcept(
17828                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17829                                            std::forward<CompatibleType>(val))))
17830     {
17831         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17832         assert_invariant();
17833     }
17834 
17835     /*!
17836     @brief create a JSON value from an existing one
17837 
17838     This is a constructor for existing @ref basic_json types.
17839     It does not hijack copy/move constructors, since the parameter has different
17840     template arguments than the current ones.
17841 
17842     The constructor tries to convert the internal @ref m_value of the parameter.
17843 
17844     @tparam BasicJsonType a type such that:
17845     - @a BasicJsonType is a @ref basic_json type.
17846     - @a BasicJsonType has different template arguments than @ref basic_json_t.
17847 
17848     @param[in] val the @ref basic_json value to be converted.
17849 
17850     @complexity Usually linear in the size of the passed @a val, also
17851                 depending on the implementation of the called `to_json()`
17852                 method.
17853 
17854     @exceptionsafety Depends on the called constructor. For types directly
17855     supported by the library (i.e., all types for which no `to_json()` function
17856     was provided), strong guarantee holds: if an exception is thrown, there are
17857     no changes to any JSON value.
17858 
17859     @since version 3.2.0
17860     */
17861     template < typename BasicJsonType,
17862                detail::enable_if_t <
17863                    detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType & val)17864     basic_json(const BasicJsonType& val)
17865     {
17866         using other_boolean_t = typename BasicJsonType::boolean_t;
17867         using other_number_float_t = typename BasicJsonType::number_float_t;
17868         using other_number_integer_t = typename BasicJsonType::number_integer_t;
17869         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17870         using other_string_t = typename BasicJsonType::string_t;
17871         using other_object_t = typename BasicJsonType::object_t;
17872         using other_array_t = typename BasicJsonType::array_t;
17873         using other_binary_t = typename BasicJsonType::binary_t;
17874 
17875         switch (val.type())
17876         {
17877             case value_t::boolean:
17878                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17879                 break;
17880             case value_t::number_float:
17881                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17882                 break;
17883             case value_t::number_integer:
17884                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17885                 break;
17886             case value_t::number_unsigned:
17887                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17888                 break;
17889             case value_t::string:
17890                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17891                 break;
17892             case value_t::object:
17893                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17894                 break;
17895             case value_t::array:
17896                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17897                 break;
17898             case value_t::binary:
17899                 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
17900                 break;
17901             case value_t::null:
17902                 *this = nullptr;
17903                 break;
17904             case value_t::discarded:
17905                 m_type = value_t::discarded;
17906                 break;
17907             default:            // LCOV_EXCL_LINE
17908                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
17909         }
17910         assert_invariant();
17911     }
17912 
17913     /*!
17914     @brief create a container (array or object) from an initializer list
17915 
17916     Creates a JSON value of type array or object from the passed initializer
17917     list @a init. In case @a type_deduction is `true` (default), the type of
17918     the JSON value to be created is deducted from the initializer list @a init
17919     according to the following rules:
17920 
17921     1. If the list is empty, an empty JSON object value `{}` is created.
17922     2. If the list consists of pairs whose first element is a string, a JSON
17923        object value is created where the first elements of the pairs are
17924        treated as keys and the second elements are as values.
17925     3. In all other cases, an array is created.
17926 
17927     The rules aim to create the best fit between a C++ initializer list and
17928     JSON values. The rationale is as follows:
17929 
17930     1. The empty initializer list is written as `{}` which is exactly an empty
17931        JSON object.
17932     2. C++ has no way of describing mapped types other than to list a list of
17933        pairs. As JSON requires that keys must be of type string, rule 2 is the
17934        weakest constraint one can pose on initializer lists to interpret them
17935        as an object.
17936     3. In all other cases, the initializer list could not be interpreted as
17937        JSON object type, so interpreting it as JSON array type is safe.
17938 
17939     With the rules described above, the following JSON values cannot be
17940     expressed by an initializer list:
17941 
17942     - the empty array (`[]`): use @ref array(initializer_list_t)
17943       with an empty initializer list in this case
17944     - arrays whose elements satisfy rule 2: use @ref
17945       array(initializer_list_t) with the same initializer list
17946       in this case
17947 
17948     @note When used without parentheses around an empty initializer list, @ref
17949     basic_json() is called instead of this function, yielding the JSON null
17950     value.
17951 
17952     @param[in] init  initializer list with JSON values
17953 
17954     @param[in] type_deduction internal parameter; when set to `true`, the type
17955     of the JSON value is deducted from the initializer list @a init; when set
17956     to `false`, the type provided via @a manual_type is forced. This mode is
17957     used by the functions @ref array(initializer_list_t) and
17958     @ref object(initializer_list_t).
17959 
17960     @param[in] manual_type internal parameter; when @a type_deduction is set
17961     to `false`, the created JSON value will use the provided type (only @ref
17962     value_t::array and @ref value_t::object are valid); when @a type_deduction
17963     is set to `true`, this parameter has no effect
17964 
17965     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
17966     `value_t::object`, but @a init contains an element which is not a pair
17967     whose first element is a string. In this case, the constructor could not
17968     create an object. If @a type_deduction would have be `true`, an array
17969     would have been created. See @ref object(initializer_list_t)
17970     for an example.
17971 
17972     @complexity Linear in the size of the initializer list @a init.
17973 
17974     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17975     changes to any JSON value.
17976 
17977     @liveexample{The example below shows how JSON values are created from
17978     initializer lists.,basic_json__list_init_t}
17979 
17980     @sa @ref array(initializer_list_t) -- create a JSON array
17981     value from an initializer list
17982     @sa @ref object(initializer_list_t) -- create a JSON object
17983     value from an initializer list
17984 
17985     @since version 1.0.0
17986     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)17987     basic_json(initializer_list_t init,
17988                bool type_deduction = true,
17989                value_t manual_type = value_t::array)
17990     {
17991         // check if each element is an array with two elements whose first
17992         // element is a string
17993         bool is_an_object = std::all_of(init.begin(), init.end(),
17994                                         [](const detail::json_ref<basic_json>& element_ref)
17995         {
17996             return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
17997         });
17998 
17999         // adjust type if type deduction is not wanted
18000         if (!type_deduction)
18001         {
18002             // if array is wanted, do not create an object though possible
18003             if (manual_type == value_t::array)
18004             {
18005                 is_an_object = false;
18006             }
18007 
18008             // if object is wanted but impossible, throw an exception
18009             if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18010             {
18011                 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18012             }
18013         }
18014 
18015         if (is_an_object)
18016         {
18017             // the initializer list is a list of pairs -> create object
18018             m_type = value_t::object;
18019             m_value = value_t::object;
18020 
18021             std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18022             {
18023                 auto element = element_ref.moved_or_copied();
18024                 m_value.object->emplace(
18025                     std::move(*((*element.m_value.array)[0].m_value.string)),
18026                     std::move((*element.m_value.array)[1]));
18027             });
18028         }
18029         else
18030         {
18031             // the initializer list describes an array -> create array
18032             m_type = value_t::array;
18033             m_value.array = create<array_t>(init.begin(), init.end());
18034         }
18035 
18036         assert_invariant();
18037     }
18038 
18039     /*!
18040     @brief explicitly create a binary array (without subtype)
18041 
18042     Creates a JSON binary array value from a given binary container. Binary
18043     values are part of various binary formats, such as CBOR, MessagePack, and
18044     BSON. This constructor is used to create a value for serialization to those
18045     formats.
18046 
18047     @note Note, this function exists because of the difficulty in correctly
18048     specifying the correct template overload in the standard value ctor, as both
18049     JSON arrays and JSON binary arrays are backed with some form of a
18050     `std::vector`. Because JSON binary arrays are a non-standard extension it
18051     was decided that it would be best to prevent automatic initialization of a
18052     binary array type, for backwards compatibility and so it does not happen on
18053     accident.
18054 
18055     @param[in] init container containing bytes to use as binary type
18056 
18057     @return JSON binary array value
18058 
18059     @complexity Linear in the size of @a init.
18060 
18061     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18062     changes to any JSON value.
18063 
18064     @since version 3.8.0
18065     */
18066     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init)18067     static basic_json binary(const typename binary_t::container_type& init)
18068     {
18069         auto res = basic_json();
18070         res.m_type = value_t::binary;
18071         res.m_value = init;
18072         return res;
18073     }
18074 
18075     /*!
18076     @brief explicitly create a binary array (with subtype)
18077 
18078     Creates a JSON binary array value from a given binary container. Binary
18079     values are part of various binary formats, such as CBOR, MessagePack, and
18080     BSON. This constructor is used to create a value for serialization to those
18081     formats.
18082 
18083     @note Note, this function exists because of the difficulty in correctly
18084     specifying the correct template overload in the standard value ctor, as both
18085     JSON arrays and JSON binary arrays are backed with some form of a
18086     `std::vector`. Because JSON binary arrays are a non-standard extension it
18087     was decided that it would be best to prevent automatic initialization of a
18088     binary array type, for backwards compatibility and so it does not happen on
18089     accident.
18090 
18091     @param[in] init container containing bytes to use as binary type
18092     @param[in] subtype subtype to use in MessagePack and BSON
18093 
18094     @return JSON binary array value
18095 
18096     @complexity Linear in the size of @a init.
18097 
18098     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18099     changes to any JSON value.
18100 
18101     @since version 3.8.0
18102     */
18103     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init,std::uint8_t subtype)18104     static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18105     {
18106         auto res = basic_json();
18107         res.m_type = value_t::binary;
18108         res.m_value = binary_t(init, subtype);
18109         return res;
18110     }
18111 
18112     /// @copydoc binary(const typename binary_t::container_type&)
18113     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init)18114     static basic_json binary(typename binary_t::container_type&& init)
18115     {
18116         auto res = basic_json();
18117         res.m_type = value_t::binary;
18118         res.m_value = std::move(init);
18119         return res;
18120     }
18121 
18122     /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
18123     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init,std::uint8_t subtype)18124     static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18125     {
18126         auto res = basic_json();
18127         res.m_type = value_t::binary;
18128         res.m_value = binary_t(std::move(init), subtype);
18129         return res;
18130     }
18131 
18132     /*!
18133     @brief explicitly create an array from an initializer list
18134 
18135     Creates a JSON array value from a given initializer list. That is, given a
18136     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
18137     initializer list is empty, the empty array `[]` is created.
18138 
18139     @note This function is only needed to express two edge cases that cannot
18140     be realized with the initializer list constructor (@ref
18141     basic_json(initializer_list_t, bool, value_t)). These cases
18142     are:
18143     1. creating an array whose elements are all pairs whose first element is a
18144     string -- in this case, the initializer list constructor would create an
18145     object, taking the first elements as keys
18146     2. creating an empty array -- passing the empty initializer list to the
18147     initializer list constructor yields an empty object
18148 
18149     @param[in] init  initializer list with JSON values to create an array from
18150     (optional)
18151 
18152     @return JSON array value
18153 
18154     @complexity Linear in the size of @a init.
18155 
18156     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18157     changes to any JSON value.
18158 
18159     @liveexample{The following code shows an example for the `array`
18160     function.,array}
18161 
18162     @sa @ref basic_json(initializer_list_t, bool, value_t) --
18163     create a JSON value from an initializer list
18164     @sa @ref object(initializer_list_t) -- create a JSON object
18165     value from an initializer list
18166 
18167     @since version 1.0.0
18168     */
18169     JSON_HEDLEY_WARN_UNUSED_RESULT
array(initializer_list_t init={})18170     static basic_json array(initializer_list_t init = {})
18171     {
18172         return basic_json(init, false, value_t::array);
18173     }
18174 
18175     /*!
18176     @brief explicitly create an object from an initializer list
18177 
18178     Creates a JSON object value from a given initializer list. The initializer
18179     lists elements must be pairs, and their first elements must be strings. If
18180     the initializer list is empty, the empty object `{}` is created.
18181 
18182     @note This function is only added for symmetry reasons. In contrast to the
18183     related function @ref array(initializer_list_t), there are
18184     no cases which can only be expressed by this function. That is, any
18185     initializer list @a init can also be passed to the initializer list
18186     constructor @ref basic_json(initializer_list_t, bool, value_t).
18187 
18188     @param[in] init  initializer list to create an object from (optional)
18189 
18190     @return JSON object value
18191 
18192     @throw type_error.301 if @a init is not a list of pairs whose first
18193     elements are strings. In this case, no object can be created. When such a
18194     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
18195     an array would have been created from the passed initializer list @a init.
18196     See example below.
18197 
18198     @complexity Linear in the size of @a init.
18199 
18200     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18201     changes to any JSON value.
18202 
18203     @liveexample{The following code shows an example for the `object`
18204     function.,object}
18205 
18206     @sa @ref basic_json(initializer_list_t, bool, value_t) --
18207     create a JSON value from an initializer list
18208     @sa @ref array(initializer_list_t) -- create a JSON array
18209     value from an initializer list
18210 
18211     @since version 1.0.0
18212     */
18213     JSON_HEDLEY_WARN_UNUSED_RESULT
object(initializer_list_t init={})18214     static basic_json object(initializer_list_t init = {})
18215     {
18216         return basic_json(init, false, value_t::object);
18217     }
18218 
18219     /*!
18220     @brief construct an array with count copies of given value
18221 
18222     Constructs a JSON array value by creating @a cnt copies of a passed value.
18223     In case @a cnt is `0`, an empty array is created.
18224 
18225     @param[in] cnt  the number of JSON copies of @a val to create
18226     @param[in] val  the JSON value to copy
18227 
18228     @post `std::distance(begin(),end()) == cnt` holds.
18229 
18230     @complexity Linear in @a cnt.
18231 
18232     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18233     changes to any JSON value.
18234 
18235     @liveexample{The following code shows examples for the @ref
18236     basic_json(size_type\, const basic_json&)
18237     constructor.,basic_json__size_type_basic_json}
18238 
18239     @since version 1.0.0
18240     */
basic_json(size_type cnt,const basic_json & val)18241     basic_json(size_type cnt, const basic_json& val)
18242         : m_type(value_t::array)
18243     {
18244         m_value.array = create<array_t>(cnt, val);
18245         assert_invariant();
18246     }
18247 
18248     /*!
18249     @brief construct a JSON container given an iterator range
18250 
18251     Constructs the JSON value with the contents of the range `[first, last)`.
18252     The semantics depends on the different types a JSON value can have:
18253     - In case of a null type, invalid_iterator.206 is thrown.
18254     - In case of other primitive types (number, boolean, or string), @a first
18255       must be `begin()` and @a last must be `end()`. In this case, the value is
18256       copied. Otherwise, invalid_iterator.204 is thrown.
18257     - In case of structured types (array, object), the constructor behaves as
18258       similar versions for `std::vector` or `std::map`; that is, a JSON array
18259       or object is constructed from the values in the range.
18260 
18261     @tparam InputIT an input iterator type (@ref iterator or @ref
18262     const_iterator)
18263 
18264     @param[in] first begin of the range to copy from (included)
18265     @param[in] last end of the range to copy from (excluded)
18266 
18267     @pre Iterators @a first and @a last must be initialized. **This
18268          precondition is enforced with an assertion (see warning).** If
18269          assertions are switched off, a violation of this precondition yields
18270          undefined behavior.
18271 
18272     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
18273          checked efficiently. Only certain edge cases are detected; see the
18274          description of the exceptions below. A violation of this precondition
18275          yields undefined behavior.
18276 
18277     @warning A precondition is enforced with a runtime assertion that will
18278              result in calling `std::abort` if this precondition is not met.
18279              Assertions can be disabled by defining `NDEBUG` at compile time.
18280              See https://en.cppreference.com/w/cpp/error/assert for more
18281              information.
18282 
18283     @throw invalid_iterator.201 if iterators @a first and @a last are not
18284     compatible (i.e., do not belong to the same JSON value). In this case,
18285     the range `[first, last)` is undefined.
18286     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
18287     primitive type (number, boolean, or string), but @a first does not point
18288     to the first element any more. In this case, the range `[first, last)` is
18289     undefined. See example code below.
18290     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
18291     null value. In this case, the range `[first, last)` is undefined.
18292 
18293     @complexity Linear in distance between @a first and @a last.
18294 
18295     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18296     changes to any JSON value.
18297 
18298     @liveexample{The example below shows several ways to create JSON values by
18299     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
18300 
18301     @since version 1.0.0
18302     */
18303     template < class InputIT, typename std::enable_if <
18304                    std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18305                    std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
basic_json(InputIT first,InputIT last)18306     basic_json(InputIT first, InputIT last)
18307     {
18308         JSON_ASSERT(first.m_object != nullptr);
18309         JSON_ASSERT(last.m_object != nullptr);
18310 
18311         // make sure iterator fits the current value
18312         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18313         {
18314             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18315         }
18316 
18317         // copy type from first iterator
18318         m_type = first.m_object->m_type;
18319 
18320         // check if iterator range is complete for primitive values
18321         switch (m_type)
18322         {
18323             case value_t::boolean:
18324             case value_t::number_float:
18325             case value_t::number_integer:
18326             case value_t::number_unsigned:
18327             case value_t::string:
18328             {
18329                 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18330                                          || !last.m_it.primitive_iterator.is_end()))
18331                 {
18332                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18333                 }
18334                 break;
18335             }
18336 
18337             default:
18338                 break;
18339         }
18340 
18341         switch (m_type)
18342         {
18343             case value_t::number_integer:
18344             {
18345                 m_value.number_integer = first.m_object->m_value.number_integer;
18346                 break;
18347             }
18348 
18349             case value_t::number_unsigned:
18350             {
18351                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18352                 break;
18353             }
18354 
18355             case value_t::number_float:
18356             {
18357                 m_value.number_float = first.m_object->m_value.number_float;
18358                 break;
18359             }
18360 
18361             case value_t::boolean:
18362             {
18363                 m_value.boolean = first.m_object->m_value.boolean;
18364                 break;
18365             }
18366 
18367             case value_t::string:
18368             {
18369                 m_value = *first.m_object->m_value.string;
18370                 break;
18371             }
18372 
18373             case value_t::object:
18374             {
18375                 m_value.object = create<object_t>(first.m_it.object_iterator,
18376                                                   last.m_it.object_iterator);
18377                 break;
18378             }
18379 
18380             case value_t::array:
18381             {
18382                 m_value.array = create<array_t>(first.m_it.array_iterator,
18383                                                 last.m_it.array_iterator);
18384                 break;
18385             }
18386 
18387             case value_t::binary:
18388             {
18389                 m_value = *first.m_object->m_value.binary;
18390                 break;
18391             }
18392 
18393             default:
18394                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18395                                                     std::string(first.m_object->type_name())));
18396         }
18397 
18398         assert_invariant();
18399     }
18400 
18401 
18402     ///////////////////////////////////////
18403     // other constructors and destructor //
18404     ///////////////////////////////////////
18405 
18406     template<typename JsonRef,
18407              detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18408                                  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef & ref)18409     basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18410 
18411     /*!
18412     @brief copy constructor
18413 
18414     Creates a copy of a given JSON value.
18415 
18416     @param[in] other  the JSON value to copy
18417 
18418     @post `*this == other`
18419 
18420     @complexity Linear in the size of @a other.
18421 
18422     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18423     changes to any JSON value.
18424 
18425     @requirement This function helps `basic_json` satisfying the
18426     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18427     requirements:
18428     - The complexity is linear.
18429     - As postcondition, it holds: `other == basic_json(other)`.
18430 
18431     @liveexample{The following code shows an example for the copy
18432     constructor.,basic_json__basic_json}
18433 
18434     @since version 1.0.0
18435     */
basic_json(const basic_json & other)18436     basic_json(const basic_json& other)
18437         : m_type(other.m_type)
18438     {
18439         // check of passed value is valid
18440         other.assert_invariant();
18441 
18442         switch (m_type)
18443         {
18444             case value_t::object:
18445             {
18446                 m_value = *other.m_value.object;
18447                 break;
18448             }
18449 
18450             case value_t::array:
18451             {
18452                 m_value = *other.m_value.array;
18453                 break;
18454             }
18455 
18456             case value_t::string:
18457             {
18458                 m_value = *other.m_value.string;
18459                 break;
18460             }
18461 
18462             case value_t::boolean:
18463             {
18464                 m_value = other.m_value.boolean;
18465                 break;
18466             }
18467 
18468             case value_t::number_integer:
18469             {
18470                 m_value = other.m_value.number_integer;
18471                 break;
18472             }
18473 
18474             case value_t::number_unsigned:
18475             {
18476                 m_value = other.m_value.number_unsigned;
18477                 break;
18478             }
18479 
18480             case value_t::number_float:
18481             {
18482                 m_value = other.m_value.number_float;
18483                 break;
18484             }
18485 
18486             case value_t::binary:
18487             {
18488                 m_value = *other.m_value.binary;
18489                 break;
18490             }
18491 
18492             default:
18493                 break;
18494         }
18495 
18496         assert_invariant();
18497     }
18498 
18499     /*!
18500     @brief move constructor
18501 
18502     Move constructor. Constructs a JSON value with the contents of the given
18503     value @a other using move semantics. It "steals" the resources from @a
18504     other and leaves it as JSON null value.
18505 
18506     @param[in,out] other  value to move to this object
18507 
18508     @post `*this` has the same value as @a other before the call.
18509     @post @a other is a JSON null value.
18510 
18511     @complexity Constant.
18512 
18513     @exceptionsafety No-throw guarantee: this constructor never throws
18514     exceptions.
18515 
18516     @requirement This function helps `basic_json` satisfying the
18517     [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
18518     requirements.
18519 
18520     @liveexample{The code below shows the move constructor explicitly called
18521     via std::move.,basic_json__moveconstructor}
18522 
18523     @since version 1.0.0
18524     */
basic_json(basic_json && other)18525     basic_json(basic_json&& other) noexcept
18526         : m_type(std::move(other.m_type)),
18527           m_value(std::move(other.m_value))
18528     {
18529         // check that passed value is valid
18530         other.assert_invariant();
18531 
18532         // invalidate payload
18533         other.m_type = value_t::null;
18534         other.m_value = {};
18535 
18536         assert_invariant();
18537     }
18538 
18539     /*!
18540     @brief copy assignment
18541 
18542     Copy assignment operator. Copies a JSON value via the "copy and swap"
18543     strategy: It is expressed in terms of the copy constructor, destructor,
18544     and the `swap()` member function.
18545 
18546     @param[in] other  value to copy from
18547 
18548     @complexity Linear.
18549 
18550     @requirement This function helps `basic_json` satisfying the
18551     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18552     requirements:
18553     - The complexity is linear.
18554 
18555     @liveexample{The code below shows and example for the copy assignment. It
18556     creates a copy of value `a` which is then swapped with `b`. Finally\, the
18557     copy of `a` (which is the null value after the swap) is
18558     destroyed.,basic_json__copyassignment}
18559 
18560     @since version 1.0.0
18561     */
operator =(basic_json other)18562     basic_json& operator=(basic_json other) noexcept (
18563         std::is_nothrow_move_constructible<value_t>::value&&
18564         std::is_nothrow_move_assignable<value_t>::value&&
18565         std::is_nothrow_move_constructible<json_value>::value&&
18566         std::is_nothrow_move_assignable<json_value>::value
18567     )
18568     {
18569         // check that passed value is valid
18570         other.assert_invariant();
18571 
18572         using std::swap;
18573         swap(m_type, other.m_type);
18574         swap(m_value, other.m_value);
18575 
18576         assert_invariant();
18577         return *this;
18578     }
18579 
18580     /*!
18581     @brief destructor
18582 
18583     Destroys the JSON value and frees all allocated memory.
18584 
18585     @complexity Linear.
18586 
18587     @requirement This function helps `basic_json` satisfying the
18588     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18589     requirements:
18590     - The complexity is linear.
18591     - All stored elements are destroyed and all memory is freed.
18592 
18593     @since version 1.0.0
18594     */
~basic_json()18595     ~basic_json() noexcept
18596     {
18597         assert_invariant();
18598         m_value.destroy(m_type);
18599     }
18600 
18601     /// @}
18602 
18603   public:
18604     ///////////////////////
18605     // object inspection //
18606     ///////////////////////
18607 
18608     /// @name object inspection
18609     /// Functions to inspect the type of a JSON value.
18610     /// @{
18611 
18612     /*!
18613     @brief serialization
18614 
18615     Serialization function for JSON values. The function tries to mimic
18616     Python's `json.dumps()` function, and currently supports its @a indent
18617     and @a ensure_ascii parameters.
18618 
18619     @param[in] indent If indent is nonnegative, then array elements and object
18620     members will be pretty-printed with that indent level. An indent level of
18621     `0` will only insert newlines. `-1` (the default) selects the most compact
18622     representation.
18623     @param[in] indent_char The character to use for indentation if @a indent is
18624     greater than `0`. The default is ` ` (space).
18625     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
18626     in the output are escaped with `\uXXXX` sequences, and the result consists
18627     of ASCII characters only.
18628     @param[in] error_handler  how to react on decoding errors; there are three
18629     possible values: `strict` (throws and exception in case a decoding error
18630     occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
18631     and `ignore` (ignore invalid UTF-8 sequences during serialization; all
18632     bytes are copied to the output unchanged).
18633 
18634     @return string containing the serialization of the JSON value
18635 
18636     @throw type_error.316 if a string stored inside the JSON value is not
18637                           UTF-8 encoded and @a error_handler is set to strict
18638 
18639     @note Binary values are serialized as object containing two keys:
18640       - "bytes": an array of bytes as integers
18641       - "subtype": the subtype as integer or "null" if the binary has no subtype
18642 
18643     @complexity Linear.
18644 
18645     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18646     changes in the JSON value.
18647 
18648     @liveexample{The following example shows the effect of different @a indent\,
18649     @a indent_char\, and @a ensure_ascii parameters to the result of the
18650     serialization.,dump}
18651 
18652     @see https://docs.python.org/2/library/json.html#json.dump
18653 
18654     @since version 1.0.0; indentation character @a indent_char, option
18655            @a ensure_ascii and exceptions added in version 3.0.0; error
18656            handlers added in version 3.4.0; serialization of binary values added
18657            in version 3.8.0.
18658     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const18659     string_t dump(const int indent = -1,
18660                   const char indent_char = ' ',
18661                   const bool ensure_ascii = false,
18662                   const error_handler_t error_handler = error_handler_t::strict) const
18663     {
18664         string_t result;
18665         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18666 
18667         if (indent >= 0)
18668         {
18669             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18670         }
18671         else
18672         {
18673             s.dump(*this, false, ensure_ascii, 0);
18674         }
18675 
18676         return result;
18677     }
18678 
18679     /*!
18680     @brief return the type of the JSON value (explicit)
18681 
18682     Return the type of the JSON value as a value from the @ref value_t
18683     enumeration.
18684 
18685     @return the type of the JSON value
18686             Value type                | return value
18687             ------------------------- | -------------------------
18688             null                      | value_t::null
18689             boolean                   | value_t::boolean
18690             string                    | value_t::string
18691             number (integer)          | value_t::number_integer
18692             number (unsigned integer) | value_t::number_unsigned
18693             number (floating-point)   | value_t::number_float
18694             object                    | value_t::object
18695             array                     | value_t::array
18696             binary                    | value_t::binary
18697             discarded                 | value_t::discarded
18698 
18699     @complexity Constant.
18700 
18701     @exceptionsafety No-throw guarantee: this member function never throws
18702     exceptions.
18703 
18704     @liveexample{The following code exemplifies `type()` for all JSON
18705     types.,type}
18706 
18707     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
18708     @sa @ref type_name() -- return the type as string
18709 
18710     @since version 1.0.0
18711     */
type() const18712     constexpr value_t type() const noexcept
18713     {
18714         return m_type;
18715     }
18716 
18717     /*!
18718     @brief return whether type is primitive
18719 
18720     This function returns true if and only if the JSON type is primitive
18721     (string, number, boolean, or null).
18722 
18723     @return `true` if type is primitive (string, number, boolean, or null),
18724     `false` otherwise.
18725 
18726     @complexity Constant.
18727 
18728     @exceptionsafety No-throw guarantee: this member function never throws
18729     exceptions.
18730 
18731     @liveexample{The following code exemplifies `is_primitive()` for all JSON
18732     types.,is_primitive}
18733 
18734     @sa @ref is_structured() -- returns whether JSON value is structured
18735     @sa @ref is_null() -- returns whether JSON value is `null`
18736     @sa @ref is_string() -- returns whether JSON value is a string
18737     @sa @ref is_boolean() -- returns whether JSON value is a boolean
18738     @sa @ref is_number() -- returns whether JSON value is a number
18739     @sa @ref is_binary() -- returns whether JSON value is a binary array
18740 
18741     @since version 1.0.0
18742     */
is_primitive() const18743     constexpr bool is_primitive() const noexcept
18744     {
18745         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18746     }
18747 
18748     /*!
18749     @brief return whether type is structured
18750 
18751     This function returns true if and only if the JSON type is structured
18752     (array or object).
18753 
18754     @return `true` if type is structured (array or object), `false` otherwise.
18755 
18756     @complexity Constant.
18757 
18758     @exceptionsafety No-throw guarantee: this member function never throws
18759     exceptions.
18760 
18761     @liveexample{The following code exemplifies `is_structured()` for all JSON
18762     types.,is_structured}
18763 
18764     @sa @ref is_primitive() -- returns whether value is primitive
18765     @sa @ref is_array() -- returns whether value is an array
18766     @sa @ref is_object() -- returns whether value is an object
18767 
18768     @since version 1.0.0
18769     */
is_structured() const18770     constexpr bool is_structured() const noexcept
18771     {
18772         return is_array() || is_object();
18773     }
18774 
18775     /*!
18776     @brief return whether value is null
18777 
18778     This function returns true if and only if the JSON value is null.
18779 
18780     @return `true` if type is null, `false` otherwise.
18781 
18782     @complexity Constant.
18783 
18784     @exceptionsafety No-throw guarantee: this member function never throws
18785     exceptions.
18786 
18787     @liveexample{The following code exemplifies `is_null()` for all JSON
18788     types.,is_null}
18789 
18790     @since version 1.0.0
18791     */
is_null() const18792     constexpr bool is_null() const noexcept
18793     {
18794         return m_type == value_t::null;
18795     }
18796 
18797     /*!
18798     @brief return whether value is a boolean
18799 
18800     This function returns true if and only if the JSON value is a boolean.
18801 
18802     @return `true` if type is boolean, `false` otherwise.
18803 
18804     @complexity Constant.
18805 
18806     @exceptionsafety No-throw guarantee: this member function never throws
18807     exceptions.
18808 
18809     @liveexample{The following code exemplifies `is_boolean()` for all JSON
18810     types.,is_boolean}
18811 
18812     @since version 1.0.0
18813     */
is_boolean() const18814     constexpr bool is_boolean() const noexcept
18815     {
18816         return m_type == value_t::boolean;
18817     }
18818 
18819     /*!
18820     @brief return whether value is a number
18821 
18822     This function returns true if and only if the JSON value is a number. This
18823     includes both integer (signed and unsigned) and floating-point values.
18824 
18825     @return `true` if type is number (regardless whether integer, unsigned
18826     integer or floating-type), `false` otherwise.
18827 
18828     @complexity Constant.
18829 
18830     @exceptionsafety No-throw guarantee: this member function never throws
18831     exceptions.
18832 
18833     @liveexample{The following code exemplifies `is_number()` for all JSON
18834     types.,is_number}
18835 
18836     @sa @ref is_number_integer() -- check if value is an integer or unsigned
18837     integer number
18838     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
18839     number
18840     @sa @ref is_number_float() -- check if value is a floating-point number
18841 
18842     @since version 1.0.0
18843     */
is_number() const18844     constexpr bool is_number() const noexcept
18845     {
18846         return is_number_integer() || is_number_float();
18847     }
18848 
18849     /*!
18850     @brief return whether value is an integer number
18851 
18852     This function returns true if and only if the JSON value is a signed or
18853     unsigned integer number. This excludes floating-point values.
18854 
18855     @return `true` if type is an integer or unsigned integer number, `false`
18856     otherwise.
18857 
18858     @complexity Constant.
18859 
18860     @exceptionsafety No-throw guarantee: this member function never throws
18861     exceptions.
18862 
18863     @liveexample{The following code exemplifies `is_number_integer()` for all
18864     JSON types.,is_number_integer}
18865 
18866     @sa @ref is_number() -- check if value is a number
18867     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
18868     number
18869     @sa @ref is_number_float() -- check if value is a floating-point number
18870 
18871     @since version 1.0.0
18872     */
is_number_integer() const18873     constexpr bool is_number_integer() const noexcept
18874     {
18875         return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18876     }
18877 
18878     /*!
18879     @brief return whether value is an unsigned integer number
18880 
18881     This function returns true if and only if the JSON value is an unsigned
18882     integer number. This excludes floating-point and signed integer values.
18883 
18884     @return `true` if type is an unsigned integer number, `false` otherwise.
18885 
18886     @complexity Constant.
18887 
18888     @exceptionsafety No-throw guarantee: this member function never throws
18889     exceptions.
18890 
18891     @liveexample{The following code exemplifies `is_number_unsigned()` for all
18892     JSON types.,is_number_unsigned}
18893 
18894     @sa @ref is_number() -- check if value is a number
18895     @sa @ref is_number_integer() -- check if value is an integer or unsigned
18896     integer number
18897     @sa @ref is_number_float() -- check if value is a floating-point number
18898 
18899     @since version 2.0.0
18900     */
is_number_unsigned() const18901     constexpr bool is_number_unsigned() const noexcept
18902     {
18903         return m_type == value_t::number_unsigned;
18904     }
18905 
18906     /*!
18907     @brief return whether value is a floating-point number
18908 
18909     This function returns true if and only if the JSON value is a
18910     floating-point number. This excludes signed and unsigned integer values.
18911 
18912     @return `true` if type is a floating-point number, `false` otherwise.
18913 
18914     @complexity Constant.
18915 
18916     @exceptionsafety No-throw guarantee: this member function never throws
18917     exceptions.
18918 
18919     @liveexample{The following code exemplifies `is_number_float()` for all
18920     JSON types.,is_number_float}
18921 
18922     @sa @ref is_number() -- check if value is number
18923     @sa @ref is_number_integer() -- check if value is an integer number
18924     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
18925     number
18926 
18927     @since version 1.0.0
18928     */
is_number_float() const18929     constexpr bool is_number_float() const noexcept
18930     {
18931         return m_type == value_t::number_float;
18932     }
18933 
18934     /*!
18935     @brief return whether value is an object
18936 
18937     This function returns true if and only if the JSON value is an object.
18938 
18939     @return `true` if type is object, `false` otherwise.
18940 
18941     @complexity Constant.
18942 
18943     @exceptionsafety No-throw guarantee: this member function never throws
18944     exceptions.
18945 
18946     @liveexample{The following code exemplifies `is_object()` for all JSON
18947     types.,is_object}
18948 
18949     @since version 1.0.0
18950     */
is_object() const18951     constexpr bool is_object() const noexcept
18952     {
18953         return m_type == value_t::object;
18954     }
18955 
18956     /*!
18957     @brief return whether value is an array
18958 
18959     This function returns true if and only if the JSON value is an array.
18960 
18961     @return `true` if type is array, `false` otherwise.
18962 
18963     @complexity Constant.
18964 
18965     @exceptionsafety No-throw guarantee: this member function never throws
18966     exceptions.
18967 
18968     @liveexample{The following code exemplifies `is_array()` for all JSON
18969     types.,is_array}
18970 
18971     @since version 1.0.0
18972     */
is_array() const18973     constexpr bool is_array() const noexcept
18974     {
18975         return m_type == value_t::array;
18976     }
18977 
18978     /*!
18979     @brief return whether value is a string
18980 
18981     This function returns true if and only if the JSON value is a string.
18982 
18983     @return `true` if type is string, `false` otherwise.
18984 
18985     @complexity Constant.
18986 
18987     @exceptionsafety No-throw guarantee: this member function never throws
18988     exceptions.
18989 
18990     @liveexample{The following code exemplifies `is_string()` for all JSON
18991     types.,is_string}
18992 
18993     @since version 1.0.0
18994     */
is_string() const18995     constexpr bool is_string() const noexcept
18996     {
18997         return m_type == value_t::string;
18998     }
18999 
19000     /*!
19001     @brief return whether value is a binary array
19002 
19003     This function returns true if and only if the JSON value is a binary array.
19004 
19005     @return `true` if type is binary array, `false` otherwise.
19006 
19007     @complexity Constant.
19008 
19009     @exceptionsafety No-throw guarantee: this member function never throws
19010     exceptions.
19011 
19012     @liveexample{The following code exemplifies `is_binary()` for all JSON
19013     types.,is_binary}
19014 
19015     @since version 3.8.0
19016     */
is_binary() const19017     constexpr bool is_binary() const noexcept
19018     {
19019         return m_type == value_t::binary;
19020     }
19021 
19022     /*!
19023     @brief return whether value is discarded
19024 
19025     This function returns true if and only if the JSON value was discarded
19026     during parsing with a callback function (see @ref parser_callback_t).
19027 
19028     @note This function will always be `false` for JSON values after parsing.
19029     That is, discarded values can only occur during parsing, but will be
19030     removed when inside a structured value or replaced by null in other cases.
19031 
19032     @return `true` if type is discarded, `false` otherwise.
19033 
19034     @complexity Constant.
19035 
19036     @exceptionsafety No-throw guarantee: this member function never throws
19037     exceptions.
19038 
19039     @liveexample{The following code exemplifies `is_discarded()` for all JSON
19040     types.,is_discarded}
19041 
19042     @since version 1.0.0
19043     */
is_discarded() const19044     constexpr bool is_discarded() const noexcept
19045     {
19046         return m_type == value_t::discarded;
19047     }
19048 
19049     /*!
19050     @brief return the type of the JSON value (implicit)
19051 
19052     Implicitly return the type of the JSON value as a value from the @ref
19053     value_t enumeration.
19054 
19055     @return the type of the JSON value
19056 
19057     @complexity Constant.
19058 
19059     @exceptionsafety No-throw guarantee: this member function never throws
19060     exceptions.
19061 
19062     @liveexample{The following code exemplifies the @ref value_t operator for
19063     all JSON types.,operator__value_t}
19064 
19065     @sa @ref type() -- return the type of the JSON value (explicit)
19066     @sa @ref type_name() -- return the type as string
19067 
19068     @since version 1.0.0
19069     */
operator value_t() const19070     constexpr operator value_t() const noexcept
19071     {
19072         return m_type;
19073     }
19074 
19075     /// @}
19076 
19077   private:
19078     //////////////////
19079     // value access //
19080     //////////////////
19081 
19082     /// get a boolean (explicit)
get_impl(boolean_t *) const19083     boolean_t get_impl(boolean_t* /*unused*/) const
19084     {
19085         if (JSON_HEDLEY_LIKELY(is_boolean()))
19086         {
19087             return m_value.boolean;
19088         }
19089 
19090         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19091     }
19092 
19093     /// get a pointer to the value (object)
get_impl_ptr(object_t *)19094     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19095     {
19096         return is_object() ? m_value.object : nullptr;
19097     }
19098 
19099     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const19100     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19101     {
19102         return is_object() ? m_value.object : nullptr;
19103     }
19104 
19105     /// get a pointer to the value (array)
get_impl_ptr(array_t *)19106     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19107     {
19108         return is_array() ? m_value.array : nullptr;
19109     }
19110 
19111     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const19112     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19113     {
19114         return is_array() ? m_value.array : nullptr;
19115     }
19116 
19117     /// get a pointer to the value (string)
get_impl_ptr(string_t *)19118     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19119     {
19120         return is_string() ? m_value.string : nullptr;
19121     }
19122 
19123     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const19124     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19125     {
19126         return is_string() ? m_value.string : nullptr;
19127     }
19128 
19129     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)19130     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19131     {
19132         return is_boolean() ? &m_value.boolean : nullptr;
19133     }
19134 
19135     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const19136     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19137     {
19138         return is_boolean() ? &m_value.boolean : nullptr;
19139     }
19140 
19141     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)19142     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19143     {
19144         return is_number_integer() ? &m_value.number_integer : nullptr;
19145     }
19146 
19147     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const19148     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19149     {
19150         return is_number_integer() ? &m_value.number_integer : nullptr;
19151     }
19152 
19153     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)19154     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19155     {
19156         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19157     }
19158 
19159     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const19160     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19161     {
19162         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19163     }
19164 
19165     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)19166     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19167     {
19168         return is_number_float() ? &m_value.number_float : nullptr;
19169     }
19170 
19171     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const19172     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19173     {
19174         return is_number_float() ? &m_value.number_float : nullptr;
19175     }
19176 
19177     /// get a pointer to the value (binary)
get_impl_ptr(binary_t *)19178     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19179     {
19180         return is_binary() ? m_value.binary : nullptr;
19181     }
19182 
19183     /// get a pointer to the value (binary)
get_impl_ptr(const binary_t *) const19184     constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19185     {
19186         return is_binary() ? m_value.binary : nullptr;
19187     }
19188 
19189     /*!
19190     @brief helper function to implement get_ref()
19191 
19192     This function helps to implement get_ref() without code duplication for
19193     const and non-const overloads
19194 
19195     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
19196 
19197     @throw type_error.303 if ReferenceType does not match underlying value
19198     type of the current JSON
19199     */
19200     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)19201     static ReferenceType get_ref_impl(ThisType& obj)
19202     {
19203         // delegate the call to get_ptr<>()
19204         auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19205 
19206         if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19207         {
19208             return *ptr;
19209         }
19210 
19211         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19212     }
19213 
19214   public:
19215     /// @name value access
19216     /// Direct access to the stored value of a JSON value.
19217     /// @{
19218 
19219     /*!
19220     @brief get special-case overload
19221 
19222     This overloads avoids a lot of template boilerplate, it can be seen as the
19223     identity method
19224 
19225     @tparam BasicJsonType == @ref basic_json
19226 
19227     @return a copy of *this
19228 
19229     @complexity Constant.
19230 
19231     @since version 2.1.0
19232     */
19233     template<typename BasicJsonType, detail::enable_if_t<
19234                  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19235                  int> = 0>
get() const19236     basic_json get() const
19237     {
19238         return *this;
19239     }
19240 
19241     /*!
19242     @brief get special-case overload
19243 
19244     This overloads converts the current @ref basic_json in a different
19245     @ref basic_json type
19246 
19247     @tparam BasicJsonType == @ref basic_json
19248 
19249     @return a copy of *this, converted into @tparam BasicJsonType
19250 
19251     @complexity Depending on the implementation of the called `from_json()`
19252                 method.
19253 
19254     @since version 3.2.0
19255     */
19256     template < typename BasicJsonType, detail::enable_if_t <
19257                    !std::is_same<BasicJsonType, basic_json>::value&&
19258                    detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19259     BasicJsonType get() const
19260     {
19261         return *this;
19262     }
19263 
19264     /*!
19265     @brief get a value (explicit)
19266 
19267     Explicit type conversion between the JSON value and a compatible value
19268     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19269     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19270     The value is converted by calling the @ref json_serializer<ValueType>
19271     `from_json()` method.
19272 
19273     The function is equivalent to executing
19274     @code {.cpp}
19275     ValueType ret;
19276     JSONSerializer<ValueType>::from_json(*this, ret);
19277     return ret;
19278     @endcode
19279 
19280     This overloads is chosen if:
19281     - @a ValueType is not @ref basic_json,
19282     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19283       `void from_json(const basic_json&, ValueType&)`, and
19284     - @ref json_serializer<ValueType> does not have a `from_json()` method of
19285       the form `ValueType from_json(const basic_json&)`
19286 
19287     @tparam ValueTypeCV the provided value type
19288     @tparam ValueType the returned value type
19289 
19290     @return copy of the JSON value, converted to @a ValueType
19291 
19292     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19293 
19294     @liveexample{The example below shows several conversions from JSON values
19295     to other types. There a few things to note: (1) Floating-point numbers can
19296     be converted to integers\, (2) A JSON array can be converted to a standard
19297     `std::vector<short>`\, (3) A JSON object can be converted to C++
19298     associative containers such as `std::unordered_map<std::string\,
19299     json>`.,get__ValueType_const}
19300 
19301     @since version 2.1.0
19302     */
19303     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19304                detail::enable_if_t <
19305                    !detail::is_basic_json<ValueType>::value &&
19306                    detail::has_from_json<basic_json_t, ValueType>::value &&
19307                    !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19308                    int > = 0 >
19309     ValueType get() const noexcept(noexcept(
19310                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19311     {
19312         // we cannot static_assert on ValueTypeCV being non-const, because
19313         // there is support for get<const basic_json_t>(), which is why we
19314         // still need the uncvref
19315         static_assert(!std::is_reference<ValueTypeCV>::value,
19316                       "get() cannot be used with reference types, you might want to use get_ref()");
19317         static_assert(std::is_default_constructible<ValueType>::value,
19318                       "types must be DefaultConstructible when used with get()");
19319 
19320         ValueType ret;
19321         JSONSerializer<ValueType>::from_json(*this, ret);
19322         return ret;
19323     }
19324 
19325     /*!
19326     @brief get a value (explicit); special case
19327 
19328     Explicit type conversion between the JSON value and a compatible value
19329     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19330     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19331     The value is converted by calling the @ref json_serializer<ValueType>
19332     `from_json()` method.
19333 
19334     The function is equivalent to executing
19335     @code {.cpp}
19336     return JSONSerializer<ValueTypeCV>::from_json(*this);
19337     @endcode
19338 
19339     This overloads is chosen if:
19340     - @a ValueType is not @ref basic_json and
19341     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19342       `ValueType from_json(const basic_json&)`
19343 
19344     @note If @ref json_serializer<ValueType> has both overloads of
19345     `from_json()`, this one is chosen.
19346 
19347     @tparam ValueTypeCV the provided value type
19348     @tparam ValueType the returned value type
19349 
19350     @return copy of the JSON value, converted to @a ValueType
19351 
19352     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19353 
19354     @since version 2.1.0
19355     */
19356     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19357                detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19358                                      detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19359                                      int > = 0 >
19360     ValueType get() const noexcept(noexcept(
19361                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19362     {
19363         static_assert(!std::is_reference<ValueTypeCV>::value,
19364                       "get() cannot be used with reference types, you might want to use get_ref()");
19365         return JSONSerializer<ValueType>::from_json(*this);
19366     }
19367 
19368     /*!
19369     @brief get a value (explicit)
19370 
19371     Explicit type conversion between the JSON value and a compatible value.
19372     The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
19373     `from_json()` method.
19374 
19375     The function is equivalent to executing
19376     @code {.cpp}
19377     ValueType v;
19378     JSONSerializer<ValueType>::from_json(*this, v);
19379     @endcode
19380 
19381     This overloads is chosen if:
19382     - @a ValueType is not @ref basic_json,
19383     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19384       `void from_json(const basic_json&, ValueType&)`, and
19385 
19386     @tparam ValueType the input parameter type.
19387 
19388     @return the input parameter, allowing chaining calls.
19389 
19390     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19391 
19392     @liveexample{The example below shows several conversions from JSON values
19393     to other types. There a few things to note: (1) Floating-point numbers can
19394     be converted to integers\, (2) A JSON array can be converted to a standard
19395     `std::vector<short>`\, (3) A JSON object can be converted to C++
19396     associative containers such as `std::unordered_map<std::string\,
19397     json>`.,get_to}
19398 
19399     @since version 3.3.0
19400     */
19401     template < typename ValueType,
19402                detail::enable_if_t <
19403                    !detail::is_basic_json<ValueType>::value&&
19404                    detail::has_from_json<basic_json_t, ValueType>::value,
19405                    int > = 0 >
19406     ValueType & get_to(ValueType& v) const noexcept(noexcept(
19407                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19408     {
19409         JSONSerializer<ValueType>::from_json(*this, v);
19410         return v;
19411     }
19412 
19413     // specialization to allow to call get_to with a basic_json value
19414     // see https://github.com/nlohmann/json/issues/2175
19415     template<typename ValueType,
19416              detail::enable_if_t <
19417                  detail::is_basic_json<ValueType>::value,
19418                  int> = 0>
19419     ValueType & get_to(ValueType& v) const
19420     {
19421         v = *this;
19422         return v;
19423     }
19424 
19425     template <
19426         typename T, std::size_t N,
19427         typename Array = T (&)[N],
19428         detail::enable_if_t <
19429             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19430     Array get_to(T (&v)[N]) const
19431     noexcept(noexcept(JSONSerializer<Array>::from_json(
19432                           std::declval<const basic_json_t&>(), v)))
19433     {
19434         JSONSerializer<Array>::from_json(*this, v);
19435         return v;
19436     }
19437 
19438 
19439     /*!
19440     @brief get a pointer value (implicit)
19441 
19442     Implicit pointer access to the internally stored JSON value. No copies are
19443     made.
19444 
19445     @warning Writing data to the pointee of the result yields an undefined
19446     state.
19447 
19448     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19449     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19450     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
19451     assertion.
19452 
19453     @return pointer to the internally stored JSON value if the requested
19454     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19455 
19456     @complexity Constant.
19457 
19458     @liveexample{The example below shows how pointers to internal values of a
19459     JSON value can be requested. Note that no type conversions are made and a
19460     `nullptr` is returned if the value and the requested pointer type does not
19461     match.,get_ptr}
19462 
19463     @since version 1.0.0
19464     */
19465     template<typename PointerType, typename std::enable_if<
19466                  std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()19467     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19468     {
19469         // delegate the call to get_impl_ptr<>()
19470         return get_impl_ptr(static_cast<PointerType>(nullptr));
19471     }
19472 
19473     /*!
19474     @brief get a pointer value (implicit)
19475     @copydoc get_ptr()
19476     */
19477     template < typename PointerType, typename std::enable_if <
19478                    std::is_pointer<PointerType>::value&&
19479                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
get_ptr() const19480     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19481     {
19482         // delegate the call to get_impl_ptr<>() const
19483         return get_impl_ptr(static_cast<PointerType>(nullptr));
19484     }
19485 
19486     /*!
19487     @brief get a pointer value (explicit)
19488 
19489     Explicit pointer access to the internally stored JSON value. No copies are
19490     made.
19491 
19492     @warning The pointer becomes invalid if the underlying JSON object
19493     changes.
19494 
19495     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19496     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19497     @ref number_unsigned_t, or @ref number_float_t.
19498 
19499     @return pointer to the internally stored JSON value if the requested
19500     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19501 
19502     @complexity Constant.
19503 
19504     @liveexample{The example below shows how pointers to internal values of a
19505     JSON value can be requested. Note that no type conversions are made and a
19506     `nullptr` is returned if the value and the requested pointer type does not
19507     match.,get__PointerType}
19508 
19509     @sa @ref get_ptr() for explicit pointer-member access
19510 
19511     @since version 1.0.0
19512     */
19513     template<typename PointerType, typename std::enable_if<
19514                  std::is_pointer<PointerType>::value, int>::type = 0>
get()19515     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19516     {
19517         // delegate the call to get_ptr
19518         return get_ptr<PointerType>();
19519     }
19520 
19521     /*!
19522     @brief get a pointer value (explicit)
19523     @copydoc get()
19524     */
19525     template<typename PointerType, typename std::enable_if<
19526                  std::is_pointer<PointerType>::value, int>::type = 0>
get() const19527     constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19528     {
19529         // delegate the call to get_ptr
19530         return get_ptr<PointerType>();
19531     }
19532 
19533     /*!
19534     @brief get a reference value (implicit)
19535 
19536     Implicit reference access to the internally stored JSON value. No copies
19537     are made.
19538 
19539     @warning Writing data to the referee of the result yields an undefined
19540     state.
19541 
19542     @tparam ReferenceType reference type; must be a reference to @ref array_t,
19543     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
19544     @ref number_float_t. Enforced by static assertion.
19545 
19546     @return reference to the internally stored JSON value if the requested
19547     reference type @a ReferenceType fits to the JSON value; throws
19548     type_error.303 otherwise
19549 
19550     @throw type_error.303 in case passed type @a ReferenceType is incompatible
19551     with the stored JSON value; see example below
19552 
19553     @complexity Constant.
19554 
19555     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
19556 
19557     @since version 1.1.0
19558     */
19559     template<typename ReferenceType, typename std::enable_if<
19560                  std::is_reference<ReferenceType>::value, int>::type = 0>
19561     ReferenceType get_ref()
19562     {
19563         // delegate call to get_ref_impl
19564         return get_ref_impl<ReferenceType>(*this);
19565     }
19566 
19567     /*!
19568     @brief get a reference value (implicit)
19569     @copydoc get_ref()
19570     */
19571     template < typename ReferenceType, typename std::enable_if <
19572                    std::is_reference<ReferenceType>::value&&
19573                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19574     ReferenceType get_ref() const
19575     {
19576         // delegate call to get_ref_impl
19577         return get_ref_impl<ReferenceType>(*this);
19578     }
19579 
19580     /*!
19581     @brief get a value (implicit)
19582 
19583     Implicit type conversion between the JSON value and a compatible value.
19584     The call is realized by calling @ref get() const.
19585 
19586     @tparam ValueType non-pointer type compatible to the JSON value, for
19587     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
19588     `std::vector` types for JSON arrays. The character type of @ref string_t
19589     as well as an initializer list of this type is excluded to avoid
19590     ambiguities as these types implicitly convert to `std::string`.
19591 
19592     @return copy of the JSON value, converted to type @a ValueType
19593 
19594     @throw type_error.302 in case passed type @a ValueType is incompatible
19595     to the JSON value type (e.g., the JSON value is of type boolean, but a
19596     string is requested); see example below
19597 
19598     @complexity Linear in the size of the JSON value.
19599 
19600     @liveexample{The example below shows several conversions from JSON values
19601     to other types. There a few things to note: (1) Floating-point numbers can
19602     be converted to integers\, (2) A JSON array can be converted to a standard
19603     `std::vector<short>`\, (3) A JSON object can be converted to C++
19604     associative containers such as `std::unordered_map<std::string\,
19605     json>`.,operator__ValueType}
19606 
19607     @since version 1.0.0
19608     */
19609     template < typename ValueType, typename std::enable_if <
19610                    !std::is_pointer<ValueType>::value&&
19611                    !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19612                    !std::is_same<ValueType, typename string_t::value_type>::value&&
19613                    !detail::is_basic_json<ValueType>::value
19614                    && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19615 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19616                    && !std::is_same<ValueType, typename std::string_view>::value
19617 #endif
19618                    && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19619                    , int >::type = 0 >
operator ValueType() const19620     JSON_EXPLICIT operator ValueType() const
19621     {
19622         // delegate the call to get<>() const
19623         return get<ValueType>();
19624     }
19625 
19626     /*!
19627     @return reference to the binary value
19628 
19629     @throw type_error.302 if the value is not binary
19630 
19631     @sa @ref is_binary() to check if the value is binary
19632 
19633     @since version 3.8.0
19634     */
get_binary()19635     binary_t& get_binary()
19636     {
19637         if (!is_binary())
19638         {
19639             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19640         }
19641 
19642         return *get_ptr<binary_t*>();
19643     }
19644 
19645     /// @copydoc get_binary()
get_binary() const19646     const binary_t& get_binary() const
19647     {
19648         if (!is_binary())
19649         {
19650             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19651         }
19652 
19653         return *get_ptr<const binary_t*>();
19654     }
19655 
19656     /// @}
19657 
19658 
19659     ////////////////////
19660     // element access //
19661     ////////////////////
19662 
19663     /// @name element access
19664     /// Access to the JSON value.
19665     /// @{
19666 
19667     /*!
19668     @brief access specified array element with bounds checking
19669 
19670     Returns a reference to the element at specified location @a idx, with
19671     bounds checking.
19672 
19673     @param[in] idx  index of the element to access
19674 
19675     @return reference to the element at index @a idx
19676 
19677     @throw type_error.304 if the JSON value is not an array; in this case,
19678     calling `at` with an index makes no sense. See example below.
19679     @throw out_of_range.401 if the index @a idx is out of range of the array;
19680     that is, `idx >= size()`. See example below.
19681 
19682     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19683     changes in the JSON value.
19684 
19685     @complexity Constant.
19686 
19687     @since version 1.0.0
19688 
19689     @liveexample{The example below shows how array elements can be read and
19690     written using `at()`. It also demonstrates the different exceptions that
19691     can be thrown.,at__size_type}
19692     */
at(size_type idx)19693     reference at(size_type idx)
19694     {
19695         // at only works for arrays
19696         if (JSON_HEDLEY_LIKELY(is_array()))
19697         {
19698             JSON_TRY
19699             {
19700                 return m_value.array->at(idx);
19701             }
19702             JSON_CATCH (std::out_of_range&)
19703             {
19704                 // create better exception explanation
19705                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19706             }
19707         }
19708         else
19709         {
19710             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19711         }
19712     }
19713 
19714     /*!
19715     @brief access specified array element with bounds checking
19716 
19717     Returns a const reference to the element at specified location @a idx,
19718     with bounds checking.
19719 
19720     @param[in] idx  index of the element to access
19721 
19722     @return const reference to the element at index @a idx
19723 
19724     @throw type_error.304 if the JSON value is not an array; in this case,
19725     calling `at` with an index makes no sense. See example below.
19726     @throw out_of_range.401 if the index @a idx is out of range of the array;
19727     that is, `idx >= size()`. See example below.
19728 
19729     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19730     changes in the JSON value.
19731 
19732     @complexity Constant.
19733 
19734     @since version 1.0.0
19735 
19736     @liveexample{The example below shows how array elements can be read using
19737     `at()`. It also demonstrates the different exceptions that can be thrown.,
19738     at__size_type_const}
19739     */
at(size_type idx) const19740     const_reference at(size_type idx) const
19741     {
19742         // at only works for arrays
19743         if (JSON_HEDLEY_LIKELY(is_array()))
19744         {
19745             JSON_TRY
19746             {
19747                 return m_value.array->at(idx);
19748             }
19749             JSON_CATCH (std::out_of_range&)
19750             {
19751                 // create better exception explanation
19752                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19753             }
19754         }
19755         else
19756         {
19757             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19758         }
19759     }
19760 
19761     /*!
19762     @brief access specified object element with bounds checking
19763 
19764     Returns a reference to the element at with specified key @a key, with
19765     bounds checking.
19766 
19767     @param[in] key  key of the element to access
19768 
19769     @return reference to the element at key @a key
19770 
19771     @throw type_error.304 if the JSON value is not an object; in this case,
19772     calling `at` with a key makes no sense. See example below.
19773     @throw out_of_range.403 if the key @a key is is not stored in the object;
19774     that is, `find(key) == end()`. See example below.
19775 
19776     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19777     changes in the JSON value.
19778 
19779     @complexity Logarithmic in the size of the container.
19780 
19781     @sa @ref operator[](const typename object_t::key_type&) for unchecked
19782     access by reference
19783     @sa @ref value() for access by value with a default value
19784 
19785     @since version 1.0.0
19786 
19787     @liveexample{The example below shows how object elements can be read and
19788     written using `at()`. It also demonstrates the different exceptions that
19789     can be thrown.,at__object_t_key_type}
19790     */
at(const typename object_t::key_type & key)19791     reference at(const typename object_t::key_type& key)
19792     {
19793         // at only works for objects
19794         if (JSON_HEDLEY_LIKELY(is_object()))
19795         {
19796             JSON_TRY
19797             {
19798                 return m_value.object->at(key);
19799             }
19800             JSON_CATCH (std::out_of_range&)
19801             {
19802                 // create better exception explanation
19803                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19804             }
19805         }
19806         else
19807         {
19808             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19809         }
19810     }
19811 
19812     /*!
19813     @brief access specified object element with bounds checking
19814 
19815     Returns a const reference to the element at with specified key @a key,
19816     with bounds checking.
19817 
19818     @param[in] key  key of the element to access
19819 
19820     @return const reference to the element at key @a key
19821 
19822     @throw type_error.304 if the JSON value is not an object; in this case,
19823     calling `at` with a key makes no sense. See example below.
19824     @throw out_of_range.403 if the key @a key is is not stored in the object;
19825     that is, `find(key) == end()`. See example below.
19826 
19827     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19828     changes in the JSON value.
19829 
19830     @complexity Logarithmic in the size of the container.
19831 
19832     @sa @ref operator[](const typename object_t::key_type&) for unchecked
19833     access by reference
19834     @sa @ref value() for access by value with a default value
19835 
19836     @since version 1.0.0
19837 
19838     @liveexample{The example below shows how object elements can be read using
19839     `at()`. It also demonstrates the different exceptions that can be thrown.,
19840     at__object_t_key_type_const}
19841     */
at(const typename object_t::key_type & key) const19842     const_reference at(const typename object_t::key_type& key) const
19843     {
19844         // at only works for objects
19845         if (JSON_HEDLEY_LIKELY(is_object()))
19846         {
19847             JSON_TRY
19848             {
19849                 return m_value.object->at(key);
19850             }
19851             JSON_CATCH (std::out_of_range&)
19852             {
19853                 // create better exception explanation
19854                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19855             }
19856         }
19857         else
19858         {
19859             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19860         }
19861     }
19862 
19863     /*!
19864     @brief access specified array element
19865 
19866     Returns a reference to the element at specified location @a idx.
19867 
19868     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
19869     then the array is silently filled up with `null` values to make `idx` a
19870     valid reference to the last stored element.
19871 
19872     @param[in] idx  index of the element to access
19873 
19874     @return reference to the element at index @a idx
19875 
19876     @throw type_error.305 if the JSON value is not an array or null; in that
19877     cases, using the [] operator with an index makes no sense.
19878 
19879     @complexity Constant if @a idx is in the range of the array. Otherwise
19880     linear in `idx - size()`.
19881 
19882     @liveexample{The example below shows how array elements can be read and
19883     written using `[]` operator. Note the addition of `null`
19884     values.,operatorarray__size_type}
19885 
19886     @since version 1.0.0
19887     */
operator [](size_type idx)19888     reference operator[](size_type idx)
19889     {
19890         // implicitly convert null value to an empty array
19891         if (is_null())
19892         {
19893             m_type = value_t::array;
19894             m_value.array = create<array_t>();
19895             assert_invariant();
19896         }
19897 
19898         // operator[] only works for arrays
19899         if (JSON_HEDLEY_LIKELY(is_array()))
19900         {
19901             // fill up array with null values if given idx is outside range
19902             if (idx >= m_value.array->size())
19903             {
19904                 m_value.array->insert(m_value.array->end(),
19905                                       idx - m_value.array->size() + 1,
19906                                       basic_json());
19907             }
19908 
19909             return m_value.array->operator[](idx);
19910         }
19911 
19912         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19913     }
19914 
19915     /*!
19916     @brief access specified array element
19917 
19918     Returns a const reference to the element at specified location @a idx.
19919 
19920     @param[in] idx  index of the element to access
19921 
19922     @return const reference to the element at index @a idx
19923 
19924     @throw type_error.305 if the JSON value is not an array; in that case,
19925     using the [] operator with an index makes no sense.
19926 
19927     @complexity Constant.
19928 
19929     @liveexample{The example below shows how array elements can be read using
19930     the `[]` operator.,operatorarray__size_type_const}
19931 
19932     @since version 1.0.0
19933     */
operator [](size_type idx) const19934     const_reference operator[](size_type idx) const
19935     {
19936         // const operator[] only works for arrays
19937         if (JSON_HEDLEY_LIKELY(is_array()))
19938         {
19939             return m_value.array->operator[](idx);
19940         }
19941 
19942         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
19943     }
19944 
19945     /*!
19946     @brief access specified object element
19947 
19948     Returns a reference to the element at with specified key @a key.
19949 
19950     @note If @a key is not found in the object, then it is silently added to
19951     the object and filled with a `null` value to make `key` a valid reference.
19952     In case the value was `null` before, it is converted to an object.
19953 
19954     @param[in] key  key of the element to access
19955 
19956     @return reference to the element at key @a key
19957 
19958     @throw type_error.305 if the JSON value is not an object or null; in that
19959     cases, using the [] operator with a key makes no sense.
19960 
19961     @complexity Logarithmic in the size of the container.
19962 
19963     @liveexample{The example below shows how object elements can be read and
19964     written using the `[]` operator.,operatorarray__key_type}
19965 
19966     @sa @ref at(const typename object_t::key_type&) for access by reference
19967     with range checking
19968     @sa @ref value() for access by value with a default value
19969 
19970     @since version 1.0.0
19971     */
operator [](const typename object_t::key_type & key)19972     reference operator[](const typename object_t::key_type& key)
19973     {
19974         // implicitly convert null value to an empty object
19975         if (is_null())
19976         {
19977             m_type = value_t::object;
19978             m_value.object = create<object_t>();
19979             assert_invariant();
19980         }
19981 
19982         // operator[] only works for objects
19983         if (JSON_HEDLEY_LIKELY(is_object()))
19984         {
19985             return m_value.object->operator[](key);
19986         }
19987 
19988         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
19989     }
19990 
19991     /*!
19992     @brief read-only access specified object element
19993 
19994     Returns a const reference to the element at with specified key @a key. No
19995     bounds checking is performed.
19996 
19997     @warning If the element with key @a key does not exist, the behavior is
19998     undefined.
19999 
20000     @param[in] key  key of the element to access
20001 
20002     @return const reference to the element at key @a key
20003 
20004     @pre The element with key @a key must exist. **This precondition is
20005          enforced with an assertion.**
20006 
20007     @throw type_error.305 if the JSON value is not an object; in that case,
20008     using the [] operator with a key makes no sense.
20009 
20010     @complexity Logarithmic in the size of the container.
20011 
20012     @liveexample{The example below shows how object elements can be read using
20013     the `[]` operator.,operatorarray__key_type_const}
20014 
20015     @sa @ref at(const typename object_t::key_type&) for access by reference
20016     with range checking
20017     @sa @ref value() for access by value with a default value
20018 
20019     @since version 1.0.0
20020     */
operator [](const typename object_t::key_type & key) const20021     const_reference operator[](const typename object_t::key_type& key) const
20022     {
20023         // const operator[] only works for objects
20024         if (JSON_HEDLEY_LIKELY(is_object()))
20025         {
20026             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20027             return m_value.object->find(key)->second;
20028         }
20029 
20030         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20031     }
20032 
20033     /*!
20034     @brief access specified object element
20035 
20036     Returns a reference to the element at with specified key @a key.
20037 
20038     @note If @a key is not found in the object, then it is silently added to
20039     the object and filled with a `null` value to make `key` a valid reference.
20040     In case the value was `null` before, it is converted to an object.
20041 
20042     @param[in] key  key of the element to access
20043 
20044     @return reference to the element at key @a key
20045 
20046     @throw type_error.305 if the JSON value is not an object or null; in that
20047     cases, using the [] operator with a key makes no sense.
20048 
20049     @complexity Logarithmic in the size of the container.
20050 
20051     @liveexample{The example below shows how object elements can be read and
20052     written using the `[]` operator.,operatorarray__key_type}
20053 
20054     @sa @ref at(const typename object_t::key_type&) for access by reference
20055     with range checking
20056     @sa @ref value() for access by value with a default value
20057 
20058     @since version 1.1.0
20059     */
20060     template<typename T>
20061     JSON_HEDLEY_NON_NULL(2)
operator [](T * key)20062     reference operator[](T* key)
20063     {
20064         // implicitly convert null to object
20065         if (is_null())
20066         {
20067             m_type = value_t::object;
20068             m_value = value_t::object;
20069             assert_invariant();
20070         }
20071 
20072         // at only works for objects
20073         if (JSON_HEDLEY_LIKELY(is_object()))
20074         {
20075             return m_value.object->operator[](key);
20076         }
20077 
20078         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20079     }
20080 
20081     /*!
20082     @brief read-only access specified object element
20083 
20084     Returns a const reference to the element at with specified key @a key. No
20085     bounds checking is performed.
20086 
20087     @warning If the element with key @a key does not exist, the behavior is
20088     undefined.
20089 
20090     @param[in] key  key of the element to access
20091 
20092     @return const reference to the element at key @a key
20093 
20094     @pre The element with key @a key must exist. **This precondition is
20095          enforced with an assertion.**
20096 
20097     @throw type_error.305 if the JSON value is not an object; in that case,
20098     using the [] operator with a key makes no sense.
20099 
20100     @complexity Logarithmic in the size of the container.
20101 
20102     @liveexample{The example below shows how object elements can be read using
20103     the `[]` operator.,operatorarray__key_type_const}
20104 
20105     @sa @ref at(const typename object_t::key_type&) for access by reference
20106     with range checking
20107     @sa @ref value() for access by value with a default value
20108 
20109     @since version 1.1.0
20110     */
20111     template<typename T>
20112     JSON_HEDLEY_NON_NULL(2)
operator [](T * key) const20113     const_reference operator[](T* key) const
20114     {
20115         // at only works for objects
20116         if (JSON_HEDLEY_LIKELY(is_object()))
20117         {
20118             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20119             return m_value.object->find(key)->second;
20120         }
20121 
20122         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20123     }
20124 
20125     /*!
20126     @brief access specified object element with default value
20127 
20128     Returns either a copy of an object's element at the specified key @a key
20129     or a given default value if no element with key @a key exists.
20130 
20131     The function is basically equivalent to executing
20132     @code {.cpp}
20133     try {
20134         return at(key);
20135     } catch(out_of_range) {
20136         return default_value;
20137     }
20138     @endcode
20139 
20140     @note Unlike @ref at(const typename object_t::key_type&), this function
20141     does not throw if the given key @a key was not found.
20142 
20143     @note Unlike @ref operator[](const typename object_t::key_type& key), this
20144     function does not implicitly add an element to the position defined by @a
20145     key. This function is furthermore also applicable to const objects.
20146 
20147     @param[in] key  key of the element to access
20148     @param[in] default_value  the value to return if @a key is not found
20149 
20150     @tparam ValueType type compatible to JSON values, for instance `int` for
20151     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20152     JSON arrays. Note the type of the expected value at @a key and the default
20153     value @a default_value must be compatible.
20154 
20155     @return copy of the element at key @a key or @a default_value if @a key
20156     is not found
20157 
20158     @throw type_error.302 if @a default_value does not match the type of the
20159     value at @a key
20160     @throw type_error.306 if the JSON value is not an object; in that case,
20161     using `value()` with a key makes no sense.
20162 
20163     @complexity Logarithmic in the size of the container.
20164 
20165     @liveexample{The example below shows how object elements can be queried
20166     with a default value.,basic_json__value}
20167 
20168     @sa @ref at(const typename object_t::key_type&) for access by reference
20169     with range checking
20170     @sa @ref operator[](const typename object_t::key_type&) for unchecked
20171     access by reference
20172 
20173     @since version 1.0.0
20174     */
20175     // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20176     template < class ValueType, typename std::enable_if <
20177                    detail::is_getable<basic_json_t, ValueType>::value
20178                    && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20179     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20180     {
20181         // at only works for objects
20182         if (JSON_HEDLEY_LIKELY(is_object()))
20183         {
20184             // if key is found, return value and given default value otherwise
20185             const auto it = find(key);
20186             if (it != end())
20187             {
20188                 return it->template get<ValueType>();
20189             }
20190 
20191             return default_value;
20192         }
20193 
20194         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20195     }
20196 
20197     /*!
20198     @brief overload for a default value of type const char*
20199     @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
20200     */
value(const typename object_t::key_type & key,const char * default_value) const20201     string_t value(const typename object_t::key_type& key, const char* default_value) const
20202     {
20203         return value(key, string_t(default_value));
20204     }
20205 
20206     /*!
20207     @brief access specified object element via JSON Pointer with default value
20208 
20209     Returns either a copy of an object's element at the specified key @a key
20210     or a given default value if no element with key @a key exists.
20211 
20212     The function is basically equivalent to executing
20213     @code {.cpp}
20214     try {
20215         return at(ptr);
20216     } catch(out_of_range) {
20217         return default_value;
20218     }
20219     @endcode
20220 
20221     @note Unlike @ref at(const json_pointer&), this function does not throw
20222     if the given key @a key was not found.
20223 
20224     @param[in] ptr  a JSON pointer to the element to access
20225     @param[in] default_value  the value to return if @a ptr found no value
20226 
20227     @tparam ValueType type compatible to JSON values, for instance `int` for
20228     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20229     JSON arrays. Note the type of the expected value at @a key and the default
20230     value @a default_value must be compatible.
20231 
20232     @return copy of the element at key @a key or @a default_value if @a key
20233     is not found
20234 
20235     @throw type_error.302 if @a default_value does not match the type of the
20236     value at @a ptr
20237     @throw type_error.306 if the JSON value is not an object; in that case,
20238     using `value()` with a key makes no sense.
20239 
20240     @complexity Logarithmic in the size of the container.
20241 
20242     @liveexample{The example below shows how object elements can be queried
20243     with a default value.,basic_json__value_ptr}
20244 
20245     @sa @ref operator[](const json_pointer&) for unchecked access by reference
20246 
20247     @since version 2.0.2
20248     */
20249     template<class ValueType, typename std::enable_if<
20250                  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20251     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20252     {
20253         // at only works for objects
20254         if (JSON_HEDLEY_LIKELY(is_object()))
20255         {
20256             // if pointer resolves a value, return it or use default value
20257             JSON_TRY
20258             {
20259                 return ptr.get_checked(this).template get<ValueType>();
20260             }
20261             JSON_INTERNAL_CATCH (out_of_range&)
20262             {
20263                 return default_value;
20264             }
20265         }
20266 
20267         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20268     }
20269 
20270     /*!
20271     @brief overload for a default value of type const char*
20272     @copydoc basic_json::value(const json_pointer&, ValueType) const
20273     */
20274     JSON_HEDLEY_NON_NULL(3)
value(const json_pointer & ptr,const char * default_value) const20275     string_t value(const json_pointer& ptr, const char* default_value) const
20276     {
20277         return value(ptr, string_t(default_value));
20278     }
20279 
20280     /*!
20281     @brief access the first element
20282 
20283     Returns a reference to the first element in the container. For a JSON
20284     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
20285 
20286     @return In case of a structured type (array or object), a reference to the
20287     first element is returned. In case of number, string, boolean, or binary
20288     values, a reference to the value is returned.
20289 
20290     @complexity Constant.
20291 
20292     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20293     or an empty array or object (undefined behavior, **guarded by
20294     assertions**).
20295     @post The JSON value remains unchanged.
20296 
20297     @throw invalid_iterator.214 when called on `null` value
20298 
20299     @liveexample{The following code shows an example for `front()`.,front}
20300 
20301     @sa @ref back() -- access the last element
20302 
20303     @since version 1.0.0
20304     */
front()20305     reference front()
20306     {
20307         return *begin();
20308     }
20309 
20310     /*!
20311     @copydoc basic_json::front()
20312     */
front() const20313     const_reference front() const
20314     {
20315         return *cbegin();
20316     }
20317 
20318     /*!
20319     @brief access the last element
20320 
20321     Returns a reference to the last element in the container. For a JSON
20322     container `c`, the expression `c.back()` is equivalent to
20323     @code {.cpp}
20324     auto tmp = c.end();
20325     --tmp;
20326     return *tmp;
20327     @endcode
20328 
20329     @return In case of a structured type (array or object), a reference to the
20330     last element is returned. In case of number, string, boolean, or binary
20331     values, a reference to the value is returned.
20332 
20333     @complexity Constant.
20334 
20335     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20336     or an empty array or object (undefined behavior, **guarded by
20337     assertions**).
20338     @post The JSON value remains unchanged.
20339 
20340     @throw invalid_iterator.214 when called on a `null` value. See example
20341     below.
20342 
20343     @liveexample{The following code shows an example for `back()`.,back}
20344 
20345     @sa @ref front() -- access the first element
20346 
20347     @since version 1.0.0
20348     */
back()20349     reference back()
20350     {
20351         auto tmp = end();
20352         --tmp;
20353         return *tmp;
20354     }
20355 
20356     /*!
20357     @copydoc basic_json::back()
20358     */
back() const20359     const_reference back() const
20360     {
20361         auto tmp = cend();
20362         --tmp;
20363         return *tmp;
20364     }
20365 
20366     /*!
20367     @brief remove element given an iterator
20368 
20369     Removes the element specified by iterator @a pos. The iterator @a pos must
20370     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
20371     but is not dereferenceable) cannot be used as a value for @a pos.
20372 
20373     If called on a primitive type other than `null`, the resulting JSON value
20374     will be `null`.
20375 
20376     @param[in] pos iterator to the element to remove
20377     @return Iterator following the last removed element. If the iterator @a
20378     pos refers to the last element, the `end()` iterator is returned.
20379 
20380     @tparam IteratorType an @ref iterator or @ref const_iterator
20381 
20382     @post Invalidates iterators and references at or after the point of the
20383     erase, including the `end()` iterator.
20384 
20385     @throw type_error.307 if called on a `null` value; example: `"cannot use
20386     erase() with null"`
20387     @throw invalid_iterator.202 if called on an iterator which does not belong
20388     to the current JSON value; example: `"iterator does not fit current
20389     value"`
20390     @throw invalid_iterator.205 if called on a primitive type with invalid
20391     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
20392     out of range"`
20393 
20394     @complexity The complexity depends on the type:
20395     - objects: amortized constant
20396     - arrays: linear in distance between @a pos and the end of the container
20397     - strings and binary: linear in the length of the member
20398     - other types: constant
20399 
20400     @liveexample{The example shows the result of `erase()` for different JSON
20401     types.,erase__IteratorType}
20402 
20403     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20404     the given range
20405     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20406     from an object at the given key
20407     @sa @ref erase(const size_type) -- removes the element from an array at
20408     the given index
20409 
20410     @since version 1.0.0
20411     */
20412     template < class IteratorType, typename std::enable_if <
20413                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20414                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20415                = 0 >
20416     IteratorType erase(IteratorType pos)
20417     {
20418         // make sure iterator fits the current value
20419         if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20420         {
20421             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20422         }
20423 
20424         IteratorType result = end();
20425 
20426         switch (m_type)
20427         {
20428             case value_t::boolean:
20429             case value_t::number_float:
20430             case value_t::number_integer:
20431             case value_t::number_unsigned:
20432             case value_t::string:
20433             case value_t::binary:
20434             {
20435                 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20436                 {
20437                     JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20438                 }
20439 
20440                 if (is_string())
20441                 {
20442                     AllocatorType<string_t> alloc;
20443                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20444                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20445                     m_value.string = nullptr;
20446                 }
20447                 else if (is_binary())
20448                 {
20449                     AllocatorType<binary_t> alloc;
20450                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20451                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20452                     m_value.binary = nullptr;
20453                 }
20454 
20455                 m_type = value_t::null;
20456                 assert_invariant();
20457                 break;
20458             }
20459 
20460             case value_t::object:
20461             {
20462                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20463                 break;
20464             }
20465 
20466             case value_t::array:
20467             {
20468                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20469                 break;
20470             }
20471 
20472             default:
20473                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20474         }
20475 
20476         return result;
20477     }
20478 
20479     /*!
20480     @brief remove elements given an iterator range
20481 
20482     Removes the element specified by the range `[first; last)`. The iterator
20483     @a first does not need to be dereferenceable if `first == last`: erasing
20484     an empty range is a no-op.
20485 
20486     If called on a primitive type other than `null`, the resulting JSON value
20487     will be `null`.
20488 
20489     @param[in] first iterator to the beginning of the range to remove
20490     @param[in] last iterator past the end of the range to remove
20491     @return Iterator following the last removed element. If the iterator @a
20492     second refers to the last element, the `end()` iterator is returned.
20493 
20494     @tparam IteratorType an @ref iterator or @ref const_iterator
20495 
20496     @post Invalidates iterators and references at or after the point of the
20497     erase, including the `end()` iterator.
20498 
20499     @throw type_error.307 if called on a `null` value; example: `"cannot use
20500     erase() with null"`
20501     @throw invalid_iterator.203 if called on iterators which does not belong
20502     to the current JSON value; example: `"iterators do not fit current value"`
20503     @throw invalid_iterator.204 if called on a primitive type with invalid
20504     iterators (i.e., if `first != begin()` and `last != end()`); example:
20505     `"iterators out of range"`
20506 
20507     @complexity The complexity depends on the type:
20508     - objects: `log(size()) + std::distance(first, last)`
20509     - arrays: linear in the distance between @a first and @a last, plus linear
20510       in the distance between @a last and end of the container
20511     - strings and binary: linear in the length of the member
20512     - other types: constant
20513 
20514     @liveexample{The example shows the result of `erase()` for different JSON
20515     types.,erase__IteratorType_IteratorType}
20516 
20517     @sa @ref erase(IteratorType) -- removes the element at a given position
20518     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20519     from an object at the given key
20520     @sa @ref erase(const size_type) -- removes the element from an array at
20521     the given index
20522 
20523     @since version 1.0.0
20524     */
20525     template < class IteratorType, typename std::enable_if <
20526                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20527                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20528                = 0 >
20529     IteratorType erase(IteratorType first, IteratorType last)
20530     {
20531         // make sure iterator fits the current value
20532         if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20533         {
20534             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20535         }
20536 
20537         IteratorType result = end();
20538 
20539         switch (m_type)
20540         {
20541             case value_t::boolean:
20542             case value_t::number_float:
20543             case value_t::number_integer:
20544             case value_t::number_unsigned:
20545             case value_t::string:
20546             case value_t::binary:
20547             {
20548                 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20549                                        || !last.m_it.primitive_iterator.is_end()))
20550                 {
20551                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20552                 }
20553 
20554                 if (is_string())
20555                 {
20556                     AllocatorType<string_t> alloc;
20557                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20558                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20559                     m_value.string = nullptr;
20560                 }
20561                 else if (is_binary())
20562                 {
20563                     AllocatorType<binary_t> alloc;
20564                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20565                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20566                     m_value.binary = nullptr;
20567                 }
20568 
20569                 m_type = value_t::null;
20570                 assert_invariant();
20571                 break;
20572             }
20573 
20574             case value_t::object:
20575             {
20576                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20577                                               last.m_it.object_iterator);
20578                 break;
20579             }
20580 
20581             case value_t::array:
20582             {
20583                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20584                                              last.m_it.array_iterator);
20585                 break;
20586             }
20587 
20588             default:
20589                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20590         }
20591 
20592         return result;
20593     }
20594 
20595     /*!
20596     @brief remove element from a JSON object given a key
20597 
20598     Removes elements from a JSON object with the key value @a key.
20599 
20600     @param[in] key value of the elements to remove
20601 
20602     @return Number of elements removed. If @a ObjectType is the default
20603     `std::map` type, the return value will always be `0` (@a key was not
20604     found) or `1` (@a key was found).
20605 
20606     @post References and iterators to the erased elements are invalidated.
20607     Other references and iterators are not affected.
20608 
20609     @throw type_error.307 when called on a type other than JSON object;
20610     example: `"cannot use erase() with null"`
20611 
20612     @complexity `log(size()) + count(key)`
20613 
20614     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
20615 
20616     @sa @ref erase(IteratorType) -- removes the element at a given position
20617     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20618     the given range
20619     @sa @ref erase(const size_type) -- removes the element from an array at
20620     the given index
20621 
20622     @since version 1.0.0
20623     */
erase(const typename object_t::key_type & key)20624     size_type erase(const typename object_t::key_type& key)
20625     {
20626         // this erase only works for objects
20627         if (JSON_HEDLEY_LIKELY(is_object()))
20628         {
20629             return m_value.object->erase(key);
20630         }
20631 
20632         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20633     }
20634 
20635     /*!
20636     @brief remove element from a JSON array given an index
20637 
20638     Removes element from a JSON array at the index @a idx.
20639 
20640     @param[in] idx index of the element to remove
20641 
20642     @throw type_error.307 when called on a type other than JSON object;
20643     example: `"cannot use erase() with null"`
20644     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
20645     is out of range"`
20646 
20647     @complexity Linear in distance between @a idx and the end of the container.
20648 
20649     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
20650 
20651     @sa @ref erase(IteratorType) -- removes the element at a given position
20652     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20653     the given range
20654     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20655     from an object at the given key
20656 
20657     @since version 1.0.0
20658     */
erase(const size_type idx)20659     void erase(const size_type idx)
20660     {
20661         // this erase only works for arrays
20662         if (JSON_HEDLEY_LIKELY(is_array()))
20663         {
20664             if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20665             {
20666                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20667             }
20668 
20669             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20670         }
20671         else
20672         {
20673             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20674         }
20675     }
20676 
20677     /// @}
20678 
20679 
20680     ////////////
20681     // lookup //
20682     ////////////
20683 
20684     /// @name lookup
20685     /// @{
20686 
20687     /*!
20688     @brief find an element in a JSON object
20689 
20690     Finds an element in a JSON object with key equivalent to @a key. If the
20691     element is not found or the JSON value is not an object, end() is
20692     returned.
20693 
20694     @note This method always returns @ref end() when executed on a JSON type
20695           that is not an object.
20696 
20697     @param[in] key key value of the element to search for.
20698 
20699     @return Iterator to an element with key equivalent to @a key. If no such
20700     element is found or the JSON value is not an object, past-the-end (see
20701     @ref end()) iterator is returned.
20702 
20703     @complexity Logarithmic in the size of the JSON object.
20704 
20705     @liveexample{The example shows how `find()` is used.,find__key_type}
20706 
20707     @sa @ref contains(KeyT&&) const -- checks whether a key exists
20708 
20709     @since version 1.0.0
20710     */
20711     template<typename KeyT>
find(KeyT && key)20712     iterator find(KeyT&& key)
20713     {
20714         auto result = end();
20715 
20716         if (is_object())
20717         {
20718             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20719         }
20720 
20721         return result;
20722     }
20723 
20724     /*!
20725     @brief find an element in a JSON object
20726     @copydoc find(KeyT&&)
20727     */
20728     template<typename KeyT>
find(KeyT && key) const20729     const_iterator find(KeyT&& key) const
20730     {
20731         auto result = cend();
20732 
20733         if (is_object())
20734         {
20735             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20736         }
20737 
20738         return result;
20739     }
20740 
20741     /*!
20742     @brief returns the number of occurrences of a key in a JSON object
20743 
20744     Returns the number of elements with key @a key. If ObjectType is the
20745     default `std::map` type, the return value will always be `0` (@a key was
20746     not found) or `1` (@a key was found).
20747 
20748     @note This method always returns `0` when executed on a JSON type that is
20749           not an object.
20750 
20751     @param[in] key key value of the element to count
20752 
20753     @return Number of elements with key @a key. If the JSON value is not an
20754     object, the return value will be `0`.
20755 
20756     @complexity Logarithmic in the size of the JSON object.
20757 
20758     @liveexample{The example shows how `count()` is used.,count}
20759 
20760     @since version 1.0.0
20761     */
20762     template<typename KeyT>
count(KeyT && key) const20763     size_type count(KeyT&& key) const
20764     {
20765         // return 0 for all nonobject types
20766         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20767     }
20768 
20769     /*!
20770     @brief check the existence of an element in a JSON object
20771 
20772     Check whether an element exists in a JSON object with key equivalent to
20773     @a key. If the element is not found or the JSON value is not an object,
20774     false is returned.
20775 
20776     @note This method always returns false when executed on a JSON type
20777           that is not an object.
20778 
20779     @param[in] key key value to check its existence.
20780 
20781     @return true if an element with specified @a key exists. If no such
20782     element with such key is found or the JSON value is not an object,
20783     false is returned.
20784 
20785     @complexity Logarithmic in the size of the JSON object.
20786 
20787     @liveexample{The following code shows an example for `contains()`.,contains}
20788 
20789     @sa @ref find(KeyT&&) -- returns an iterator to an object element
20790     @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
20791 
20792     @since version 3.6.0
20793     */
20794     template < typename KeyT, typename std::enable_if <
20795                    !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
contains(KeyT && key) const20796     bool contains(KeyT && key) const
20797     {
20798         return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20799     }
20800 
20801     /*!
20802     @brief check the existence of an element in a JSON object given a JSON pointer
20803 
20804     Check whether the given JSON pointer @a ptr can be resolved in the current
20805     JSON value.
20806 
20807     @note This method can be executed on any JSON value type.
20808 
20809     @param[in] ptr JSON pointer to check its existence.
20810 
20811     @return true if the JSON pointer can be resolved to a stored value, false
20812     otherwise.
20813 
20814     @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
20815 
20816     @throw parse_error.106   if an array index begins with '0'
20817     @throw parse_error.109   if an array index was not a number
20818 
20819     @complexity Logarithmic in the size of the JSON object.
20820 
20821     @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
20822 
20823     @sa @ref contains(KeyT &&) const -- checks the existence of a key
20824 
20825     @since version 3.7.0
20826     */
contains(const json_pointer & ptr) const20827     bool contains(const json_pointer& ptr) const
20828     {
20829         return ptr.contains(this);
20830     }
20831 
20832     /// @}
20833 
20834 
20835     ///////////////
20836     // iterators //
20837     ///////////////
20838 
20839     /// @name iterators
20840     /// @{
20841 
20842     /*!
20843     @brief returns an iterator to the first element
20844 
20845     Returns an iterator to the first element.
20846 
20847     @image html range-begin-end.svg "Illustration from cppreference.com"
20848 
20849     @return iterator to the first element
20850 
20851     @complexity Constant.
20852 
20853     @requirement This function helps `basic_json` satisfying the
20854     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
20855     requirements:
20856     - The complexity is constant.
20857 
20858     @liveexample{The following code shows an example for `begin()`.,begin}
20859 
20860     @sa @ref cbegin() -- returns a const iterator to the beginning
20861     @sa @ref end() -- returns an iterator to the end
20862     @sa @ref cend() -- returns a const iterator to the end
20863 
20864     @since version 1.0.0
20865     */
begin()20866     iterator begin() noexcept
20867     {
20868         iterator result(this);
20869         result.set_begin();
20870         return result;
20871     }
20872 
20873     /*!
20874     @copydoc basic_json::cbegin()
20875     */
begin() const20876     const_iterator begin() const noexcept
20877     {
20878         return cbegin();
20879     }
20880 
20881     /*!
20882     @brief returns a const iterator to the first element
20883 
20884     Returns a const iterator to the first element.
20885 
20886     @image html range-begin-end.svg "Illustration from cppreference.com"
20887 
20888     @return const iterator to the first element
20889 
20890     @complexity Constant.
20891 
20892     @requirement This function helps `basic_json` satisfying the
20893     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
20894     requirements:
20895     - The complexity is constant.
20896     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
20897 
20898     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
20899 
20900     @sa @ref begin() -- returns an iterator to the beginning
20901     @sa @ref end() -- returns an iterator to the end
20902     @sa @ref cend() -- returns a const iterator to the end
20903 
20904     @since version 1.0.0
20905     */
cbegin() const20906     const_iterator cbegin() const noexcept
20907     {
20908         const_iterator result(this);
20909         result.set_begin();
20910         return result;
20911     }
20912 
20913     /*!
20914     @brief returns an iterator to one past the last element
20915 
20916     Returns an iterator to one past the last element.
20917 
20918     @image html range-begin-end.svg "Illustration from cppreference.com"
20919 
20920     @return iterator one past the last element
20921 
20922     @complexity Constant.
20923 
20924     @requirement This function helps `basic_json` satisfying the
20925     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
20926     requirements:
20927     - The complexity is constant.
20928 
20929     @liveexample{The following code shows an example for `end()`.,end}
20930 
20931     @sa @ref cend() -- returns a const iterator to the end
20932     @sa @ref begin() -- returns an iterator to the beginning
20933     @sa @ref cbegin() -- returns a const iterator to the beginning
20934 
20935     @since version 1.0.0
20936     */
end()20937     iterator end() noexcept
20938     {
20939         iterator result(this);
20940         result.set_end();
20941         return result;
20942     }
20943 
20944     /*!
20945     @copydoc basic_json::cend()
20946     */
end() const20947     const_iterator end() const noexcept
20948     {
20949         return cend();
20950     }
20951 
20952     /*!
20953     @brief returns a const iterator to one past the last element
20954 
20955     Returns a const iterator to one past the last element.
20956 
20957     @image html range-begin-end.svg "Illustration from cppreference.com"
20958 
20959     @return const iterator one past the last element
20960 
20961     @complexity Constant.
20962 
20963     @requirement This function helps `basic_json` satisfying the
20964     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
20965     requirements:
20966     - The complexity is constant.
20967     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
20968 
20969     @liveexample{The following code shows an example for `cend()`.,cend}
20970 
20971     @sa @ref end() -- returns an iterator to the end
20972     @sa @ref begin() -- returns an iterator to the beginning
20973     @sa @ref cbegin() -- returns a const iterator to the beginning
20974 
20975     @since version 1.0.0
20976     */
cend() const20977     const_iterator cend() const noexcept
20978     {
20979         const_iterator result(this);
20980         result.set_end();
20981         return result;
20982     }
20983 
20984     /*!
20985     @brief returns an iterator to the reverse-beginning
20986 
20987     Returns an iterator to the reverse-beginning; that is, the last element.
20988 
20989     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
20990 
20991     @complexity Constant.
20992 
20993     @requirement This function helps `basic_json` satisfying the
20994     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
20995     requirements:
20996     - The complexity is constant.
20997     - Has the semantics of `reverse_iterator(end())`.
20998 
20999     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
21000 
21001     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21002     @sa @ref rend() -- returns a reverse iterator to the end
21003     @sa @ref crend() -- returns a const reverse iterator to the end
21004 
21005     @since version 1.0.0
21006     */
rbegin()21007     reverse_iterator rbegin() noexcept
21008     {
21009         return reverse_iterator(end());
21010     }
21011 
21012     /*!
21013     @copydoc basic_json::crbegin()
21014     */
rbegin() const21015     const_reverse_iterator rbegin() const noexcept
21016     {
21017         return crbegin();
21018     }
21019 
21020     /*!
21021     @brief returns an iterator to the reverse-end
21022 
21023     Returns an iterator to the reverse-end; that is, one before the first
21024     element.
21025 
21026     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21027 
21028     @complexity Constant.
21029 
21030     @requirement This function helps `basic_json` satisfying the
21031     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21032     requirements:
21033     - The complexity is constant.
21034     - Has the semantics of `reverse_iterator(begin())`.
21035 
21036     @liveexample{The following code shows an example for `rend()`.,rend}
21037 
21038     @sa @ref crend() -- returns a const reverse iterator to the end
21039     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21040     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21041 
21042     @since version 1.0.0
21043     */
rend()21044     reverse_iterator rend() noexcept
21045     {
21046         return reverse_iterator(begin());
21047     }
21048 
21049     /*!
21050     @copydoc basic_json::crend()
21051     */
rend() const21052     const_reverse_iterator rend() const noexcept
21053     {
21054         return crend();
21055     }
21056 
21057     /*!
21058     @brief returns a const reverse iterator to the last element
21059 
21060     Returns a const iterator to the reverse-beginning; that is, the last
21061     element.
21062 
21063     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21064 
21065     @complexity Constant.
21066 
21067     @requirement This function helps `basic_json` satisfying the
21068     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21069     requirements:
21070     - The complexity is constant.
21071     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
21072 
21073     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
21074 
21075     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21076     @sa @ref rend() -- returns a reverse iterator to the end
21077     @sa @ref crend() -- returns a const reverse iterator to the end
21078 
21079     @since version 1.0.0
21080     */
crbegin() const21081     const_reverse_iterator crbegin() const noexcept
21082     {
21083         return const_reverse_iterator(cend());
21084     }
21085 
21086     /*!
21087     @brief returns a const reverse iterator to one before the first
21088 
21089     Returns a const reverse iterator to the reverse-end; that is, one before
21090     the first element.
21091 
21092     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21093 
21094     @complexity Constant.
21095 
21096     @requirement This function helps `basic_json` satisfying the
21097     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21098     requirements:
21099     - The complexity is constant.
21100     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
21101 
21102     @liveexample{The following code shows an example for `crend()`.,crend}
21103 
21104     @sa @ref rend() -- returns a reverse iterator to the end
21105     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21106     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21107 
21108     @since version 1.0.0
21109     */
crend() const21110     const_reverse_iterator crend() const noexcept
21111     {
21112         return const_reverse_iterator(cbegin());
21113     }
21114 
21115   public:
21116     /*!
21117     @brief wrapper to access iterator member functions in range-based for
21118 
21119     This function allows to access @ref iterator::key() and @ref
21120     iterator::value() during range-based for loops. In these loops, a
21121     reference to the JSON values is returned, so there is no access to the
21122     underlying iterator.
21123 
21124     For loop without iterator_wrapper:
21125 
21126     @code{cpp}
21127     for (auto it = j_object.begin(); it != j_object.end(); ++it)
21128     {
21129         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21130     }
21131     @endcode
21132 
21133     Range-based for loop without iterator proxy:
21134 
21135     @code{cpp}
21136     for (auto it : j_object)
21137     {
21138         // "it" is of type json::reference and has no key() member
21139         std::cout << "value: " << it << '\n';
21140     }
21141     @endcode
21142 
21143     Range-based for loop with iterator proxy:
21144 
21145     @code{cpp}
21146     for (auto it : json::iterator_wrapper(j_object))
21147     {
21148         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21149     }
21150     @endcode
21151 
21152     @note When iterating over an array, `key()` will return the index of the
21153           element as string (see example).
21154 
21155     @param[in] ref  reference to a JSON value
21156     @return iteration proxy object wrapping @a ref with an interface to use in
21157             range-based for loops
21158 
21159     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
21160 
21161     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21162     changes in the JSON value.
21163 
21164     @complexity Constant.
21165 
21166     @note The name of this function is not yet final and may change in the
21167     future.
21168 
21169     @deprecated This stream operator is deprecated and will be removed in
21170                 future 4.0.0 of the library. Please use @ref items() instead;
21171                 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
21172     */
items()21173     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21174     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21175     {
21176         return ref.items();
21177     }
21178 
21179     /*!
21180     @copydoc iterator_wrapper(reference)
21181     */
items()21182     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21183     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21184     {
21185         return ref.items();
21186     }
21187 
21188     /*!
21189     @brief helper to access iterator member functions in range-based for
21190 
21191     This function allows to access @ref iterator::key() and @ref
21192     iterator::value() during range-based for loops. In these loops, a
21193     reference to the JSON values is returned, so there is no access to the
21194     underlying iterator.
21195 
21196     For loop without `items()` function:
21197 
21198     @code{cpp}
21199     for (auto it = j_object.begin(); it != j_object.end(); ++it)
21200     {
21201         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21202     }
21203     @endcode
21204 
21205     Range-based for loop without `items()` function:
21206 
21207     @code{cpp}
21208     for (auto it : j_object)
21209     {
21210         // "it" is of type json::reference and has no key() member
21211         std::cout << "value: " << it << '\n';
21212     }
21213     @endcode
21214 
21215     Range-based for loop with `items()` function:
21216 
21217     @code{cpp}
21218     for (auto& el : j_object.items())
21219     {
21220         std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
21221     }
21222     @endcode
21223 
21224     The `items()` function also allows to use
21225     [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
21226     (C++17):
21227 
21228     @code{cpp}
21229     for (auto& [key, val] : j_object.items())
21230     {
21231         std::cout << "key: " << key << ", value:" << val << '\n';
21232     }
21233     @endcode
21234 
21235     @note When iterating over an array, `key()` will return the index of the
21236           element as string (see example). For primitive types (e.g., numbers),
21237           `key()` returns an empty string.
21238 
21239     @warning Using `items()` on temporary objects is dangerous. Make sure the
21240              object's lifetime exeeds the iteration. See
21241              <https://github.com/nlohmann/json/issues/2040> for more
21242              information.
21243 
21244     @return iteration proxy object wrapping @a ref with an interface to use in
21245             range-based for loops
21246 
21247     @liveexample{The following code shows how the function is used.,items}
21248 
21249     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21250     changes in the JSON value.
21251 
21252     @complexity Constant.
21253 
21254     @since version 3.1.0, structured bindings support since 3.5.0.
21255     */
items()21256     iteration_proxy<iterator> items() noexcept
21257     {
21258         return iteration_proxy<iterator>(*this);
21259     }
21260 
21261     /*!
21262     @copydoc items()
21263     */
items() const21264     iteration_proxy<const_iterator> items() const noexcept
21265     {
21266         return iteration_proxy<const_iterator>(*this);
21267     }
21268 
21269     /// @}
21270 
21271 
21272     //////////////
21273     // capacity //
21274     //////////////
21275 
21276     /// @name capacity
21277     /// @{
21278 
21279     /*!
21280     @brief checks whether the container is empty.
21281 
21282     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
21283 
21284     @return The return value depends on the different types and is
21285             defined as follows:
21286             Value type  | return value
21287             ----------- | -------------
21288             null        | `true`
21289             boolean     | `false`
21290             string      | `false`
21291             number      | `false`
21292             binary      | `false`
21293             object      | result of function `object_t::empty()`
21294             array       | result of function `array_t::empty()`
21295 
21296     @liveexample{The following code uses `empty()` to check if a JSON
21297     object contains any elements.,empty}
21298 
21299     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21300     the Container concept; that is, their `empty()` functions have constant
21301     complexity.
21302 
21303     @iterators No changes.
21304 
21305     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21306 
21307     @note This function does not return whether a string stored as JSON value
21308     is empty - it returns whether the JSON container itself is empty which is
21309     false in the case of a string.
21310 
21311     @requirement This function helps `basic_json` satisfying the
21312     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21313     requirements:
21314     - The complexity is constant.
21315     - Has the semantics of `begin() == end()`.
21316 
21317     @sa @ref size() -- returns the number of elements
21318 
21319     @since version 1.0.0
21320     */
empty() const21321     bool empty() const noexcept
21322     {
21323         switch (m_type)
21324         {
21325             case value_t::null:
21326             {
21327                 // null values are empty
21328                 return true;
21329             }
21330 
21331             case value_t::array:
21332             {
21333                 // delegate call to array_t::empty()
21334                 return m_value.array->empty();
21335             }
21336 
21337             case value_t::object:
21338             {
21339                 // delegate call to object_t::empty()
21340                 return m_value.object->empty();
21341             }
21342 
21343             default:
21344             {
21345                 // all other types are nonempty
21346                 return false;
21347             }
21348         }
21349     }
21350 
21351     /*!
21352     @brief returns the number of elements
21353 
21354     Returns the number of elements in a JSON value.
21355 
21356     @return The return value depends on the different types and is
21357             defined as follows:
21358             Value type  | return value
21359             ----------- | -------------
21360             null        | `0`
21361             boolean     | `1`
21362             string      | `1`
21363             number      | `1`
21364             binary      | `1`
21365             object      | result of function object_t::size()
21366             array       | result of function array_t::size()
21367 
21368     @liveexample{The following code calls `size()` on the different value
21369     types.,size}
21370 
21371     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21372     the Container concept; that is, their size() functions have constant
21373     complexity.
21374 
21375     @iterators No changes.
21376 
21377     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21378 
21379     @note This function does not return the length of a string stored as JSON
21380     value - it returns the number of elements in the JSON value which is 1 in
21381     the case of a string.
21382 
21383     @requirement This function helps `basic_json` satisfying the
21384     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21385     requirements:
21386     - The complexity is constant.
21387     - Has the semantics of `std::distance(begin(), end())`.
21388 
21389     @sa @ref empty() -- checks whether the container is empty
21390     @sa @ref max_size() -- returns the maximal number of elements
21391 
21392     @since version 1.0.0
21393     */
size() const21394     size_type size() const noexcept
21395     {
21396         switch (m_type)
21397         {
21398             case value_t::null:
21399             {
21400                 // null values are empty
21401                 return 0;
21402             }
21403 
21404             case value_t::array:
21405             {
21406                 // delegate call to array_t::size()
21407                 return m_value.array->size();
21408             }
21409 
21410             case value_t::object:
21411             {
21412                 // delegate call to object_t::size()
21413                 return m_value.object->size();
21414             }
21415 
21416             default:
21417             {
21418                 // all other types have size 1
21419                 return 1;
21420             }
21421         }
21422     }
21423 
21424     /*!
21425     @brief returns the maximum possible number of elements
21426 
21427     Returns the maximum number of elements a JSON value is able to hold due to
21428     system or library implementation limitations, i.e. `std::distance(begin(),
21429     end())` for the JSON value.
21430 
21431     @return The return value depends on the different types and is
21432             defined as follows:
21433             Value type  | return value
21434             ----------- | -------------
21435             null        | `0` (same as `size()`)
21436             boolean     | `1` (same as `size()`)
21437             string      | `1` (same as `size()`)
21438             number      | `1` (same as `size()`)
21439             binary      | `1` (same as `size()`)
21440             object      | result of function `object_t::max_size()`
21441             array       | result of function `array_t::max_size()`
21442 
21443     @liveexample{The following code calls `max_size()` on the different value
21444     types. Note the output is implementation specific.,max_size}
21445 
21446     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21447     the Container concept; that is, their `max_size()` functions have constant
21448     complexity.
21449 
21450     @iterators No changes.
21451 
21452     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21453 
21454     @requirement This function helps `basic_json` satisfying the
21455     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21456     requirements:
21457     - The complexity is constant.
21458     - Has the semantics of returning `b.size()` where `b` is the largest
21459       possible JSON value.
21460 
21461     @sa @ref size() -- returns the number of elements
21462 
21463     @since version 1.0.0
21464     */
max_size() const21465     size_type max_size() const noexcept
21466     {
21467         switch (m_type)
21468         {
21469             case value_t::array:
21470             {
21471                 // delegate call to array_t::max_size()
21472                 return m_value.array->max_size();
21473             }
21474 
21475             case value_t::object:
21476             {
21477                 // delegate call to object_t::max_size()
21478                 return m_value.object->max_size();
21479             }
21480 
21481             default:
21482             {
21483                 // all other types have max_size() == size()
21484                 return size();
21485             }
21486         }
21487     }
21488 
21489     /// @}
21490 
21491 
21492     ///////////////
21493     // modifiers //
21494     ///////////////
21495 
21496     /// @name modifiers
21497     /// @{
21498 
21499     /*!
21500     @brief clears the contents
21501 
21502     Clears the content of a JSON value and resets it to the default value as
21503     if @ref basic_json(value_t) would have been called with the current value
21504     type from @ref type():
21505 
21506     Value type  | initial value
21507     ----------- | -------------
21508     null        | `null`
21509     boolean     | `false`
21510     string      | `""`
21511     number      | `0`
21512     binary      | An empty byte vector
21513     object      | `{}`
21514     array       | `[]`
21515 
21516     @post Has the same effect as calling
21517     @code {.cpp}
21518     *this = basic_json(type());
21519     @endcode
21520 
21521     @liveexample{The example below shows the effect of `clear()` to different
21522     JSON types.,clear}
21523 
21524     @complexity Linear in the size of the JSON value.
21525 
21526     @iterators All iterators, pointers and references related to this container
21527                are invalidated.
21528 
21529     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21530 
21531     @sa @ref basic_json(value_t) -- constructor that creates an object with the
21532         same value than calling `clear()`
21533 
21534     @since version 1.0.0
21535     */
clear()21536     void clear() noexcept
21537     {
21538         switch (m_type)
21539         {
21540             case value_t::number_integer:
21541             {
21542                 m_value.number_integer = 0;
21543                 break;
21544             }
21545 
21546             case value_t::number_unsigned:
21547             {
21548                 m_value.number_unsigned = 0;
21549                 break;
21550             }
21551 
21552             case value_t::number_float:
21553             {
21554                 m_value.number_float = 0.0;
21555                 break;
21556             }
21557 
21558             case value_t::boolean:
21559             {
21560                 m_value.boolean = false;
21561                 break;
21562             }
21563 
21564             case value_t::string:
21565             {
21566                 m_value.string->clear();
21567                 break;
21568             }
21569 
21570             case value_t::binary:
21571             {
21572                 m_value.binary->clear();
21573                 break;
21574             }
21575 
21576             case value_t::array:
21577             {
21578                 m_value.array->clear();
21579                 break;
21580             }
21581 
21582             case value_t::object:
21583             {
21584                 m_value.object->clear();
21585                 break;
21586             }
21587 
21588             default:
21589                 break;
21590         }
21591     }
21592 
21593     /*!
21594     @brief add an object to an array
21595 
21596     Appends the given element @a val to the end of the JSON value. If the
21597     function is called on a JSON null value, an empty array is created before
21598     appending @a val.
21599 
21600     @param[in] val the value to add to the JSON array
21601 
21602     @throw type_error.308 when called on a type other than JSON array or
21603     null; example: `"cannot use push_back() with number"`
21604 
21605     @complexity Amortized constant.
21606 
21607     @liveexample{The example shows how `push_back()` and `+=` can be used to
21608     add elements to a JSON array. Note how the `null` value was silently
21609     converted to a JSON array.,push_back}
21610 
21611     @since version 1.0.0
21612     */
push_back(basic_json && val)21613     void push_back(basic_json&& val)
21614     {
21615         // push_back only works for null objects or arrays
21616         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21617         {
21618             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21619         }
21620 
21621         // transform null object into an array
21622         if (is_null())
21623         {
21624             m_type = value_t::array;
21625             m_value = value_t::array;
21626             assert_invariant();
21627         }
21628 
21629         // add element to array (move semantics)
21630         m_value.array->push_back(std::move(val));
21631         // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21632     }
21633 
21634     /*!
21635     @brief add an object to an array
21636     @copydoc push_back(basic_json&&)
21637     */
operator +=(basic_json && val)21638     reference operator+=(basic_json&& val)
21639     {
21640         push_back(std::move(val));
21641         return *this;
21642     }
21643 
21644     /*!
21645     @brief add an object to an array
21646     @copydoc push_back(basic_json&&)
21647     */
push_back(const basic_json & val)21648     void push_back(const basic_json& val)
21649     {
21650         // push_back only works for null objects or arrays
21651         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21652         {
21653             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21654         }
21655 
21656         // transform null object into an array
21657         if (is_null())
21658         {
21659             m_type = value_t::array;
21660             m_value = value_t::array;
21661             assert_invariant();
21662         }
21663 
21664         // add element to array
21665         m_value.array->push_back(val);
21666     }
21667 
21668     /*!
21669     @brief add an object to an array
21670     @copydoc push_back(basic_json&&)
21671     */
operator +=(const basic_json & val)21672     reference operator+=(const basic_json& val)
21673     {
21674         push_back(val);
21675         return *this;
21676     }
21677 
21678     /*!
21679     @brief add an object to an object
21680 
21681     Inserts the given element @a val to the JSON object. If the function is
21682     called on a JSON null value, an empty object is created before inserting
21683     @a val.
21684 
21685     @param[in] val the value to add to the JSON object
21686 
21687     @throw type_error.308 when called on a type other than JSON object or
21688     null; example: `"cannot use push_back() with number"`
21689 
21690     @complexity Logarithmic in the size of the container, O(log(`size()`)).
21691 
21692     @liveexample{The example shows how `push_back()` and `+=` can be used to
21693     add elements to a JSON object. Note how the `null` value was silently
21694     converted to a JSON object.,push_back__object_t__value}
21695 
21696     @since version 1.0.0
21697     */
push_back(const typename object_t::value_type & val)21698     void push_back(const typename object_t::value_type& val)
21699     {
21700         // push_back only works for null objects or objects
21701         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21702         {
21703             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21704         }
21705 
21706         // transform null object into an object
21707         if (is_null())
21708         {
21709             m_type = value_t::object;
21710             m_value = value_t::object;
21711             assert_invariant();
21712         }
21713 
21714         // add element to array
21715         m_value.object->insert(val);
21716     }
21717 
21718     /*!
21719     @brief add an object to an object
21720     @copydoc push_back(const typename object_t::value_type&)
21721     */
operator +=(const typename object_t::value_type & val)21722     reference operator+=(const typename object_t::value_type& val)
21723     {
21724         push_back(val);
21725         return *this;
21726     }
21727 
21728     /*!
21729     @brief add an object to an object
21730 
21731     This function allows to use `push_back` with an initializer list. In case
21732 
21733     1. the current value is an object,
21734     2. the initializer list @a init contains only two elements, and
21735     3. the first element of @a init is a string,
21736 
21737     @a init is converted into an object element and added using
21738     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
21739     is converted to a JSON value and added using @ref push_back(basic_json&&).
21740 
21741     @param[in] init  an initializer list
21742 
21743     @complexity Linear in the size of the initializer list @a init.
21744 
21745     @note This function is required to resolve an ambiguous overload error,
21746           because pairs like `{"key", "value"}` can be both interpreted as
21747           `object_t::value_type` or `std::initializer_list<basic_json>`, see
21748           https://github.com/nlohmann/json/issues/235 for more information.
21749 
21750     @liveexample{The example shows how initializer lists are treated as
21751     objects when possible.,push_back__initializer_list}
21752     */
push_back(initializer_list_t init)21753     void push_back(initializer_list_t init)
21754     {
21755         if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21756         {
21757             basic_json&& key = init.begin()->moved_or_copied();
21758             push_back(typename object_t::value_type(
21759                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21760         }
21761         else
21762         {
21763             push_back(basic_json(init));
21764         }
21765     }
21766 
21767     /*!
21768     @brief add an object to an object
21769     @copydoc push_back(initializer_list_t)
21770     */
operator +=(initializer_list_t init)21771     reference operator+=(initializer_list_t init)
21772     {
21773         push_back(init);
21774         return *this;
21775     }
21776 
21777     /*!
21778     @brief add an object to an array
21779 
21780     Creates a JSON value from the passed parameters @a args to the end of the
21781     JSON value. If the function is called on a JSON null value, an empty array
21782     is created before appending the value created from @a args.
21783 
21784     @param[in] args arguments to forward to a constructor of @ref basic_json
21785     @tparam Args compatible types to create a @ref basic_json object
21786 
21787     @return reference to the inserted element
21788 
21789     @throw type_error.311 when called on a type other than JSON array or
21790     null; example: `"cannot use emplace_back() with number"`
21791 
21792     @complexity Amortized constant.
21793 
21794     @liveexample{The example shows how `push_back()` can be used to add
21795     elements to a JSON array. Note how the `null` value was silently converted
21796     to a JSON array.,emplace_back}
21797 
21798     @since version 2.0.8, returns reference since 3.7.0
21799     */
21800     template<class... Args>
emplace_back(Args &&...args)21801     reference emplace_back(Args&& ... args)
21802     {
21803         // emplace_back only works for null objects or arrays
21804         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21805         {
21806             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21807         }
21808 
21809         // transform null object into an array
21810         if (is_null())
21811         {
21812             m_type = value_t::array;
21813             m_value = value_t::array;
21814             assert_invariant();
21815         }
21816 
21817         // add element to array (perfect forwarding)
21818 #ifdef JSON_HAS_CPP_17
21819         return m_value.array->emplace_back(std::forward<Args>(args)...);
21820 #else
21821         m_value.array->emplace_back(std::forward<Args>(args)...);
21822         return m_value.array->back();
21823 #endif
21824     }
21825 
21826     /*!
21827     @brief add an object to an object if key does not exist
21828 
21829     Inserts a new element into a JSON object constructed in-place with the
21830     given @a args if there is no element with the key in the container. If the
21831     function is called on a JSON null value, an empty object is created before
21832     appending the value created from @a args.
21833 
21834     @param[in] args arguments to forward to a constructor of @ref basic_json
21835     @tparam Args compatible types to create a @ref basic_json object
21836 
21837     @return a pair consisting of an iterator to the inserted element, or the
21838             already-existing element if no insertion happened, and a bool
21839             denoting whether the insertion took place.
21840 
21841     @throw type_error.311 when called on a type other than JSON object or
21842     null; example: `"cannot use emplace() with number"`
21843 
21844     @complexity Logarithmic in the size of the container, O(log(`size()`)).
21845 
21846     @liveexample{The example shows how `emplace()` can be used to add elements
21847     to a JSON object. Note how the `null` value was silently converted to a
21848     JSON object. Further note how no value is added if there was already one
21849     value stored with the same key.,emplace}
21850 
21851     @since version 2.0.8
21852     */
21853     template<class... Args>
emplace(Args &&...args)21854     std::pair<iterator, bool> emplace(Args&& ... args)
21855     {
21856         // emplace only works for null objects or arrays
21857         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21858         {
21859             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21860         }
21861 
21862         // transform null object into an object
21863         if (is_null())
21864         {
21865             m_type = value_t::object;
21866             m_value = value_t::object;
21867             assert_invariant();
21868         }
21869 
21870         // add element to array (perfect forwarding)
21871         auto res = m_value.object->emplace(std::forward<Args>(args)...);
21872         // create result iterator and set iterator to the result of emplace
21873         auto it = begin();
21874         it.m_it.object_iterator = res.first;
21875 
21876         // return pair of iterator and boolean
21877         return {it, res.second};
21878     }
21879 
21880     /// Helper for insertion of an iterator
21881     /// @note: This uses std::distance to support GCC 4.8,
21882     ///        see https://github.com/nlohmann/json/pull/1257
21883     template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)21884     iterator insert_iterator(const_iterator pos, Args&& ... args)
21885     {
21886         iterator result(this);
21887         JSON_ASSERT(m_value.array != nullptr);
21888 
21889         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21890         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21891         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21892 
21893         // This could have been written as:
21894         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21895         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21896 
21897         return result;
21898     }
21899 
21900     /*!
21901     @brief inserts element
21902 
21903     Inserts element @a val before iterator @a pos.
21904 
21905     @param[in] pos iterator before which the content will be inserted; may be
21906     the end() iterator
21907     @param[in] val element to insert
21908     @return iterator pointing to the inserted @a val.
21909 
21910     @throw type_error.309 if called on JSON values other than arrays;
21911     example: `"cannot use insert() with string"`
21912     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
21913     example: `"iterator does not fit current value"`
21914 
21915     @complexity Constant plus linear in the distance between @a pos and end of
21916     the container.
21917 
21918     @liveexample{The example shows how `insert()` is used.,insert}
21919 
21920     @since version 1.0.0
21921     */
insert(const_iterator pos,const basic_json & val)21922     iterator insert(const_iterator pos, const basic_json& val)
21923     {
21924         // insert only works for arrays
21925         if (JSON_HEDLEY_LIKELY(is_array()))
21926         {
21927             // check if iterator pos fits to this JSON value
21928             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21929             {
21930                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21931             }
21932 
21933             // insert to array and return iterator
21934             return insert_iterator(pos, val);
21935         }
21936 
21937         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21938     }
21939 
21940     /*!
21941     @brief inserts element
21942     @copydoc insert(const_iterator, const basic_json&)
21943     */
insert(const_iterator pos,basic_json && val)21944     iterator insert(const_iterator pos, basic_json&& val)
21945     {
21946         return insert(pos, val);
21947     }
21948 
21949     /*!
21950     @brief inserts elements
21951 
21952     Inserts @a cnt copies of @a val before iterator @a pos.
21953 
21954     @param[in] pos iterator before which the content will be inserted; may be
21955     the end() iterator
21956     @param[in] cnt number of copies of @a val to insert
21957     @param[in] val element to insert
21958     @return iterator pointing to the first element inserted, or @a pos if
21959     `cnt==0`
21960 
21961     @throw type_error.309 if called on JSON values other than arrays; example:
21962     `"cannot use insert() with string"`
21963     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
21964     example: `"iterator does not fit current value"`
21965 
21966     @complexity Linear in @a cnt plus linear in the distance between @a pos
21967     and end of the container.
21968 
21969     @liveexample{The example shows how `insert()` is used.,insert__count}
21970 
21971     @since version 1.0.0
21972     */
insert(const_iterator pos,size_type cnt,const basic_json & val)21973     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
21974     {
21975         // insert only works for arrays
21976         if (JSON_HEDLEY_LIKELY(is_array()))
21977         {
21978             // check if iterator pos fits to this JSON value
21979             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21980             {
21981                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
21982             }
21983 
21984             // insert to array and return iterator
21985             return insert_iterator(pos, cnt, val);
21986         }
21987 
21988         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
21989     }
21990 
21991     /*!
21992     @brief inserts elements
21993 
21994     Inserts elements from range `[first, last)` before iterator @a pos.
21995 
21996     @param[in] pos iterator before which the content will be inserted; may be
21997     the end() iterator
21998     @param[in] first begin of the range of elements to insert
21999     @param[in] last end of the range of elements to insert
22000 
22001     @throw type_error.309 if called on JSON values other than arrays; example:
22002     `"cannot use insert() with string"`
22003     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22004     example: `"iterator does not fit current value"`
22005     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22006     same JSON value; example: `"iterators do not fit"`
22007     @throw invalid_iterator.211 if @a first or @a last are iterators into
22008     container for which insert is called; example: `"passed iterators may not
22009     belong to container"`
22010 
22011     @return iterator pointing to the first element inserted, or @a pos if
22012     `first==last`
22013 
22014     @complexity Linear in `std::distance(first, last)` plus linear in the
22015     distance between @a pos and end of the container.
22016 
22017     @liveexample{The example shows how `insert()` is used.,insert__range}
22018 
22019     @since version 1.0.0
22020     */
insert(const_iterator pos,const_iterator first,const_iterator last)22021     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22022     {
22023         // insert only works for arrays
22024         if (JSON_HEDLEY_UNLIKELY(!is_array()))
22025         {
22026             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22027         }
22028 
22029         // check if iterator pos fits to this JSON value
22030         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22031         {
22032             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22033         }
22034 
22035         // check if range iterators belong to the same JSON object
22036         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22037         {
22038             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22039         }
22040 
22041         if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22042         {
22043             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22044         }
22045 
22046         // insert to array and return iterator
22047         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22048     }
22049 
22050     /*!
22051     @brief inserts elements
22052 
22053     Inserts elements from initializer list @a ilist before iterator @a pos.
22054 
22055     @param[in] pos iterator before which the content will be inserted; may be
22056     the end() iterator
22057     @param[in] ilist initializer list to insert the values from
22058 
22059     @throw type_error.309 if called on JSON values other than arrays; example:
22060     `"cannot use insert() with string"`
22061     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22062     example: `"iterator does not fit current value"`
22063 
22064     @return iterator pointing to the first element inserted, or @a pos if
22065     `ilist` is empty
22066 
22067     @complexity Linear in `ilist.size()` plus linear in the distance between
22068     @a pos and end of the container.
22069 
22070     @liveexample{The example shows how `insert()` is used.,insert__ilist}
22071 
22072     @since version 1.0.0
22073     */
insert(const_iterator pos,initializer_list_t ilist)22074     iterator insert(const_iterator pos, initializer_list_t ilist)
22075     {
22076         // insert only works for arrays
22077         if (JSON_HEDLEY_UNLIKELY(!is_array()))
22078         {
22079             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22080         }
22081 
22082         // check if iterator pos fits to this JSON value
22083         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22084         {
22085             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22086         }
22087 
22088         // insert to array and return iterator
22089         return insert_iterator(pos, ilist.begin(), ilist.end());
22090     }
22091 
22092     /*!
22093     @brief inserts elements
22094 
22095     Inserts elements from range `[first, last)`.
22096 
22097     @param[in] first begin of the range of elements to insert
22098     @param[in] last end of the range of elements to insert
22099 
22100     @throw type_error.309 if called on JSON values other than objects; example:
22101     `"cannot use insert() with string"`
22102     @throw invalid_iterator.202 if iterator @a first or @a last does does not
22103     point to an object; example: `"iterators first and last must point to
22104     objects"`
22105     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22106     same JSON value; example: `"iterators do not fit"`
22107 
22108     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
22109     of elements to insert.
22110 
22111     @liveexample{The example shows how `insert()` is used.,insert__range_object}
22112 
22113     @since version 3.0.0
22114     */
insert(const_iterator first,const_iterator last)22115     void insert(const_iterator first, const_iterator last)
22116     {
22117         // insert only works for objects
22118         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22119         {
22120             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22121         }
22122 
22123         // check if range iterators belong to the same JSON object
22124         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22125         {
22126             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22127         }
22128 
22129         // passed iterators must belong to objects
22130         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22131         {
22132             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22133         }
22134 
22135         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22136     }
22137 
22138     /*!
22139     @brief updates a JSON object from another object, overwriting existing keys
22140 
22141     Inserts all values from JSON object @a j and overwrites existing keys.
22142 
22143     @param[in] j  JSON object to read values from
22144 
22145     @throw type_error.312 if called on JSON values other than objects; example:
22146     `"cannot use update() with string"`
22147 
22148     @complexity O(N*log(size() + N)), where N is the number of elements to
22149                 insert.
22150 
22151     @liveexample{The example shows how `update()` is used.,update}
22152 
22153     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22154 
22155     @since version 3.0.0
22156     */
update(const_reference j)22157     void update(const_reference j)
22158     {
22159         // implicitly convert null value to an empty object
22160         if (is_null())
22161         {
22162             m_type = value_t::object;
22163             m_value.object = create<object_t>();
22164             assert_invariant();
22165         }
22166 
22167         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22168         {
22169             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22170         }
22171         if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22172         {
22173             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22174         }
22175 
22176         for (auto it = j.cbegin(); it != j.cend(); ++it)
22177         {
22178             m_value.object->operator[](it.key()) = it.value();
22179         }
22180     }
22181 
22182     /*!
22183     @brief updates a JSON object from another object, overwriting existing keys
22184 
22185     Inserts all values from from range `[first, last)` and overwrites existing
22186     keys.
22187 
22188     @param[in] first begin of the range of elements to insert
22189     @param[in] last end of the range of elements to insert
22190 
22191     @throw type_error.312 if called on JSON values other than objects; example:
22192     `"cannot use update() with string"`
22193     @throw invalid_iterator.202 if iterator @a first or @a last does does not
22194     point to an object; example: `"iterators first and last must point to
22195     objects"`
22196     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22197     same JSON value; example: `"iterators do not fit"`
22198 
22199     @complexity O(N*log(size() + N)), where N is the number of elements to
22200                 insert.
22201 
22202     @liveexample{The example shows how `update()` is used__range.,update}
22203 
22204     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22205 
22206     @since version 3.0.0
22207     */
update(const_iterator first,const_iterator last)22208     void update(const_iterator first, const_iterator last)
22209     {
22210         // implicitly convert null value to an empty object
22211         if (is_null())
22212         {
22213             m_type = value_t::object;
22214             m_value.object = create<object_t>();
22215             assert_invariant();
22216         }
22217 
22218         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22219         {
22220             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22221         }
22222 
22223         // check if range iterators belong to the same JSON object
22224         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22225         {
22226             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22227         }
22228 
22229         // passed iterators must belong to objects
22230         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22231                                  || !last.m_object->is_object()))
22232         {
22233             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22234         }
22235 
22236         for (auto it = first; it != last; ++it)
22237         {
22238             m_value.object->operator[](it.key()) = it.value();
22239         }
22240     }
22241 
22242     /*!
22243     @brief exchanges the values
22244 
22245     Exchanges the contents of the JSON value with those of @a other. Does not
22246     invoke any move, copy, or swap operations on individual elements. All
22247     iterators and references remain valid. The past-the-end iterator is
22248     invalidated.
22249 
22250     @param[in,out] other JSON value to exchange the contents with
22251 
22252     @complexity Constant.
22253 
22254     @liveexample{The example below shows how JSON values can be swapped with
22255     `swap()`.,swap__reference}
22256 
22257     @since version 1.0.0
22258     */
swap(reference other)22259     void swap(reference other) noexcept (
22260         std::is_nothrow_move_constructible<value_t>::value&&
22261         std::is_nothrow_move_assignable<value_t>::value&&
22262         std::is_nothrow_move_constructible<json_value>::value&&
22263         std::is_nothrow_move_assignable<json_value>::value
22264     )
22265     {
22266         std::swap(m_type, other.m_type);
22267         std::swap(m_value, other.m_value);
22268         assert_invariant();
22269     }
22270 
22271     /*!
22272     @brief exchanges the values
22273 
22274     Exchanges the contents of the JSON value from @a left with those of @a right. Does not
22275     invoke any move, copy, or swap operations on individual elements. All
22276     iterators and references remain valid. The past-the-end iterator is
22277     invalidated. implemented as a friend function callable via ADL.
22278 
22279     @param[in,out] left JSON value to exchange the contents with
22280     @param[in,out] right JSON value to exchange the contents with
22281 
22282     @complexity Constant.
22283 
22284     @liveexample{The example below shows how JSON values can be swapped with
22285     `swap()`.,swap__reference}
22286 
22287     @since version 1.0.0
22288     */
swap(reference left,reference right)22289     friend void swap(reference left, reference right) noexcept (
22290         std::is_nothrow_move_constructible<value_t>::value&&
22291         std::is_nothrow_move_assignable<value_t>::value&&
22292         std::is_nothrow_move_constructible<json_value>::value&&
22293         std::is_nothrow_move_assignable<json_value>::value
22294     )
22295     {
22296         left.swap(right);
22297     }
22298 
22299     /*!
22300     @brief exchanges the values
22301 
22302     Exchanges the contents of a JSON array with those of @a other. Does not
22303     invoke any move, copy, or swap operations on individual elements. All
22304     iterators and references remain valid. The past-the-end iterator is
22305     invalidated.
22306 
22307     @param[in,out] other array to exchange the contents with
22308 
22309     @throw type_error.310 when JSON value is not an array; example: `"cannot
22310     use swap() with string"`
22311 
22312     @complexity Constant.
22313 
22314     @liveexample{The example below shows how arrays can be swapped with
22315     `swap()`.,swap__array_t}
22316 
22317     @since version 1.0.0
22318     */
swap(array_t & other)22319     void swap(array_t& other)
22320     {
22321         // swap only works for arrays
22322         if (JSON_HEDLEY_LIKELY(is_array()))
22323         {
22324             std::swap(*(m_value.array), other);
22325         }
22326         else
22327         {
22328             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22329         }
22330     }
22331 
22332     /*!
22333     @brief exchanges the values
22334 
22335     Exchanges the contents of a JSON object with those of @a other. Does not
22336     invoke any move, copy, or swap operations on individual elements. All
22337     iterators and references remain valid. The past-the-end iterator is
22338     invalidated.
22339 
22340     @param[in,out] other object to exchange the contents with
22341 
22342     @throw type_error.310 when JSON value is not an object; example:
22343     `"cannot use swap() with string"`
22344 
22345     @complexity Constant.
22346 
22347     @liveexample{The example below shows how objects can be swapped with
22348     `swap()`.,swap__object_t}
22349 
22350     @since version 1.0.0
22351     */
swap(object_t & other)22352     void swap(object_t& other)
22353     {
22354         // swap only works for objects
22355         if (JSON_HEDLEY_LIKELY(is_object()))
22356         {
22357             std::swap(*(m_value.object), other);
22358         }
22359         else
22360         {
22361             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22362         }
22363     }
22364 
22365     /*!
22366     @brief exchanges the values
22367 
22368     Exchanges the contents of a JSON string with those of @a other. Does not
22369     invoke any move, copy, or swap operations on individual elements. All
22370     iterators and references remain valid. The past-the-end iterator is
22371     invalidated.
22372 
22373     @param[in,out] other string to exchange the contents with
22374 
22375     @throw type_error.310 when JSON value is not a string; example: `"cannot
22376     use swap() with boolean"`
22377 
22378     @complexity Constant.
22379 
22380     @liveexample{The example below shows how strings can be swapped with
22381     `swap()`.,swap__string_t}
22382 
22383     @since version 1.0.0
22384     */
swap(string_t & other)22385     void swap(string_t& other)
22386     {
22387         // swap only works for strings
22388         if (JSON_HEDLEY_LIKELY(is_string()))
22389         {
22390             std::swap(*(m_value.string), other);
22391         }
22392         else
22393         {
22394             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22395         }
22396     }
22397 
22398     /*!
22399     @brief exchanges the values
22400 
22401     Exchanges the contents of a JSON string with those of @a other. Does not
22402     invoke any move, copy, or swap operations on individual elements. All
22403     iterators and references remain valid. The past-the-end iterator is
22404     invalidated.
22405 
22406     @param[in,out] other binary to exchange the contents with
22407 
22408     @throw type_error.310 when JSON value is not a string; example: `"cannot
22409     use swap() with boolean"`
22410 
22411     @complexity Constant.
22412 
22413     @liveexample{The example below shows how strings can be swapped with
22414     `swap()`.,swap__binary_t}
22415 
22416     @since version 3.8.0
22417     */
swap(binary_t & other)22418     void swap(binary_t& other)
22419     {
22420         // swap only works for strings
22421         if (JSON_HEDLEY_LIKELY(is_binary()))
22422         {
22423             std::swap(*(m_value.binary), other);
22424         }
22425         else
22426         {
22427             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22428         }
22429     }
22430 
22431     /// @copydoc swap(binary_t)
swap(typename binary_t::container_type & other)22432     void swap(typename binary_t::container_type& other)
22433     {
22434         // swap only works for strings
22435         if (JSON_HEDLEY_LIKELY(is_binary()))
22436         {
22437             std::swap(*(m_value.binary), other);
22438         }
22439         else
22440         {
22441             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22442         }
22443     }
22444 
22445     /// @}
22446 
22447   public:
22448     //////////////////////////////////////////
22449     // lexicographical comparison operators //
22450     //////////////////////////////////////////
22451 
22452     /// @name lexicographical comparison operators
22453     /// @{
22454 
22455     /*!
22456     @brief comparison: equal
22457 
22458     Compares two JSON values for equality according to the following rules:
22459     - Two JSON values are equal if (1) they are from the same type and (2)
22460       their stored values are the same according to their respective
22461       `operator==`.
22462     - Integer and floating-point numbers are automatically converted before
22463       comparison. Note that two NaN values are always treated as unequal.
22464     - Two JSON null values are equal.
22465 
22466     @note Floating-point inside JSON values numbers are compared with
22467     `json::number_float_t::operator==` which is `double::operator==` by
22468     default. To compare floating-point while respecting an epsilon, an alternative
22469     [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
22470     could be used, for instance
22471     @code {.cpp}
22472     template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
22473     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
22474     {
22475         return std::abs(a - b) <= epsilon;
22476     }
22477     @endcode
22478     Or you can self-defined operator equal function like this:
22479     @code {.cpp}
22480     bool my_equal(const_reference lhs, const_reference rhs) {
22481     const auto lhs_type lhs.type();
22482     const auto rhs_type rhs.type();
22483     if (lhs_type == rhs_type) {
22484         switch(lhs_type)
22485             // self_defined case
22486             case value_t::number_float:
22487                 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
22488             // other cases remain the same with the original
22489             ...
22490     }
22491     ...
22492     }
22493     @endcode
22494 
22495     @note NaN values never compare equal to themselves or to other NaN values.
22496 
22497     @param[in] lhs  first JSON value to consider
22498     @param[in] rhs  second JSON value to consider
22499     @return whether the values @a lhs and @a rhs are equal
22500 
22501     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22502 
22503     @complexity Linear.
22504 
22505     @liveexample{The example demonstrates comparing several JSON
22506     types.,operator__equal}
22507 
22508     @since version 1.0.0
22509     */
operator ==(const_reference lhs,const_reference rhs)22510     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22511     {
22512         const auto lhs_type = lhs.type();
22513         const auto rhs_type = rhs.type();
22514 
22515         if (lhs_type == rhs_type)
22516         {
22517             switch (lhs_type)
22518             {
22519                 case value_t::array:
22520                     return *lhs.m_value.array == *rhs.m_value.array;
22521 
22522                 case value_t::object:
22523                     return *lhs.m_value.object == *rhs.m_value.object;
22524 
22525                 case value_t::null:
22526                     return true;
22527 
22528                 case value_t::string:
22529                     return *lhs.m_value.string == *rhs.m_value.string;
22530 
22531                 case value_t::boolean:
22532                     return lhs.m_value.boolean == rhs.m_value.boolean;
22533 
22534                 case value_t::number_integer:
22535                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
22536 
22537                 case value_t::number_unsigned:
22538                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22539 
22540                 case value_t::number_float:
22541                     return lhs.m_value.number_float == rhs.m_value.number_float;
22542 
22543                 case value_t::binary:
22544                     return *lhs.m_value.binary == *rhs.m_value.binary;
22545 
22546                 default:
22547                     return false;
22548             }
22549         }
22550         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22551         {
22552             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22553         }
22554         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22555         {
22556             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22557         }
22558         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22559         {
22560             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22561         }
22562         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22563         {
22564             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22565         }
22566         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22567         {
22568             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22569         }
22570         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22571         {
22572             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22573         }
22574 
22575         return false;
22576     }
22577 
22578     /*!
22579     @brief comparison: equal
22580     @copydoc operator==(const_reference, const_reference)
22581     */
22582     template<typename ScalarType, typename std::enable_if<
22583                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)22584     friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22585     {
22586         return lhs == basic_json(rhs);
22587     }
22588 
22589     /*!
22590     @brief comparison: equal
22591     @copydoc operator==(const_reference, const_reference)
22592     */
22593     template<typename ScalarType, typename std::enable_if<
22594                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)22595     friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22596     {
22597         return basic_json(lhs) == rhs;
22598     }
22599 
22600     /*!
22601     @brief comparison: not equal
22602 
22603     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
22604 
22605     @param[in] lhs  first JSON value to consider
22606     @param[in] rhs  second JSON value to consider
22607     @return whether the values @a lhs and @a rhs are not equal
22608 
22609     @complexity Linear.
22610 
22611     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22612 
22613     @liveexample{The example demonstrates comparing several JSON
22614     types.,operator__notequal}
22615 
22616     @since version 1.0.0
22617     */
operator !=(const_reference lhs,const_reference rhs)22618     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22619     {
22620         return !(lhs == rhs);
22621     }
22622 
22623     /*!
22624     @brief comparison: not equal
22625     @copydoc operator!=(const_reference, const_reference)
22626     */
22627     template<typename ScalarType, typename std::enable_if<
22628                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)22629     friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22630     {
22631         return lhs != basic_json(rhs);
22632     }
22633 
22634     /*!
22635     @brief comparison: not equal
22636     @copydoc operator!=(const_reference, const_reference)
22637     */
22638     template<typename ScalarType, typename std::enable_if<
22639                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)22640     friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22641     {
22642         return basic_json(lhs) != rhs;
22643     }
22644 
22645     /*!
22646     @brief comparison: less than
22647 
22648     Compares whether one JSON value @a lhs is less than another JSON value @a
22649     rhs according to the following rules:
22650     - If @a lhs and @a rhs have the same type, the values are compared using
22651       the default `<` operator.
22652     - Integer and floating-point numbers are automatically converted before
22653       comparison
22654     - In case @a lhs and @a rhs have different types, the values are ignored
22655       and the order of the types is considered, see
22656       @ref operator<(const value_t, const value_t).
22657 
22658     @param[in] lhs  first JSON value to consider
22659     @param[in] rhs  second JSON value to consider
22660     @return whether @a lhs is less than @a rhs
22661 
22662     @complexity Linear.
22663 
22664     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22665 
22666     @liveexample{The example demonstrates comparing several JSON
22667     types.,operator__less}
22668 
22669     @since version 1.0.0
22670     */
operator <(const_reference lhs,const_reference rhs)22671     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22672     {
22673         const auto lhs_type = lhs.type();
22674         const auto rhs_type = rhs.type();
22675 
22676         if (lhs_type == rhs_type)
22677         {
22678             switch (lhs_type)
22679             {
22680                 case value_t::array:
22681                     // note parentheses are necessary, see
22682                     // https://github.com/nlohmann/json/issues/1530
22683                     return (*lhs.m_value.array) < (*rhs.m_value.array);
22684 
22685                 case value_t::object:
22686                     return (*lhs.m_value.object) < (*rhs.m_value.object);
22687 
22688                 case value_t::null:
22689                     return false;
22690 
22691                 case value_t::string:
22692                     return (*lhs.m_value.string) < (*rhs.m_value.string);
22693 
22694                 case value_t::boolean:
22695                     return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22696 
22697                 case value_t::number_integer:
22698                     return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22699 
22700                 case value_t::number_unsigned:
22701                     return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22702 
22703                 case value_t::number_float:
22704                     return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22705 
22706                 case value_t::binary:
22707                     return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22708 
22709                 default:
22710                     return false;
22711             }
22712         }
22713         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22714         {
22715             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22716         }
22717         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22718         {
22719             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22720         }
22721         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22722         {
22723             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22724         }
22725         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22726         {
22727             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22728         }
22729         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22730         {
22731             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22732         }
22733         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22734         {
22735             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22736         }
22737 
22738         // We only reach this line if we cannot compare values. In that case,
22739         // we compare types. Note we have to call the operator explicitly,
22740         // because MSVC has problems otherwise.
22741         return operator<(lhs_type, rhs_type);
22742     }
22743 
22744     /*!
22745     @brief comparison: less than
22746     @copydoc operator<(const_reference, const_reference)
22747     */
22748     template<typename ScalarType, typename std::enable_if<
22749                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)22750     friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22751     {
22752         return lhs < basic_json(rhs);
22753     }
22754 
22755     /*!
22756     @brief comparison: less than
22757     @copydoc operator<(const_reference, const_reference)
22758     */
22759     template<typename ScalarType, typename std::enable_if<
22760                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)22761     friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22762     {
22763         return basic_json(lhs) < rhs;
22764     }
22765 
22766     /*!
22767     @brief comparison: less than or equal
22768 
22769     Compares whether one JSON value @a lhs is less than or equal to another
22770     JSON value by calculating `not (rhs < lhs)`.
22771 
22772     @param[in] lhs  first JSON value to consider
22773     @param[in] rhs  second JSON value to consider
22774     @return whether @a lhs is less than or equal to @a rhs
22775 
22776     @complexity Linear.
22777 
22778     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22779 
22780     @liveexample{The example demonstrates comparing several JSON
22781     types.,operator__greater}
22782 
22783     @since version 1.0.0
22784     */
operator <=(const_reference lhs,const_reference rhs)22785     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22786     {
22787         return !(rhs < lhs);
22788     }
22789 
22790     /*!
22791     @brief comparison: less than or equal
22792     @copydoc operator<=(const_reference, const_reference)
22793     */
22794     template<typename ScalarType, typename std::enable_if<
22795                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)22796     friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22797     {
22798         return lhs <= basic_json(rhs);
22799     }
22800 
22801     /*!
22802     @brief comparison: less than or equal
22803     @copydoc operator<=(const_reference, const_reference)
22804     */
22805     template<typename ScalarType, typename std::enable_if<
22806                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)22807     friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22808     {
22809         return basic_json(lhs) <= rhs;
22810     }
22811 
22812     /*!
22813     @brief comparison: greater than
22814 
22815     Compares whether one JSON value @a lhs is greater than another
22816     JSON value by calculating `not (lhs <= rhs)`.
22817 
22818     @param[in] lhs  first JSON value to consider
22819     @param[in] rhs  second JSON value to consider
22820     @return whether @a lhs is greater than to @a rhs
22821 
22822     @complexity Linear.
22823 
22824     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22825 
22826     @liveexample{The example demonstrates comparing several JSON
22827     types.,operator__lessequal}
22828 
22829     @since version 1.0.0
22830     */
operator >(const_reference lhs,const_reference rhs)22831     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22832     {
22833         return !(lhs <= rhs);
22834     }
22835 
22836     /*!
22837     @brief comparison: greater than
22838     @copydoc operator>(const_reference, const_reference)
22839     */
22840     template<typename ScalarType, typename std::enable_if<
22841                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)22842     friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22843     {
22844         return lhs > basic_json(rhs);
22845     }
22846 
22847     /*!
22848     @brief comparison: greater than
22849     @copydoc operator>(const_reference, const_reference)
22850     */
22851     template<typename ScalarType, typename std::enable_if<
22852                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)22853     friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22854     {
22855         return basic_json(lhs) > rhs;
22856     }
22857 
22858     /*!
22859     @brief comparison: greater than or equal
22860 
22861     Compares whether one JSON value @a lhs is greater than or equal to another
22862     JSON value by calculating `not (lhs < rhs)`.
22863 
22864     @param[in] lhs  first JSON value to consider
22865     @param[in] rhs  second JSON value to consider
22866     @return whether @a lhs is greater than or equal to @a rhs
22867 
22868     @complexity Linear.
22869 
22870     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22871 
22872     @liveexample{The example demonstrates comparing several JSON
22873     types.,operator__greaterequal}
22874 
22875     @since version 1.0.0
22876     */
operator >=(const_reference lhs,const_reference rhs)22877     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22878     {
22879         return !(lhs < rhs);
22880     }
22881 
22882     /*!
22883     @brief comparison: greater than or equal
22884     @copydoc operator>=(const_reference, const_reference)
22885     */
22886     template<typename ScalarType, typename std::enable_if<
22887                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)22888     friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22889     {
22890         return lhs >= basic_json(rhs);
22891     }
22892 
22893     /*!
22894     @brief comparison: greater than or equal
22895     @copydoc operator>=(const_reference, const_reference)
22896     */
22897     template<typename ScalarType, typename std::enable_if<
22898                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)22899     friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
22900     {
22901         return basic_json(lhs) >= rhs;
22902     }
22903 
22904     /// @}
22905 
22906     ///////////////////
22907     // serialization //
22908     ///////////////////
22909 
22910     /// @name serialization
22911     /// @{
22912 
22913     /*!
22914     @brief serialize to stream
22915 
22916     Serialize the given JSON value @a j to the output stream @a o. The JSON
22917     value will be serialized using the @ref dump member function.
22918 
22919     - The indentation of the output can be controlled with the member variable
22920       `width` of the output stream @a o. For instance, using the manipulator
22921       `std::setw(4)` on @a o sets the indentation level to `4` and the
22922       serialization result is the same as calling `dump(4)`.
22923 
22924     - The indentation character can be controlled with the member variable
22925       `fill` of the output stream @a o. For instance, the manipulator
22926       `std::setfill('\\t')` sets indentation to use a tab character rather than
22927       the default space character.
22928 
22929     @param[in,out] o  stream to serialize to
22930     @param[in] j  JSON value to serialize
22931 
22932     @return the stream @a o
22933 
22934     @throw type_error.316 if a string stored inside the JSON value is not
22935                           UTF-8 encoded
22936 
22937     @complexity Linear.
22938 
22939     @liveexample{The example below shows the serialization with different
22940     parameters to `width` to adjust the indentation level.,operator_serialize}
22941 
22942     @since version 1.0.0; indentation character added in version 3.0.0
22943     */
operator <<(std::ostream & o,const basic_json & j)22944     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22945     {
22946         // read width member and use it as indentation parameter if nonzero
22947         const bool pretty_print = o.width() > 0;
22948         const auto indentation = pretty_print ? o.width() : 0;
22949 
22950         // reset width to 0 for subsequent calls to this stream
22951         o.width(0);
22952 
22953         // do the actual serialization
22954         serializer s(detail::output_adapter<char>(o), o.fill());
22955         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22956         return o;
22957     }
22958 
22959     /*!
22960     @brief serialize to stream
22961     @deprecated This stream operator is deprecated and will be removed in
22962                 future 4.0.0 of the library. Please use
22963                 @ref operator<<(std::ostream&, const basic_json&)
22964                 instead; that is, replace calls like `j >> o;` with `o << j;`.
22965     @since version 1.0.0; deprecated since version 3.0.0
22966     */
22967     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
operator >>(const basic_json & j,std::ostream & o)22968     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22969     {
22970         return o << j;
22971     }
22972 
22973     /// @}
22974 
22975 
22976     /////////////////////
22977     // deserialization //
22978     /////////////////////
22979 
22980     /// @name deserialization
22981     /// @{
22982 
22983     /*!
22984     @brief deserialize from a compatible input
22985 
22986     @tparam InputType A compatible input, for instance
22987     - an std::istream object
22988     - a FILE pointer
22989     - a C-style array of characters
22990     - a pointer to a null-terminated string of single byte characters
22991     - an object obj for which begin(obj) and end(obj) produces a valid pair of
22992       iterators.
22993 
22994     @param[in] i  input to read from
22995     @param[in] cb  a parser callback function of type @ref parser_callback_t
22996     which is used to control the deserialization by filtering unwanted values
22997     (optional)
22998     @param[in] allow_exceptions  whether to throw exceptions in case of a
22999     parse error (optional, true by default)
23000     @param[in] ignore_comments  whether comments should be ignored and treated
23001     like whitespace (true) or yield a parse error (true); (optional, false by
23002     default)
23003 
23004     @return deserialized JSON value; in case of a parse error and
23005             @a allow_exceptions set to `false`, the return value will be
23006             value_t::discarded.
23007 
23008     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23009     of input; expected string literal""`
23010     @throw parse_error.102 if to_unicode fails or surrogate error
23011     @throw parse_error.103 if to_unicode fails
23012 
23013     @complexity Linear in the length of the input. The parser is a predictive
23014     LL(1) parser. The complexity can be higher if the parser callback function
23015     @a cb or reading from the input @a i has a super-linear complexity.
23016 
23017     @note A UTF-8 byte order mark is silently ignored.
23018 
23019     @liveexample{The example below demonstrates the `parse()` function reading
23020     from an array.,parse__array__parser_callback_t}
23021 
23022     @liveexample{The example below demonstrates the `parse()` function with
23023     and without callback function.,parse__string__parser_callback_t}
23024 
23025     @liveexample{The example below demonstrates the `parse()` function with
23026     and without callback function.,parse__istream__parser_callback_t}
23027 
23028     @liveexample{The example below demonstrates the `parse()` function reading
23029     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
23030 
23031     @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
23032     ignore comments.
23033     */
23034     template<typename InputType>
23035     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(InputType && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)23036     static basic_json parse(InputType&& i,
23037                             const parser_callback_t cb = nullptr,
23038                             const bool allow_exceptions = true,
23039                             const bool ignore_comments = false)
23040     {
23041         basic_json result;
23042         parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23043         return result;
23044     }
23045 
23046     /*!
23047     @brief deserialize from a pair of character iterators
23048 
23049     The value_type of the iterator must be a integral type with size of 1, 2 or
23050     4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
23051 
23052     @param[in] first iterator to start of character range
23053     @param[in] last  iterator to end of character range
23054     @param[in] cb  a parser callback function of type @ref parser_callback_t
23055     which is used to control the deserialization by filtering unwanted values
23056     (optional)
23057     @param[in] allow_exceptions  whether to throw exceptions in case of a
23058     parse error (optional, true by default)
23059     @param[in] ignore_comments  whether comments should be ignored and treated
23060     like whitespace (true) or yield a parse error (true); (optional, false by
23061     default)
23062 
23063     @return deserialized JSON value; in case of a parse error and
23064             @a allow_exceptions set to `false`, the return value will be
23065             value_t::discarded.
23066 
23067     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23068     of input; expected string literal""`
23069     @throw parse_error.102 if to_unicode fails or surrogate error
23070     @throw parse_error.103 if to_unicode fails
23071     */
23072     template<typename IteratorType>
23073     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)23074     static basic_json parse(IteratorType first,
23075                             IteratorType last,
23076                             const parser_callback_t cb = nullptr,
23077                             const bool allow_exceptions = true,
23078                             const bool ignore_comments = false)
23079     {
23080         basic_json result;
23081         parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23082         return result;
23083     }
23084 
23085     JSON_HEDLEY_WARN_UNUSED_RESULT
23086     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
parse(detail::span_input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)23087     static basic_json parse(detail::span_input_adapter&& i,
23088                             const parser_callback_t cb = nullptr,
23089                             const bool allow_exceptions = true,
23090                             const bool ignore_comments = false)
23091     {
23092         basic_json result;
23093         parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23094         return result;
23095     }
23096 
23097     /*!
23098     @brief check if the input is valid JSON
23099 
23100     Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
23101     function, this function neither throws an exception in case of invalid JSON
23102     input (i.e., a parse error) nor creates diagnostic information.
23103 
23104     @tparam InputType A compatible input, for instance
23105     - an std::istream object
23106     - a FILE pointer
23107     - a C-style array of characters
23108     - a pointer to a null-terminated string of single byte characters
23109     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23110       iterators.
23111 
23112     @param[in] i input to read from
23113     @param[in] ignore_comments  whether comments should be ignored and treated
23114     like whitespace (true) or yield a parse error (true); (optional, false by
23115     default)
23116 
23117     @return Whether the input read from @a i is valid JSON.
23118 
23119     @complexity Linear in the length of the input. The parser is a predictive
23120     LL(1) parser.
23121 
23122     @note A UTF-8 byte order mark is silently ignored.
23123 
23124     @liveexample{The example below demonstrates the `accept()` function reading
23125     from a string.,accept__string}
23126     */
23127     template<typename InputType>
accept(InputType && i,const bool ignore_comments=false)23128     static bool accept(InputType&& i,
23129                        const bool ignore_comments = false)
23130     {
23131         return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23132     }
23133 
23134     template<typename IteratorType>
accept(IteratorType first,IteratorType last,const bool ignore_comments=false)23135     static bool accept(IteratorType first, IteratorType last,
23136                        const bool ignore_comments = false)
23137     {
23138         return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23139     }
23140 
23141     JSON_HEDLEY_WARN_UNUSED_RESULT
23142     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
accept(detail::span_input_adapter && i,const bool ignore_comments=false)23143     static bool accept(detail::span_input_adapter&& i,
23144                        const bool ignore_comments = false)
23145     {
23146         return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23147     }
23148 
23149     /*!
23150     @brief generate SAX events
23151 
23152     The SAX event lister must follow the interface of @ref json_sax.
23153 
23154     This function reads from a compatible input. Examples are:
23155     - an std::istream object
23156     - a FILE pointer
23157     - a C-style array of characters
23158     - a pointer to a null-terminated string of single byte characters
23159     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23160       iterators.
23161 
23162     @param[in] i  input to read from
23163     @param[in,out] sax  SAX event listener
23164     @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
23165     @param[in] strict  whether the input has to be consumed completely
23166     @param[in] ignore_comments  whether comments should be ignored and treated
23167     like whitespace (true) or yield a parse error (true); (optional, false by
23168     default); only applies to the JSON file format.
23169 
23170     @return return value of the last processed SAX event
23171 
23172     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23173     of input; expected string literal""`
23174     @throw parse_error.102 if to_unicode fails or surrogate error
23175     @throw parse_error.103 if to_unicode fails
23176 
23177     @complexity Linear in the length of the input. The parser is a predictive
23178     LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
23179     a super-linear complexity.
23180 
23181     @note A UTF-8 byte order mark is silently ignored.
23182 
23183     @liveexample{The example below demonstrates the `sax_parse()` function
23184     reading from string and processing the events with a user-defined SAX
23185     event consumer.,sax_parse}
23186 
23187     @since version 3.2.0
23188     */
23189     template <typename InputType, typename SAX>
23190     JSON_HEDLEY_NON_NULL(2)
sax_parse(InputType && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)23191     static bool sax_parse(InputType&& i, SAX* sax,
23192                           input_format_t format = input_format_t::json,
23193                           const bool strict = true,
23194                           const bool ignore_comments = false)
23195     {
23196         auto ia = detail::input_adapter(std::forward<InputType>(i));
23197         return format == input_format_t::json
23198                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23199                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23200     }
23201 
23202     template<class IteratorType, class SAX>
23203     JSON_HEDLEY_NON_NULL(3)
sax_parse(IteratorType first,IteratorType last,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)23204     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23205                           input_format_t format = input_format_t::json,
23206                           const bool strict = true,
23207                           const bool ignore_comments = false)
23208     {
23209         auto ia = detail::input_adapter(std::move(first), std::move(last));
23210         return format == input_format_t::json
23211                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23212                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23213     }
23214 
23215     template <typename SAX>
23216     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23217     JSON_HEDLEY_NON_NULL(2)
sax_parse(detail::span_input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)23218     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23219                           input_format_t format = input_format_t::json,
23220                           const bool strict = true,
23221                           const bool ignore_comments = false)
23222     {
23223         auto ia = i.get();
23224         return format == input_format_t::json
23225                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23226                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23227     }
23228 
23229     /*!
23230     @brief deserialize from stream
23231     @deprecated This stream operator is deprecated and will be removed in
23232                 version 4.0.0 of the library. Please use
23233                 @ref operator>>(std::istream&, basic_json&)
23234                 instead; that is, replace calls like `j << i;` with `i >> j;`.
23235     @since version 1.0.0; deprecated since version 3.0.0
23236     */
23237     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
operator <<(basic_json & j,std::istream & i)23238     friend std::istream& operator<<(basic_json& j, std::istream& i)
23239     {
23240         return operator>>(i, j);
23241     }
23242 
23243     /*!
23244     @brief deserialize from stream
23245 
23246     Deserializes an input stream to a JSON value.
23247 
23248     @param[in,out] i  input stream to read a serialized JSON value from
23249     @param[in,out] j  JSON value to write the deserialized input to
23250 
23251     @throw parse_error.101 in case of an unexpected token
23252     @throw parse_error.102 if to_unicode fails or surrogate error
23253     @throw parse_error.103 if to_unicode fails
23254 
23255     @complexity Linear in the length of the input. The parser is a predictive
23256     LL(1) parser.
23257 
23258     @note A UTF-8 byte order mark is silently ignored.
23259 
23260     @liveexample{The example below shows how a JSON value is constructed by
23261     reading a serialization from a stream.,operator_deserialize}
23262 
23263     @sa parse(std::istream&, const parser_callback_t) for a variant with a
23264     parser callback function to filter values while parsing
23265 
23266     @since version 1.0.0
23267     */
operator >>(std::istream & i,basic_json & j)23268     friend std::istream& operator>>(std::istream& i, basic_json& j)
23269     {
23270         parser(detail::input_adapter(i)).parse(false, j);
23271         return i;
23272     }
23273 
23274     /// @}
23275 
23276     ///////////////////////////
23277     // convenience functions //
23278     ///////////////////////////
23279 
23280     /*!
23281     @brief return the type as string
23282 
23283     Returns the type name as string to be used in error messages - usually to
23284     indicate that a function was called on a wrong JSON type.
23285 
23286     @return a string representation of a the @a m_type member:
23287             Value type  | return value
23288             ----------- | -------------
23289             null        | `"null"`
23290             boolean     | `"boolean"`
23291             string      | `"string"`
23292             number      | `"number"` (for all number types)
23293             object      | `"object"`
23294             array       | `"array"`
23295             binary      | `"binary"`
23296             discarded   | `"discarded"`
23297 
23298     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23299 
23300     @complexity Constant.
23301 
23302     @liveexample{The following code exemplifies `type_name()` for all JSON
23303     types.,type_name}
23304 
23305     @sa @ref type() -- return the type of the JSON value
23306     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
23307 
23308     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
23309     since 3.0.0
23310     */
23311     JSON_HEDLEY_RETURNS_NON_NULL
type_name() const23312     const char* type_name() const noexcept
23313     {
23314         {
23315             switch (m_type)
23316             {
23317                 case value_t::null:
23318                     return "null";
23319                 case value_t::object:
23320                     return "object";
23321                 case value_t::array:
23322                     return "array";
23323                 case value_t::string:
23324                     return "string";
23325                 case value_t::boolean:
23326                     return "boolean";
23327                 case value_t::binary:
23328                     return "binary";
23329                 case value_t::discarded:
23330                     return "discarded";
23331                 default:
23332                     return "number";
23333             }
23334         }
23335     }
23336 
23337 
23338   private:
23339     //////////////////////
23340     // member variables //
23341     //////////////////////
23342 
23343     /// the type of the current element
23344     value_t m_type = value_t::null;
23345 
23346     /// the value of the current element
23347     json_value m_value = {};
23348 
23349     //////////////////////////////////////////
23350     // binary serialization/deserialization //
23351     //////////////////////////////////////////
23352 
23353     /// @name binary serialization/deserialization support
23354     /// @{
23355 
23356   public:
23357     /*!
23358     @brief create a CBOR serialization of a given JSON value
23359 
23360     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
23361     Binary Object Representation) serialization format. CBOR is a binary
23362     serialization format which aims to be more compact than JSON itself, yet
23363     more efficient to parse.
23364 
23365     The library uses the following mapping from JSON values types to
23366     CBOR types according to the CBOR specification (RFC 7049):
23367 
23368     JSON value type | value/range                                | CBOR type                          | first byte
23369     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
23370     null            | `null`                                     | Null                               | 0xF6
23371     boolean         | `true`                                     | True                               | 0xF5
23372     boolean         | `false`                                    | False                              | 0xF4
23373     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
23374     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
23375     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
23376     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
23377     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
23378     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
23379     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23380     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23381     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23382     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23383     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
23384     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23385     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23386     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23387     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23388     number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
23389     number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
23390     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
23391     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
23392     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
23393     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
23394     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
23395     array           | *size*: 0..23                              | array                              | 0x80..0x97
23396     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
23397     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
23398     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
23399     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
23400     object          | *size*: 0..23                              | map                                | 0xA0..0xB7
23401     object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
23402     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
23403     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
23404     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
23405     binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
23406     binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
23407     binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
23408     binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
23409     binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
23410 
23411     @note The mapping is **complete** in the sense that any JSON value type
23412           can be converted to a CBOR value.
23413 
23414     @note If NaN or Infinity are stored inside a JSON number, they are
23415           serialized properly. This behavior differs from the @ref dump()
23416           function which serializes NaN or Infinity to `null`.
23417 
23418     @note The following CBOR types are not used in the conversion:
23419           - UTF-8 strings terminated by "break" (0x7F)
23420           - arrays terminated by "break" (0x9F)
23421           - maps terminated by "break" (0xBF)
23422           - byte strings terminated by "break" (0x5F)
23423           - date/time (0xC0..0xC1)
23424           - bignum (0xC2..0xC3)
23425           - decimal fraction (0xC4)
23426           - bigfloat (0xC5)
23427           - expected conversions (0xD5..0xD7)
23428           - simple values (0xE0..0xF3, 0xF8)
23429           - undefined (0xF7)
23430           - half-precision floats (0xF9)
23431           - break (0xFF)
23432 
23433     @param[in] j  JSON value to serialize
23434     @return CBOR serialization as byte vector
23435 
23436     @complexity Linear in the size of the JSON value @a j.
23437 
23438     @liveexample{The example shows the serialization of a JSON value to a byte
23439     vector in CBOR format.,to_cbor}
23440 
23441     @sa http://cbor.io
23442     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
23443         analogous deserialization
23444     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23445     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23446              related UBJSON format
23447 
23448     @since version 2.0.9; compact representation of floating-point numbers
23449            since version 3.8.0
23450     */
to_cbor(const basic_json & j)23451     static std::vector<uint8_t> to_cbor(const basic_json& j)
23452     {
23453         std::vector<uint8_t> result;
23454         to_cbor(j, result);
23455         return result;
23456     }
23457 
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)23458     static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23459     {
23460         binary_writer<uint8_t>(o).write_cbor(j);
23461     }
23462 
to_cbor(const basic_json & j,detail::output_adapter<char> o)23463     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23464     {
23465         binary_writer<char>(o).write_cbor(j);
23466     }
23467 
23468     /*!
23469     @brief create a MessagePack serialization of a given JSON value
23470 
23471     Serializes a given JSON value @a j to a byte vector using the MessagePack
23472     serialization format. MessagePack is a binary serialization format which
23473     aims to be more compact than JSON itself, yet more efficient to parse.
23474 
23475     The library uses the following mapping from JSON values types to
23476     MessagePack types according to the MessagePack specification:
23477 
23478     JSON value type | value/range                       | MessagePack type | first byte
23479     --------------- | --------------------------------- | ---------------- | ----------
23480     null            | `null`                            | nil              | 0xC0
23481     boolean         | `true`                            | true             | 0xC3
23482     boolean         | `false`                           | false            | 0xC2
23483     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
23484     number_integer  | -2147483648..-32769               | int32            | 0xD2
23485     number_integer  | -32768..-129                      | int16            | 0xD1
23486     number_integer  | -128..-33                         | int8             | 0xD0
23487     number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
23488     number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
23489     number_integer  | 128..255                          | uint 8           | 0xCC
23490     number_integer  | 256..65535                        | uint 16          | 0xCD
23491     number_integer  | 65536..4294967295                 | uint 32          | 0xCE
23492     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
23493     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
23494     number_unsigned | 128..255                          | uint 8           | 0xCC
23495     number_unsigned | 256..65535                        | uint 16          | 0xCD
23496     number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
23497     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
23498     number_float    | *any value representable by a float*     | float 32 | 0xCA
23499     number_float    | *any value NOT representable by a float* | float 64 | 0xCB
23500     string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
23501     string          | *length*: 32..255                 | str 8            | 0xD9
23502     string          | *length*: 256..65535              | str 16           | 0xDA
23503     string          | *length*: 65536..4294967295       | str 32           | 0xDB
23504     array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
23505     array           | *size*: 16..65535                 | array 16         | 0xDC
23506     array           | *size*: 65536..4294967295         | array 32         | 0xDD
23507     object          | *size*: 0..15                     | fix map          | 0x80..0x8F
23508     object          | *size*: 16..65535                 | map 16           | 0xDE
23509     object          | *size*: 65536..4294967295         | map 32           | 0xDF
23510     binary          | *size*: 0..255                    | bin 8            | 0xC4
23511     binary          | *size*: 256..65535                | bin 16           | 0xC5
23512     binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
23513 
23514     @note The mapping is **complete** in the sense that any JSON value type
23515           can be converted to a MessagePack value.
23516 
23517     @note The following values can **not** be converted to a MessagePack value:
23518           - strings with more than 4294967295 bytes
23519           - byte strings with more than 4294967295 bytes
23520           - arrays with more than 4294967295 elements
23521           - objects with more than 4294967295 elements
23522 
23523     @note Any MessagePack output created @ref to_msgpack can be successfully
23524           parsed by @ref from_msgpack.
23525 
23526     @note If NaN or Infinity are stored inside a JSON number, they are
23527           serialized properly. This behavior differs from the @ref dump()
23528           function which serializes NaN or Infinity to `null`.
23529 
23530     @param[in] j  JSON value to serialize
23531     @return MessagePack serialization as byte vector
23532 
23533     @complexity Linear in the size of the JSON value @a j.
23534 
23535     @liveexample{The example shows the serialization of a JSON value to a byte
23536     vector in MessagePack format.,to_msgpack}
23537 
23538     @sa http://msgpack.org
23539     @sa @ref from_msgpack for the analogous deserialization
23540     @sa @ref to_cbor(const basic_json& for the related CBOR format
23541     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23542              related UBJSON format
23543 
23544     @since version 2.0.9
23545     */
to_msgpack(const basic_json & j)23546     static std::vector<uint8_t> to_msgpack(const basic_json& j)
23547     {
23548         std::vector<uint8_t> result;
23549         to_msgpack(j, result);
23550         return result;
23551     }
23552 
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)23553     static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23554     {
23555         binary_writer<uint8_t>(o).write_msgpack(j);
23556     }
23557 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)23558     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23559     {
23560         binary_writer<char>(o).write_msgpack(j);
23561     }
23562 
23563     /*!
23564     @brief create a UBJSON serialization of a given JSON value
23565 
23566     Serializes a given JSON value @a j to a byte vector using the UBJSON
23567     (Universal Binary JSON) serialization format. UBJSON aims to be more compact
23568     than JSON itself, yet more efficient to parse.
23569 
23570     The library uses the following mapping from JSON values types to
23571     UBJSON types according to the UBJSON specification:
23572 
23573     JSON value type | value/range                       | UBJSON type | marker
23574     --------------- | --------------------------------- | ----------- | ------
23575     null            | `null`                            | null        | `Z`
23576     boolean         | `true`                            | true        | `T`
23577     boolean         | `false`                           | false       | `F`
23578     number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
23579     number_integer  | -2147483648..-32769               | int32       | `l`
23580     number_integer  | -32768..-129                      | int16       | `I`
23581     number_integer  | -128..127                         | int8        | `i`
23582     number_integer  | 128..255                          | uint8       | `U`
23583     number_integer  | 256..32767                        | int16       | `I`
23584     number_integer  | 32768..2147483647                 | int32       | `l`
23585     number_integer  | 2147483648..9223372036854775807   | int64       | `L`
23586     number_unsigned | 0..127                            | int8        | `i`
23587     number_unsigned | 128..255                          | uint8       | `U`
23588     number_unsigned | 256..32767                        | int16       | `I`
23589     number_unsigned | 32768..2147483647                 | int32       | `l`
23590     number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
23591     number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
23592     number_float    | *any value*                       | float64     | `D`
23593     string          | *with shortest length indicator*  | string      | `S`
23594     array           | *see notes on optimized format*   | array       | `[`
23595     object          | *see notes on optimized format*   | map         | `{`
23596 
23597     @note The mapping is **complete** in the sense that any JSON value type
23598           can be converted to a UBJSON value.
23599 
23600     @note The following values can **not** be converted to a UBJSON value:
23601           - strings with more than 9223372036854775807 bytes (theoretical)
23602 
23603     @note The following markers are not used in the conversion:
23604           - `Z`: no-op values are not created.
23605           - `C`: single-byte strings are serialized with `S` markers.
23606 
23607     @note Any UBJSON output created @ref to_ubjson can be successfully parsed
23608           by @ref from_ubjson.
23609 
23610     @note If NaN or Infinity are stored inside a JSON number, they are
23611           serialized properly. This behavior differs from the @ref dump()
23612           function which serializes NaN or Infinity to `null`.
23613 
23614     @note The optimized formats for containers are supported: Parameter
23615           @a use_size adds size information to the beginning of a container and
23616           removes the closing marker. Parameter @a use_type further checks
23617           whether all elements of a container have the same type and adds the
23618           type marker to the beginning of the container. The @a use_type
23619           parameter must only be used together with @a use_size = true. Note
23620           that @a use_size = true alone may result in larger representations -
23621           the benefit of this parameter is that the receiving side is
23622           immediately informed on the number of elements of the container.
23623 
23624     @note If the JSON data contains the binary type, the value stored is a list
23625           of integers, as suggested by the UBJSON documentation.  In particular,
23626           this means that serialization and the deserialization of a JSON
23627           containing binary values into UBJSON and back will result in a
23628           different JSON object.
23629 
23630     @param[in] j  JSON value to serialize
23631     @param[in] use_size  whether to add size annotations to container types
23632     @param[in] use_type  whether to add type annotations to container types
23633                          (must be combined with @a use_size = true)
23634     @return UBJSON serialization as byte vector
23635 
23636     @complexity Linear in the size of the JSON value @a j.
23637 
23638     @liveexample{The example shows the serialization of a JSON value to a byte
23639     vector in UBJSON format.,to_ubjson}
23640 
23641     @sa http://ubjson.org
23642     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
23643         analogous deserialization
23644     @sa @ref to_cbor(const basic_json& for the related CBOR format
23645     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23646 
23647     @since version 3.1.0
23648     */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)23649     static std::vector<uint8_t> to_ubjson(const basic_json& j,
23650                                           const bool use_size = false,
23651                                           const bool use_type = false)
23652     {
23653         std::vector<uint8_t> result;
23654         to_ubjson(j, result, use_size, use_type);
23655         return result;
23656     }
23657 
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)23658     static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23659                           const bool use_size = false, const bool use_type = false)
23660     {
23661         binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23662     }
23663 
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)23664     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23665                           const bool use_size = false, const bool use_type = false)
23666     {
23667         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23668     }
23669 
23670 
23671     /*!
23672     @brief Serializes the given JSON object `j` to BSON and returns a vector
23673            containing the corresponding BSON-representation.
23674 
23675     BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
23676     stored as a single entity (a so-called document).
23677 
23678     The library uses the following mapping from JSON values types to BSON types:
23679 
23680     JSON value type | value/range                       | BSON type   | marker
23681     --------------- | --------------------------------- | ----------- | ------
23682     null            | `null`                            | null        | 0x0A
23683     boolean         | `true`, `false`                   | boolean     | 0x08
23684     number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
23685     number_integer  | -2147483648..2147483647           | int32       | 0x10
23686     number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
23687     number_unsigned | 0..2147483647                     | int32       | 0x10
23688     number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
23689     number_unsigned | 9223372036854775808..18446744073709551615| --   | --
23690     number_float    | *any value*                       | double      | 0x01
23691     string          | *any value*                       | string      | 0x02
23692     array           | *any value*                       | document    | 0x04
23693     object          | *any value*                       | document    | 0x03
23694     binary          | *any value*                       | binary      | 0x05
23695 
23696     @warning The mapping is **incomplete**, since only JSON-objects (and things
23697     contained therein) can be serialized to BSON.
23698     Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
23699     and the keys may not contain U+0000, since they are serialized a
23700     zero-terminated c-strings.
23701 
23702     @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
23703     @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
23704     @throw type_error.317    if `!j.is_object()`
23705 
23706     @pre The input `j` is required to be an object: `j.is_object() == true`.
23707 
23708     @note Any BSON output created via @ref to_bson can be successfully parsed
23709           by @ref from_bson.
23710 
23711     @param[in] j  JSON value to serialize
23712     @return BSON serialization as byte vector
23713 
23714     @complexity Linear in the size of the JSON value @a j.
23715 
23716     @liveexample{The example shows the serialization of a JSON value to a byte
23717     vector in BSON format.,to_bson}
23718 
23719     @sa http://bsonspec.org/spec.html
23720     @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
23721         analogous deserialization
23722     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23723              related UBJSON format
23724     @sa @ref to_cbor(const basic_json&) for the related CBOR format
23725     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23726     */
to_bson(const basic_json & j)23727     static std::vector<uint8_t> to_bson(const basic_json& j)
23728     {
23729         std::vector<uint8_t> result;
23730         to_bson(j, result);
23731         return result;
23732     }
23733 
23734     /*!
23735     @brief Serializes the given JSON object `j` to BSON and forwards the
23736            corresponding BSON-representation to the given output_adapter `o`.
23737     @param j The JSON object to convert to BSON.
23738     @param o The output adapter that receives the binary BSON representation.
23739     @pre The input `j` shall be an object: `j.is_object() == true`
23740     @sa @ref to_bson(const basic_json&)
23741     */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)23742     static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23743     {
23744         binary_writer<uint8_t>(o).write_bson(j);
23745     }
23746 
23747     /*!
23748     @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
23749     */
to_bson(const basic_json & j,detail::output_adapter<char> o)23750     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23751     {
23752         binary_writer<char>(o).write_bson(j);
23753     }
23754 
23755 
23756     /*!
23757     @brief create a JSON value from an input in CBOR format
23758 
23759     Deserializes a given input @a i to a JSON value using the CBOR (Concise
23760     Binary Object Representation) serialization format.
23761 
23762     The library maps CBOR types to JSON value types as follows:
23763 
23764     CBOR type              | JSON value type | first byte
23765     ---------------------- | --------------- | ----------
23766     Integer                | number_unsigned | 0x00..0x17
23767     Unsigned integer       | number_unsigned | 0x18
23768     Unsigned integer       | number_unsigned | 0x19
23769     Unsigned integer       | number_unsigned | 0x1A
23770     Unsigned integer       | number_unsigned | 0x1B
23771     Negative integer       | number_integer  | 0x20..0x37
23772     Negative integer       | number_integer  | 0x38
23773     Negative integer       | number_integer  | 0x39
23774     Negative integer       | number_integer  | 0x3A
23775     Negative integer       | number_integer  | 0x3B
23776     Byte string            | binary          | 0x40..0x57
23777     Byte string            | binary          | 0x58
23778     Byte string            | binary          | 0x59
23779     Byte string            | binary          | 0x5A
23780     Byte string            | binary          | 0x5B
23781     UTF-8 string           | string          | 0x60..0x77
23782     UTF-8 string           | string          | 0x78
23783     UTF-8 string           | string          | 0x79
23784     UTF-8 string           | string          | 0x7A
23785     UTF-8 string           | string          | 0x7B
23786     UTF-8 string           | string          | 0x7F
23787     array                  | array           | 0x80..0x97
23788     array                  | array           | 0x98
23789     array                  | array           | 0x99
23790     array                  | array           | 0x9A
23791     array                  | array           | 0x9B
23792     array                  | array           | 0x9F
23793     map                    | object          | 0xA0..0xB7
23794     map                    | object          | 0xB8
23795     map                    | object          | 0xB9
23796     map                    | object          | 0xBA
23797     map                    | object          | 0xBB
23798     map                    | object          | 0xBF
23799     False                  | `false`         | 0xF4
23800     True                   | `true`          | 0xF5
23801     Null                   | `null`          | 0xF6
23802     Half-Precision Float   | number_float    | 0xF9
23803     Single-Precision Float | number_float    | 0xFA
23804     Double-Precision Float | number_float    | 0xFB
23805 
23806     @warning The mapping is **incomplete** in the sense that not all CBOR
23807              types can be converted to a JSON value. The following CBOR types
23808              are not supported and will yield parse errors (parse_error.112):
23809              - date/time (0xC0..0xC1)
23810              - bignum (0xC2..0xC3)
23811              - decimal fraction (0xC4)
23812              - bigfloat (0xC5)
23813              - expected conversions (0xD5..0xD7)
23814              - simple values (0xE0..0xF3, 0xF8)
23815              - undefined (0xF7)
23816 
23817     @warning CBOR allows map keys of any type, whereas JSON only allows
23818              strings as keys in object values. Therefore, CBOR maps with keys
23819              other than UTF-8 strings are rejected (parse_error.113).
23820 
23821     @note Any CBOR output created @ref to_cbor can be successfully parsed by
23822           @ref from_cbor.
23823 
23824     @param[in] i  an input in CBOR format convertible to an input adapter
23825     @param[in] strict  whether to expect the input to be consumed until EOF
23826                        (true by default)
23827     @param[in] allow_exceptions  whether to throw exceptions in case of a
23828     parse error (optional, true by default)
23829     @param[in] tag_handler how to treat CBOR tags (optional, error by default)
23830 
23831     @return deserialized JSON value; in case of a parse error and
23832             @a allow_exceptions set to `false`, the return value will be
23833             value_t::discarded.
23834 
23835     @throw parse_error.110 if the given input ends prematurely or the end of
23836     file was not reached when @a strict was set to true
23837     @throw parse_error.112 if unsupported features from CBOR were
23838     used in the given input @a v or if the input is not valid CBOR
23839     @throw parse_error.113 if a string was expected as map key, but not found
23840 
23841     @complexity Linear in the size of the input @a i.
23842 
23843     @liveexample{The example shows the deserialization of a byte vector in CBOR
23844     format to a JSON value.,from_cbor}
23845 
23846     @sa http://cbor.io
23847     @sa @ref to_cbor(const basic_json&) for the analogous serialization
23848     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
23849         related MessagePack format
23850     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
23851         related UBJSON format
23852 
23853     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
23854            consume input adapters, removed start_index parameter, and added
23855            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
23856            since 3.2.0; added @a tag_handler parameter since 3.9.0.
23857     */
23858     template<typename InputType>
23859     JSON_HEDLEY_WARN_UNUSED_RESULT
from_cbor(InputType && i,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)23860     static basic_json from_cbor(InputType&& i,
23861                                 const bool strict = true,
23862                                 const bool allow_exceptions = true,
23863                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23864     {
23865         basic_json result;
23866         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23867         auto ia = detail::input_adapter(std::forward<InputType>(i));
23868         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23869         return res ? result : basic_json(value_t::discarded);
23870     }
23871 
23872     /*!
23873     @copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t)
23874     */
23875     template<typename IteratorType>
23876     JSON_HEDLEY_WARN_UNUSED_RESULT
from_cbor(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)23877     static basic_json from_cbor(IteratorType first, IteratorType last,
23878                                 const bool strict = true,
23879                                 const bool allow_exceptions = true,
23880                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23881     {
23882         basic_json result;
23883         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23884         auto ia = detail::input_adapter(std::move(first), std::move(last));
23885         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23886         return res ? result : basic_json(value_t::discarded);
23887     }
23888 
23889     template<typename T>
23890     JSON_HEDLEY_WARN_UNUSED_RESULT
23891     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
from_cbor(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)23892     static basic_json from_cbor(const T* ptr, std::size_t len,
23893                                 const bool strict = true,
23894                                 const bool allow_exceptions = true,
23895                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23896     {
23897         return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23898     }
23899 
23900 
23901     JSON_HEDLEY_WARN_UNUSED_RESULT
23902     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
from_cbor(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)23903     static basic_json from_cbor(detail::span_input_adapter&& i,
23904                                 const bool strict = true,
23905                                 const bool allow_exceptions = true,
23906                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23907     {
23908         basic_json result;
23909         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23910         auto ia = i.get();
23911         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23912         return res ? result : basic_json(value_t::discarded);
23913     }
23914 
23915     /*!
23916     @brief create a JSON value from an input in MessagePack format
23917 
23918     Deserializes a given input @a i to a JSON value using the MessagePack
23919     serialization format.
23920 
23921     The library maps MessagePack types to JSON value types as follows:
23922 
23923     MessagePack type | JSON value type | first byte
23924     ---------------- | --------------- | ----------
23925     positive fixint  | number_unsigned | 0x00..0x7F
23926     fixmap           | object          | 0x80..0x8F
23927     fixarray         | array           | 0x90..0x9F
23928     fixstr           | string          | 0xA0..0xBF
23929     nil              | `null`          | 0xC0
23930     false            | `false`         | 0xC2
23931     true             | `true`          | 0xC3
23932     float 32         | number_float    | 0xCA
23933     float 64         | number_float    | 0xCB
23934     uint 8           | number_unsigned | 0xCC
23935     uint 16          | number_unsigned | 0xCD
23936     uint 32          | number_unsigned | 0xCE
23937     uint 64          | number_unsigned | 0xCF
23938     int 8            | number_integer  | 0xD0
23939     int 16           | number_integer  | 0xD1
23940     int 32           | number_integer  | 0xD2
23941     int 64           | number_integer  | 0xD3
23942     str 8            | string          | 0xD9
23943     str 16           | string          | 0xDA
23944     str 32           | string          | 0xDB
23945     array 16         | array           | 0xDC
23946     array 32         | array           | 0xDD
23947     map 16           | object          | 0xDE
23948     map 32           | object          | 0xDF
23949     bin 8            | binary          | 0xC4
23950     bin 16           | binary          | 0xC5
23951     bin 32           | binary          | 0xC6
23952     ext 8            | binary          | 0xC7
23953     ext 16           | binary          | 0xC8
23954     ext 32           | binary          | 0xC9
23955     fixext 1         | binary          | 0xD4
23956     fixext 2         | binary          | 0xD5
23957     fixext 4         | binary          | 0xD6
23958     fixext 8         | binary          | 0xD7
23959     fixext 16        | binary          | 0xD8
23960     negative fixint  | number_integer  | 0xE0-0xFF
23961 
23962     @note Any MessagePack output created @ref to_msgpack can be successfully
23963           parsed by @ref from_msgpack.
23964 
23965     @param[in] i  an input in MessagePack format convertible to an input
23966                   adapter
23967     @param[in] strict  whether to expect the input to be consumed until EOF
23968                        (true by default)
23969     @param[in] allow_exceptions  whether to throw exceptions in case of a
23970     parse error (optional, true by default)
23971 
23972     @return deserialized JSON value; in case of a parse error and
23973             @a allow_exceptions set to `false`, the return value will be
23974             value_t::discarded.
23975 
23976     @throw parse_error.110 if the given input ends prematurely or the end of
23977     file was not reached when @a strict was set to true
23978     @throw parse_error.112 if unsupported features from MessagePack were
23979     used in the given input @a i or if the input is not valid MessagePack
23980     @throw parse_error.113 if a string was expected as map key, but not found
23981 
23982     @complexity Linear in the size of the input @a i.
23983 
23984     @liveexample{The example shows the deserialization of a byte vector in
23985     MessagePack format to a JSON value.,from_msgpack}
23986 
23987     @sa http://msgpack.org
23988     @sa @ref to_msgpack(const basic_json&) for the analogous serialization
23989     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
23990         related CBOR format
23991     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
23992         the related UBJSON format
23993     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
23994         the related BSON format
23995 
23996     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
23997            consume input adapters, removed start_index parameter, and added
23998            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
23999            since 3.2.0
24000     */
24001     template<typename InputType>
24002     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(InputType && i,const bool strict=true,const bool allow_exceptions=true)24003     static basic_json from_msgpack(InputType&& i,
24004                                    const bool strict = true,
24005                                    const bool allow_exceptions = true)
24006     {
24007         basic_json result;
24008         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24009         auto ia = detail::input_adapter(std::forward<InputType>(i));
24010         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24011         return res ? result : basic_json(value_t::discarded);
24012     }
24013 
24014     /*!
24015     @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
24016     */
24017     template<typename IteratorType>
24018     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24019     static basic_json from_msgpack(IteratorType first, IteratorType last,
24020                                    const bool strict = true,
24021                                    const bool allow_exceptions = true)
24022     {
24023         basic_json result;
24024         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24025         auto ia = detail::input_adapter(std::move(first), std::move(last));
24026         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24027         return res ? result : basic_json(value_t::discarded);
24028     }
24029 
24030 
24031     template<typename T>
24032     JSON_HEDLEY_WARN_UNUSED_RESULT
24033     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)24034     static basic_json from_msgpack(const T* ptr, std::size_t len,
24035                                    const bool strict = true,
24036                                    const bool allow_exceptions = true)
24037     {
24038         return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24039     }
24040 
24041     JSON_HEDLEY_WARN_UNUSED_RESULT
24042     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)24043     static basic_json from_msgpack(detail::span_input_adapter&& i,
24044                                    const bool strict = true,
24045                                    const bool allow_exceptions = true)
24046     {
24047         basic_json result;
24048         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24049         auto ia = i.get();
24050         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24051         return res ? result : basic_json(value_t::discarded);
24052     }
24053 
24054 
24055     /*!
24056     @brief create a JSON value from an input in UBJSON format
24057 
24058     Deserializes a given input @a i to a JSON value using the UBJSON (Universal
24059     Binary JSON) serialization format.
24060 
24061     The library maps UBJSON types to JSON value types as follows:
24062 
24063     UBJSON type | JSON value type                         | marker
24064     ----------- | --------------------------------------- | ------
24065     no-op       | *no value, next value is read*          | `N`
24066     null        | `null`                                  | `Z`
24067     false       | `false`                                 | `F`
24068     true        | `true`                                  | `T`
24069     float32     | number_float                            | `d`
24070     float64     | number_float                            | `D`
24071     uint8       | number_unsigned                         | `U`
24072     int8        | number_integer                          | `i`
24073     int16       | number_integer                          | `I`
24074     int32       | number_integer                          | `l`
24075     int64       | number_integer                          | `L`
24076     high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
24077     string      | string                                  | `S`
24078     char        | string                                  | `C`
24079     array       | array (optimized values are supported)  | `[`
24080     object      | object (optimized values are supported) | `{`
24081 
24082     @note The mapping is **complete** in the sense that any UBJSON value can
24083           be converted to a JSON value.
24084 
24085     @param[in] i  an input in UBJSON format convertible to an input adapter
24086     @param[in] strict  whether to expect the input to be consumed until EOF
24087                        (true by default)
24088     @param[in] allow_exceptions  whether to throw exceptions in case of a
24089     parse error (optional, true by default)
24090 
24091     @return deserialized JSON value; in case of a parse error and
24092             @a allow_exceptions set to `false`, the return value will be
24093             value_t::discarded.
24094 
24095     @throw parse_error.110 if the given input ends prematurely or the end of
24096     file was not reached when @a strict was set to true
24097     @throw parse_error.112 if a parse error occurs
24098     @throw parse_error.113 if a string could not be parsed successfully
24099 
24100     @complexity Linear in the size of the input @a i.
24101 
24102     @liveexample{The example shows the deserialization of a byte vector in
24103     UBJSON format to a JSON value.,from_ubjson}
24104 
24105     @sa http://ubjson.org
24106     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
24107              analogous serialization
24108     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24109         related CBOR format
24110     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24111         the related MessagePack format
24112     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24113         the related BSON format
24114 
24115     @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
24116     */
24117     template<typename InputType>
24118     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(InputType && i,const bool strict=true,const bool allow_exceptions=true)24119     static basic_json from_ubjson(InputType&& i,
24120                                   const bool strict = true,
24121                                   const bool allow_exceptions = true)
24122     {
24123         basic_json result;
24124         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24125         auto ia = detail::input_adapter(std::forward<InputType>(i));
24126         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24127         return res ? result : basic_json(value_t::discarded);
24128     }
24129 
24130     /*!
24131     @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
24132     */
24133     template<typename IteratorType>
24134     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24135     static basic_json from_ubjson(IteratorType first, IteratorType last,
24136                                   const bool strict = true,
24137                                   const bool allow_exceptions = true)
24138     {
24139         basic_json result;
24140         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24141         auto ia = detail::input_adapter(std::move(first), std::move(last));
24142         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24143         return res ? result : basic_json(value_t::discarded);
24144     }
24145 
24146     template<typename T>
24147     JSON_HEDLEY_WARN_UNUSED_RESULT
24148     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)24149     static basic_json from_ubjson(const T* ptr, std::size_t len,
24150                                   const bool strict = true,
24151                                   const bool allow_exceptions = true)
24152     {
24153         return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24154     }
24155 
24156     JSON_HEDLEY_WARN_UNUSED_RESULT
24157     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)24158     static basic_json from_ubjson(detail::span_input_adapter&& i,
24159                                   const bool strict = true,
24160                                   const bool allow_exceptions = true)
24161     {
24162         basic_json result;
24163         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24164         auto ia = i.get();
24165         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24166         return res ? result : basic_json(value_t::discarded);
24167     }
24168 
24169 
24170     /*!
24171     @brief Create a JSON value from an input in BSON format
24172 
24173     Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
24174     serialization format.
24175 
24176     The library maps BSON record types to JSON value types as follows:
24177 
24178     BSON type       | BSON marker byte | JSON value type
24179     --------------- | ---------------- | ---------------------------
24180     double          | 0x01             | number_float
24181     string          | 0x02             | string
24182     document        | 0x03             | object
24183     array           | 0x04             | array
24184     binary          | 0x05             | still unsupported
24185     undefined       | 0x06             | still unsupported
24186     ObjectId        | 0x07             | still unsupported
24187     boolean         | 0x08             | boolean
24188     UTC Date-Time   | 0x09             | still unsupported
24189     null            | 0x0A             | null
24190     Regular Expr.   | 0x0B             | still unsupported
24191     DB Pointer      | 0x0C             | still unsupported
24192     JavaScript Code | 0x0D             | still unsupported
24193     Symbol          | 0x0E             | still unsupported
24194     JavaScript Code | 0x0F             | still unsupported
24195     int32           | 0x10             | number_integer
24196     Timestamp       | 0x11             | still unsupported
24197     128-bit decimal float | 0x13       | still unsupported
24198     Max Key         | 0x7F             | still unsupported
24199     Min Key         | 0xFF             | still unsupported
24200 
24201     @warning The mapping is **incomplete**. The unsupported mappings
24202              are indicated in the table above.
24203 
24204     @param[in] i  an input in BSON format convertible to an input adapter
24205     @param[in] strict  whether to expect the input to be consumed until EOF
24206                        (true by default)
24207     @param[in] allow_exceptions  whether to throw exceptions in case of a
24208     parse error (optional, true by default)
24209 
24210     @return deserialized JSON value; in case of a parse error and
24211             @a allow_exceptions set to `false`, the return value will be
24212             value_t::discarded.
24213 
24214     @throw parse_error.114 if an unsupported BSON record type is encountered
24215 
24216     @complexity Linear in the size of the input @a i.
24217 
24218     @liveexample{The example shows the deserialization of a byte vector in
24219     BSON format to a JSON value.,from_bson}
24220 
24221     @sa http://bsonspec.org/spec.html
24222     @sa @ref to_bson(const basic_json&) for the analogous serialization
24223     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24224         related CBOR format
24225     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24226         the related MessagePack format
24227     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
24228         related UBJSON format
24229     */
24230     template<typename InputType>
24231     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(InputType && i,const bool strict=true,const bool allow_exceptions=true)24232     static basic_json from_bson(InputType&& i,
24233                                 const bool strict = true,
24234                                 const bool allow_exceptions = true)
24235     {
24236         basic_json result;
24237         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24238         auto ia = detail::input_adapter(std::forward<InputType>(i));
24239         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24240         return res ? result : basic_json(value_t::discarded);
24241     }
24242 
24243     /*!
24244     @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
24245     */
24246     template<typename IteratorType>
24247     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24248     static basic_json from_bson(IteratorType first, IteratorType last,
24249                                 const bool strict = true,
24250                                 const bool allow_exceptions = true)
24251     {
24252         basic_json result;
24253         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24254         auto ia = detail::input_adapter(std::move(first), std::move(last));
24255         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24256         return res ? result : basic_json(value_t::discarded);
24257     }
24258 
24259     template<typename T>
24260     JSON_HEDLEY_WARN_UNUSED_RESULT
24261     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)24262     static basic_json from_bson(const T* ptr, std::size_t len,
24263                                 const bool strict = true,
24264                                 const bool allow_exceptions = true)
24265     {
24266         return from_bson(ptr, ptr + len, strict, allow_exceptions);
24267     }
24268 
24269     JSON_HEDLEY_WARN_UNUSED_RESULT
24270     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)24271     static basic_json from_bson(detail::span_input_adapter&& i,
24272                                 const bool strict = true,
24273                                 const bool allow_exceptions = true)
24274     {
24275         basic_json result;
24276         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24277         auto ia = i.get();
24278         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24279         return res ? result : basic_json(value_t::discarded);
24280     }
24281     /// @}
24282 
24283     //////////////////////////
24284     // JSON Pointer support //
24285     //////////////////////////
24286 
24287     /// @name JSON Pointer functions
24288     /// @{
24289 
24290     /*!
24291     @brief access specified element via JSON Pointer
24292 
24293     Uses a JSON pointer to retrieve a reference to the respective JSON value.
24294     No bound checking is performed. Similar to @ref operator[](const typename
24295     object_t::key_type&), `null` values are created in arrays and objects if
24296     necessary.
24297 
24298     In particular:
24299     - If the JSON pointer points to an object key that does not exist, it
24300       is created an filled with a `null` value before a reference to it
24301       is returned.
24302     - If the JSON pointer points to an array index that does not exist, it
24303       is created an filled with a `null` value before a reference to it
24304       is returned. All indices between the current maximum and the given
24305       index are also filled with `null`.
24306     - The special value `-` is treated as a synonym for the index past the
24307       end.
24308 
24309     @param[in] ptr  a JSON pointer
24310 
24311     @return reference to the element pointed to by @a ptr
24312 
24313     @complexity Constant.
24314 
24315     @throw parse_error.106   if an array index begins with '0'
24316     @throw parse_error.109   if an array index was not a number
24317     @throw out_of_range.404  if the JSON pointer can not be resolved
24318 
24319     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
24320 
24321     @since version 2.0.0
24322     */
operator [](const json_pointer & ptr)24323     reference operator[](const json_pointer& ptr)
24324     {
24325         return ptr.get_unchecked(this);
24326     }
24327 
24328     /*!
24329     @brief access specified element via JSON Pointer
24330 
24331     Uses a JSON pointer to retrieve a reference to the respective JSON value.
24332     No bound checking is performed. The function does not change the JSON
24333     value; no `null` values are created. In particular, the special value
24334     `-` yields an exception.
24335 
24336     @param[in] ptr  JSON pointer to the desired element
24337 
24338     @return const reference to the element pointed to by @a ptr
24339 
24340     @complexity Constant.
24341 
24342     @throw parse_error.106   if an array index begins with '0'
24343     @throw parse_error.109   if an array index was not a number
24344     @throw out_of_range.402  if the array index '-' is used
24345     @throw out_of_range.404  if the JSON pointer can not be resolved
24346 
24347     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
24348 
24349     @since version 2.0.0
24350     */
operator [](const json_pointer & ptr) const24351     const_reference operator[](const json_pointer& ptr) const
24352     {
24353         return ptr.get_unchecked(this);
24354     }
24355 
24356     /*!
24357     @brief access specified element via JSON Pointer
24358 
24359     Returns a reference to the element at with specified JSON pointer @a ptr,
24360     with bounds checking.
24361 
24362     @param[in] ptr  JSON pointer to the desired element
24363 
24364     @return reference to the element pointed to by @a ptr
24365 
24366     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24367     begins with '0'. See example below.
24368 
24369     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24370     is not a number. See example below.
24371 
24372     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24373     is out of range. See example below.
24374 
24375     @throw out_of_range.402 if the array index '-' is used in the passed JSON
24376     pointer @a ptr. As `at` provides checked access (and no elements are
24377     implicitly inserted), the index '-' is always invalid. See example below.
24378 
24379     @throw out_of_range.403 if the JSON pointer describes a key of an object
24380     which cannot be found. See example below.
24381 
24382     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24383     See example below.
24384 
24385     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24386     changes in the JSON value.
24387 
24388     @complexity Constant.
24389 
24390     @since version 2.0.0
24391 
24392     @liveexample{The behavior is shown in the example.,at_json_pointer}
24393     */
at(const json_pointer & ptr)24394     reference at(const json_pointer& ptr)
24395     {
24396         return ptr.get_checked(this);
24397     }
24398 
24399     /*!
24400     @brief access specified element via JSON Pointer
24401 
24402     Returns a const reference to the element at with specified JSON pointer @a
24403     ptr, with bounds checking.
24404 
24405     @param[in] ptr  JSON pointer to the desired element
24406 
24407     @return reference to the element pointed to by @a ptr
24408 
24409     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24410     begins with '0'. See example below.
24411 
24412     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24413     is not a number. See example below.
24414 
24415     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24416     is out of range. See example below.
24417 
24418     @throw out_of_range.402 if the array index '-' is used in the passed JSON
24419     pointer @a ptr. As `at` provides checked access (and no elements are
24420     implicitly inserted), the index '-' is always invalid. See example below.
24421 
24422     @throw out_of_range.403 if the JSON pointer describes a key of an object
24423     which cannot be found. See example below.
24424 
24425     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24426     See example below.
24427 
24428     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24429     changes in the JSON value.
24430 
24431     @complexity Constant.
24432 
24433     @since version 2.0.0
24434 
24435     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
24436     */
at(const json_pointer & ptr) const24437     const_reference at(const json_pointer& ptr) const
24438     {
24439         return ptr.get_checked(this);
24440     }
24441 
24442     /*!
24443     @brief return flattened JSON value
24444 
24445     The function creates a JSON object whose keys are JSON pointers (see [RFC
24446     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
24447     primitive. The original JSON value can be restored using the @ref
24448     unflatten() function.
24449 
24450     @return an object that maps JSON pointers to primitive values
24451 
24452     @note Empty objects and arrays are flattened to `null` and will not be
24453           reconstructed correctly by the @ref unflatten() function.
24454 
24455     @complexity Linear in the size the JSON value.
24456 
24457     @liveexample{The following code shows how a JSON object is flattened to an
24458     object whose keys consist of JSON pointers.,flatten}
24459 
24460     @sa @ref unflatten() for the reverse function
24461 
24462     @since version 2.0.0
24463     */
flatten() const24464     basic_json flatten() const
24465     {
24466         basic_json result(value_t::object);
24467         json_pointer::flatten("", *this, result);
24468         return result;
24469     }
24470 
24471     /*!
24472     @brief unflatten a previously flattened JSON value
24473 
24474     The function restores the arbitrary nesting of a JSON value that has been
24475     flattened before using the @ref flatten() function. The JSON value must
24476     meet certain constraints:
24477     1. The value must be an object.
24478     2. The keys must be JSON pointers (see
24479        [RFC 6901](https://tools.ietf.org/html/rfc6901))
24480     3. The mapped values must be primitive JSON types.
24481 
24482     @return the original JSON from a flattened version
24483 
24484     @note Empty objects and arrays are flattened by @ref flatten() to `null`
24485           values and can not unflattened to their original type. Apart from
24486           this example, for a JSON value `j`, the following is always true:
24487           `j == j.flatten().unflatten()`.
24488 
24489     @complexity Linear in the size the JSON value.
24490 
24491     @throw type_error.314  if value is not an object
24492     @throw type_error.315  if object values are not primitive
24493 
24494     @liveexample{The following code shows how a flattened JSON object is
24495     unflattened into the original nested JSON object.,unflatten}
24496 
24497     @sa @ref flatten() for the reverse function
24498 
24499     @since version 2.0.0
24500     */
unflatten() const24501     basic_json unflatten() const
24502     {
24503         return json_pointer::unflatten(*this);
24504     }
24505 
24506     /// @}
24507 
24508     //////////////////////////
24509     // JSON Patch functions //
24510     //////////////////////////
24511 
24512     /// @name JSON Patch functions
24513     /// @{
24514 
24515     /*!
24516     @brief applies a JSON patch
24517 
24518     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
24519     expressing a sequence of operations to apply to a JSON) document. With
24520     this function, a JSON Patch is applied to the current JSON value by
24521     executing all operations from the patch.
24522 
24523     @param[in] json_patch  JSON patch document
24524     @return patched document
24525 
24526     @note The application of a patch is atomic: Either all operations succeed
24527           and the patched document is returned or an exception is thrown. In
24528           any case, the original value is not changed: the patch is applied
24529           to a copy of the value.
24530 
24531     @throw parse_error.104 if the JSON patch does not consist of an array of
24532     objects
24533 
24534     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
24535     attributes are missing); example: `"operation add must have member path"`
24536 
24537     @throw out_of_range.401 if an array index is out of range.
24538 
24539     @throw out_of_range.403 if a JSON pointer inside the patch could not be
24540     resolved successfully in the current JSON value; example: `"key baz not
24541     found"`
24542 
24543     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
24544     "move")
24545 
24546     @throw other_error.501 if "test" operation was unsuccessful
24547 
24548     @complexity Linear in the size of the JSON value and the length of the
24549     JSON patch. As usually only a fraction of the JSON value is affected by
24550     the patch, the complexity can usually be neglected.
24551 
24552     @liveexample{The following code shows how a JSON patch is applied to a
24553     value.,patch}
24554 
24555     @sa @ref diff -- create a JSON patch by comparing two JSON values
24556 
24557     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
24558     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
24559 
24560     @since version 2.0.0
24561     */
patch(const basic_json & json_patch) const24562     basic_json patch(const basic_json& json_patch) const
24563     {
24564         // make a working copy to apply the patch to
24565         basic_json result = *this;
24566 
24567         // the valid JSON Patch operations
24568         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24569 
24570         const auto get_op = [](const std::string & op)
24571         {
24572             if (op == "add")
24573             {
24574                 return patch_operations::add;
24575             }
24576             if (op == "remove")
24577             {
24578                 return patch_operations::remove;
24579             }
24580             if (op == "replace")
24581             {
24582                 return patch_operations::replace;
24583             }
24584             if (op == "move")
24585             {
24586                 return patch_operations::move;
24587             }
24588             if (op == "copy")
24589             {
24590                 return patch_operations::copy;
24591             }
24592             if (op == "test")
24593             {
24594                 return patch_operations::test;
24595             }
24596 
24597             return patch_operations::invalid;
24598         };
24599 
24600         // wrapper for "add" operation; add value at ptr
24601         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24602         {
24603             // adding to the root of the target document means replacing it
24604             if (ptr.empty())
24605             {
24606                 result = val;
24607                 return;
24608             }
24609 
24610             // make sure the top element of the pointer exists
24611             json_pointer top_pointer = ptr.top();
24612             if (top_pointer != ptr)
24613             {
24614                 result.at(top_pointer);
24615             }
24616 
24617             // get reference to parent of JSON pointer ptr
24618             const auto last_path = ptr.back();
24619             ptr.pop_back();
24620             basic_json& parent = result[ptr];
24621 
24622             switch (parent.m_type)
24623             {
24624                 case value_t::null:
24625                 case value_t::object:
24626                 {
24627                     // use operator[] to add value
24628                     parent[last_path] = val;
24629                     break;
24630                 }
24631 
24632                 case value_t::array:
24633                 {
24634                     if (last_path == "-")
24635                     {
24636                         // special case: append to back
24637                         parent.push_back(val);
24638                     }
24639                     else
24640                     {
24641                         const auto idx = json_pointer::array_index(last_path);
24642                         if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24643                         {
24644                             // avoid undefined behavior
24645                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24646                         }
24647 
24648                         // default case: insert add offset
24649                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24650                     }
24651                     break;
24652                 }
24653 
24654                 // if there exists a parent it cannot be primitive
24655                 default:            // LCOV_EXCL_LINE
24656                     JSON_ASSERT(false);  // LCOV_EXCL_LINE
24657             }
24658         };
24659 
24660         // wrapper for "remove" operation; remove value at ptr
24661         const auto operation_remove = [&result](json_pointer & ptr)
24662         {
24663             // get reference to parent of JSON pointer ptr
24664             const auto last_path = ptr.back();
24665             ptr.pop_back();
24666             basic_json& parent = result.at(ptr);
24667 
24668             // remove child
24669             if (parent.is_object())
24670             {
24671                 // perform range check
24672                 auto it = parent.find(last_path);
24673                 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24674                 {
24675                     parent.erase(it);
24676                 }
24677                 else
24678                 {
24679                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24680                 }
24681             }
24682             else if (parent.is_array())
24683             {
24684                 // note erase performs range check
24685                 parent.erase(json_pointer::array_index(last_path));
24686             }
24687         };
24688 
24689         // type check: top level value must be an array
24690         if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24691         {
24692             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24693         }
24694 
24695         // iterate and apply the operations
24696         for (const auto& val : json_patch)
24697         {
24698             // wrapper to get a value for an operation
24699             const auto get_value = [&val](const std::string & op,
24700                                           const std::string & member,
24701                                           bool string_type) -> basic_json &
24702             {
24703                 // find value
24704                 auto it = val.m_value.object->find(member);
24705 
24706                 // context-sensitive error message
24707                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24708 
24709                 // check if desired value is present
24710                 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24711                 {
24712                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24713                 }
24714 
24715                 // check if result is of type string
24716                 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24717                 {
24718                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24719                 }
24720 
24721                 // no error: return value
24722                 return it->second;
24723             };
24724 
24725             // type check: every element of the array must be an object
24726             if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24727             {
24728                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24729             }
24730 
24731             // collect mandatory members
24732             const auto op = get_value("op", "op", true).template get<std::string>();
24733             const auto path = get_value(op, "path", true).template get<std::string>();
24734             json_pointer ptr(path);
24735 
24736             switch (get_op(op))
24737             {
24738                 case patch_operations::add:
24739                 {
24740                     operation_add(ptr, get_value("add", "value", false));
24741                     break;
24742                 }
24743 
24744                 case patch_operations::remove:
24745                 {
24746                     operation_remove(ptr);
24747                     break;
24748                 }
24749 
24750                 case patch_operations::replace:
24751                 {
24752                     // the "path" location must exist - use at()
24753                     result.at(ptr) = get_value("replace", "value", false);
24754                     break;
24755                 }
24756 
24757                 case patch_operations::move:
24758                 {
24759                     const auto from_path = get_value("move", "from", true).template get<std::string>();
24760                     json_pointer from_ptr(from_path);
24761 
24762                     // the "from" location must exist - use at()
24763                     basic_json v = result.at(from_ptr);
24764 
24765                     // The move operation is functionally identical to a
24766                     // "remove" operation on the "from" location, followed
24767                     // immediately by an "add" operation at the target
24768                     // location with the value that was just removed.
24769                     operation_remove(from_ptr);
24770                     operation_add(ptr, v);
24771                     break;
24772                 }
24773 
24774                 case patch_operations::copy:
24775                 {
24776                     const auto from_path = get_value("copy", "from", true).template get<std::string>();
24777                     const json_pointer from_ptr(from_path);
24778 
24779                     // the "from" location must exist - use at()
24780                     basic_json v = result.at(from_ptr);
24781 
24782                     // The copy is functionally identical to an "add"
24783                     // operation at the target location using the value
24784                     // specified in the "from" member.
24785                     operation_add(ptr, v);
24786                     break;
24787                 }
24788 
24789                 case patch_operations::test:
24790                 {
24791                     bool success = false;
24792                     JSON_TRY
24793                     {
24794                         // check if "value" matches the one at "path"
24795                         // the "path" location must exist - use at()
24796                         success = (result.at(ptr) == get_value("test", "value", false));
24797                     }
24798                     JSON_INTERNAL_CATCH (out_of_range&)
24799                     {
24800                         // ignore out of range errors: success remains false
24801                     }
24802 
24803                     // throw an exception if test fails
24804                     if (JSON_HEDLEY_UNLIKELY(!success))
24805                     {
24806                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24807                     }
24808 
24809                     break;
24810                 }
24811 
24812                 default:
24813                 {
24814                     // op must be "add", "remove", "replace", "move", "copy", or
24815                     // "test"
24816                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24817                 }
24818             }
24819         }
24820 
24821         return result;
24822     }
24823 
24824     /*!
24825     @brief creates a diff as a JSON patch
24826 
24827     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
24828     be changed into the value @a target by calling @ref patch function.
24829 
24830     @invariant For two JSON values @a source and @a target, the following code
24831     yields always `true`:
24832     @code {.cpp}
24833     source.patch(diff(source, target)) == target;
24834     @endcode
24835 
24836     @note Currently, only `remove`, `add`, and `replace` operations are
24837           generated.
24838 
24839     @param[in] source  JSON value to compare from
24840     @param[in] target  JSON value to compare against
24841     @param[in] path    helper value to create JSON pointers
24842 
24843     @return a JSON patch to convert the @a source to @a target
24844 
24845     @complexity Linear in the lengths of @a source and @a target.
24846 
24847     @liveexample{The following code shows how a JSON patch is created as a
24848     diff for two JSON values.,diff}
24849 
24850     @sa @ref patch -- apply a JSON patch
24851     @sa @ref merge_patch -- apply a JSON Merge Patch
24852 
24853     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
24854 
24855     @since version 2.0.0
24856     */
24857     JSON_HEDLEY_WARN_UNUSED_RESULT
diff(const basic_json & source,const basic_json & target,const std::string & path="")24858     static basic_json diff(const basic_json& source, const basic_json& target,
24859                            const std::string& path = "")
24860     {
24861         // the patch
24862         basic_json result(value_t::array);
24863 
24864         // if the values are the same, return empty patch
24865         if (source == target)
24866         {
24867             return result;
24868         }
24869 
24870         if (source.type() != target.type())
24871         {
24872             // different types: replace value
24873             result.push_back(
24874             {
24875                 {"op", "replace"}, {"path", path}, {"value", target}
24876             });
24877             return result;
24878         }
24879 
24880         switch (source.type())
24881         {
24882             case value_t::array:
24883             {
24884                 // first pass: traverse common elements
24885                 std::size_t i = 0;
24886                 while (i < source.size() && i < target.size())
24887                 {
24888                     // recursive call to compare array values at index i
24889                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24890                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24891                     ++i;
24892                 }
24893 
24894                 // i now reached the end of at least one array
24895                 // in a second pass, traverse the remaining elements
24896 
24897                 // remove my remaining elements
24898                 const auto end_index = static_cast<difference_type>(result.size());
24899                 while (i < source.size())
24900                 {
24901                     // add operations in reverse order to avoid invalid
24902                     // indices
24903                     result.insert(result.begin() + end_index, object(
24904                     {
24905                         {"op", "remove"},
24906                         {"path", path + "/" + std::to_string(i)}
24907                     }));
24908                     ++i;
24909                 }
24910 
24911                 // add other remaining elements
24912                 while (i < target.size())
24913                 {
24914                     result.push_back(
24915                     {
24916                         {"op", "add"},
24917                         {"path", path + "/-"},
24918                         {"value", target[i]}
24919                     });
24920                     ++i;
24921                 }
24922 
24923                 break;
24924             }
24925 
24926             case value_t::object:
24927             {
24928                 // first pass: traverse this object's elements
24929                 for (auto it = source.cbegin(); it != source.cend(); ++it)
24930                 {
24931                     // escape the key name to be used in a JSON patch
24932                     const auto key = json_pointer::escape(it.key());
24933 
24934                     if (target.find(it.key()) != target.end())
24935                     {
24936                         // recursive call to compare object values at key it
24937                         auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
24938                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24939                     }
24940                     else
24941                     {
24942                         // found a key that is not in o -> remove it
24943                         result.push_back(object(
24944                         {
24945                             {"op", "remove"}, {"path", path + "/" + key}
24946                         }));
24947                     }
24948                 }
24949 
24950                 // second pass: traverse other object's elements
24951                 for (auto it = target.cbegin(); it != target.cend(); ++it)
24952                 {
24953                     if (source.find(it.key()) == source.end())
24954                     {
24955                         // found a key that is not in this -> add it
24956                         const auto key = json_pointer::escape(it.key());
24957                         result.push_back(
24958                         {
24959                             {"op", "add"}, {"path", path + "/" + key},
24960                             {"value", it.value()}
24961                         });
24962                     }
24963                 }
24964 
24965                 break;
24966             }
24967 
24968             default:
24969             {
24970                 // both primitive type: replace value
24971                 result.push_back(
24972                 {
24973                     {"op", "replace"}, {"path", path}, {"value", target}
24974                 });
24975                 break;
24976             }
24977         }
24978 
24979         return result;
24980     }
24981 
24982     /// @}
24983 
24984     ////////////////////////////////
24985     // JSON Merge Patch functions //
24986     ////////////////////////////////
24987 
24988     /// @name JSON Merge Patch functions
24989     /// @{
24990 
24991     /*!
24992     @brief applies a JSON Merge Patch
24993 
24994     The merge patch format is primarily intended for use with the HTTP PATCH
24995     method as a means of describing a set of modifications to a target
24996     resource's content. This function applies a merge patch to the current
24997     JSON value.
24998 
24999     The function implements the following algorithm from Section 2 of
25000     [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
25001 
25002     ```
25003     define MergePatch(Target, Patch):
25004       if Patch is an Object:
25005         if Target is not an Object:
25006           Target = {} // Ignore the contents and set it to an empty Object
25007         for each Name/Value pair in Patch:
25008           if Value is null:
25009             if Name exists in Target:
25010               remove the Name/Value pair from Target
25011           else:
25012             Target[Name] = MergePatch(Target[Name], Value)
25013         return Target
25014       else:
25015         return Patch
25016     ```
25017 
25018     Thereby, `Target` is the current object; that is, the patch is applied to
25019     the current value.
25020 
25021     @param[in] apply_patch  the patch to apply
25022 
25023     @complexity Linear in the lengths of @a patch.
25024 
25025     @liveexample{The following code shows how a JSON Merge Patch is applied to
25026     a JSON document.,merge_patch}
25027 
25028     @sa @ref patch -- apply a JSON patch
25029     @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
25030 
25031     @since version 3.0.0
25032     */
merge_patch(const basic_json & apply_patch)25033     void merge_patch(const basic_json& apply_patch)
25034     {
25035         if (apply_patch.is_object())
25036         {
25037             if (!is_object())
25038             {
25039                 *this = object();
25040             }
25041             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25042             {
25043                 if (it.value().is_null())
25044                 {
25045                     erase(it.key());
25046                 }
25047                 else
25048                 {
25049                     operator[](it.key()).merge_patch(it.value());
25050                 }
25051             }
25052         }
25053         else
25054         {
25055             *this = apply_patch;
25056         }
25057     }
25058 
25059     /// @}
25060 };
25061 
25062 /*!
25063 @brief user-defined to_string function for JSON values
25064 
25065 This function implements a user-defined to_string  for JSON objects.
25066 
25067 @param[in] j  a JSON object
25068 @return a std::string object
25069 */
25070 
25071 NLOHMANN_BASIC_JSON_TPL_DECLARATION
to_string(const NLOHMANN_BASIC_JSON_TPL & j)25072 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25073 {
25074     return j.dump();
25075 }
25076 } // namespace nlohmann
25077 
25078 ///////////////////////
25079 // nonmember support //
25080 ///////////////////////
25081 
25082 // specialization of std::swap, and std::hash
25083 namespace std
25084 {
25085 
25086 /// hash value for JSON objects
25087 template<>
25088 struct hash<nlohmann::json>
25089 {
25090     /*!
25091     @brief return a hash value for a JSON object
25092 
25093     @since version 1.0.0
25094     */
operator ()std::hash25095     std::size_t operator()(const nlohmann::json& j) const
25096     {
25097         return nlohmann::detail::hash(j);
25098     }
25099 };
25100 
25101 /// specialization for std::less<value_t>
25102 /// @note: do not remove the space after '<',
25103 ///        see https://github.com/nlohmann/json/pull/679
25104 template<>
25105 struct less<::nlohmann::detail::value_t>
25106 {
25107     /*!
25108     @brief compare two value_t enum values
25109     @since version 3.0.0
25110     */
operator ()std::less25111     bool operator()(nlohmann::detail::value_t lhs,
25112                     nlohmann::detail::value_t rhs) const noexcept
25113     {
25114         return nlohmann::detail::operator<(lhs, rhs);
25115     }
25116 };
25117 
25118 // C++20 prohibit function specialization in the std namespace.
25119 #ifndef JSON_HAS_CPP_20
25120 
25121 /*!
25122 @brief exchanges the values of two JSON objects
25123 
25124 @since version 1.0.0
25125 */
25126 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)25127 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25128     is_nothrow_move_constructible<nlohmann::json>::value&&
25129     is_nothrow_move_assignable<nlohmann::json>::value
25130                               )
25131 {
25132     j1.swap(j2);
25133 }
25134 
25135 #endif
25136 
25137 } // namespace std
25138 
25139 /*!
25140 @brief user-defined string literal for JSON values
25141 
25142 This operator implements a user-defined string literal for JSON objects. It
25143 can be used by adding `"_json"` to a string literal and returns a JSON object
25144 if no parse error occurred.
25145 
25146 @param[in] s  a string representation of a JSON object
25147 @param[in] n  the length of string @a s
25148 @return a JSON object
25149 
25150 @since version 1.0.0
25151 */
25152 JSON_HEDLEY_NON_NULL(1)
operator ""_json(const char * s,std::size_t n)25153 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25154 {
25155     return nlohmann::json::parse(s, s + n);
25156 }
25157 
25158 /*!
25159 @brief user-defined string literal for JSON pointer
25160 
25161 This operator implements a user-defined string literal for JSON Pointers. It
25162 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
25163 object if no parse error occurred.
25164 
25165 @param[in] s  a string representation of a JSON Pointer
25166 @param[in] n  the length of string @a s
25167 @return a JSON pointer object
25168 
25169 @since version 2.0.0
25170 */
25171 JSON_HEDLEY_NON_NULL(1)
operator ""_json_pointer(const char * s,std::size_t n)25172 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25173 {
25174     return nlohmann::json::json_pointer(std::string(s, n));
25175 }
25176 
25177 // #include <nlohmann/detail/macro_unscope.hpp>
25178 
25179 
25180 // restore GCC/clang diagnostic settings
25181 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25182     #pragma GCC diagnostic pop
25183 #endif
25184 #if defined(__clang__)
25185     #pragma GCC diagnostic pop
25186 #endif
25187 
25188 // clean up
25189 #undef JSON_ASSERT
25190 #undef JSON_INTERNAL_CATCH
25191 #undef JSON_CATCH
25192 #undef JSON_THROW
25193 #undef JSON_TRY
25194 #undef JSON_HAS_CPP_14
25195 #undef JSON_HAS_CPP_17
25196 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25197 #undef NLOHMANN_BASIC_JSON_TPL
25198 #undef JSON_EXPLICIT
25199 
25200 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25201 #undef JSON_HEDLEY_ALWAYS_INLINE
25202 #undef JSON_HEDLEY_ARM_VERSION
25203 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25204 #undef JSON_HEDLEY_ARRAY_PARAM
25205 #undef JSON_HEDLEY_ASSUME
25206 #undef JSON_HEDLEY_BEGIN_C_DECLS
25207 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25208 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25209 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25210 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25211 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25212 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25213 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25214 #undef JSON_HEDLEY_COMPCERT_VERSION
25215 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25216 #undef JSON_HEDLEY_CONCAT
25217 #undef JSON_HEDLEY_CONCAT3
25218 #undef JSON_HEDLEY_CONCAT3_EX
25219 #undef JSON_HEDLEY_CONCAT_EX
25220 #undef JSON_HEDLEY_CONST
25221 #undef JSON_HEDLEY_CONSTEXPR
25222 #undef JSON_HEDLEY_CONST_CAST
25223 #undef JSON_HEDLEY_CPP_CAST
25224 #undef JSON_HEDLEY_CRAY_VERSION
25225 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25226 #undef JSON_HEDLEY_C_DECL
25227 #undef JSON_HEDLEY_DEPRECATED
25228 #undef JSON_HEDLEY_DEPRECATED_FOR
25229 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25230 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25231 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25232 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25233 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25234 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25235 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25236 #undef JSON_HEDLEY_DMC_VERSION
25237 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25238 #undef JSON_HEDLEY_EMPTY_BASES
25239 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25240 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25241 #undef JSON_HEDLEY_END_C_DECLS
25242 #undef JSON_HEDLEY_FLAGS
25243 #undef JSON_HEDLEY_FLAGS_CAST
25244 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25245 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25246 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25247 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25248 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25249 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25250 #undef JSON_HEDLEY_GCC_HAS_WARNING
25251 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25252 #undef JSON_HEDLEY_GCC_VERSION
25253 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25254 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25255 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25256 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25257 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25258 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25259 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25260 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25261 #undef JSON_HEDLEY_GNUC_VERSION
25262 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25263 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25264 #undef JSON_HEDLEY_HAS_BUILTIN
25265 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25266 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25267 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25268 #undef JSON_HEDLEY_HAS_EXTENSION
25269 #undef JSON_HEDLEY_HAS_FEATURE
25270 #undef JSON_HEDLEY_HAS_WARNING
25271 #undef JSON_HEDLEY_IAR_VERSION
25272 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25273 #undef JSON_HEDLEY_IBM_VERSION
25274 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25275 #undef JSON_HEDLEY_IMPORT
25276 #undef JSON_HEDLEY_INLINE
25277 #undef JSON_HEDLEY_INTEL_VERSION
25278 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25279 #undef JSON_HEDLEY_IS_CONSTANT
25280 #undef JSON_HEDLEY_IS_CONSTEXPR_
25281 #undef JSON_HEDLEY_LIKELY
25282 #undef JSON_HEDLEY_MALLOC
25283 #undef JSON_HEDLEY_MESSAGE
25284 #undef JSON_HEDLEY_MSVC_VERSION
25285 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25286 #undef JSON_HEDLEY_NEVER_INLINE
25287 #undef JSON_HEDLEY_NON_NULL
25288 #undef JSON_HEDLEY_NO_ESCAPE
25289 #undef JSON_HEDLEY_NO_RETURN
25290 #undef JSON_HEDLEY_NO_THROW
25291 #undef JSON_HEDLEY_NULL
25292 #undef JSON_HEDLEY_PELLES_VERSION
25293 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25294 #undef JSON_HEDLEY_PGI_VERSION
25295 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25296 #undef JSON_HEDLEY_PREDICT
25297 #undef JSON_HEDLEY_PRINTF_FORMAT
25298 #undef JSON_HEDLEY_PRIVATE
25299 #undef JSON_HEDLEY_PUBLIC
25300 #undef JSON_HEDLEY_PURE
25301 #undef JSON_HEDLEY_REINTERPRET_CAST
25302 #undef JSON_HEDLEY_REQUIRE
25303 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25304 #undef JSON_HEDLEY_REQUIRE_MSG
25305 #undef JSON_HEDLEY_RESTRICT
25306 #undef JSON_HEDLEY_RETURNS_NON_NULL
25307 #undef JSON_HEDLEY_SENTINEL
25308 #undef JSON_HEDLEY_STATIC_ASSERT
25309 #undef JSON_HEDLEY_STATIC_CAST
25310 #undef JSON_HEDLEY_STRINGIFY
25311 #undef JSON_HEDLEY_STRINGIFY_EX
25312 #undef JSON_HEDLEY_SUNPRO_VERSION
25313 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25314 #undef JSON_HEDLEY_TINYC_VERSION
25315 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25316 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25317 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25318 #undef JSON_HEDLEY_TI_CL2000_VERSION
25319 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25320 #undef JSON_HEDLEY_TI_CL430_VERSION
25321 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25322 #undef JSON_HEDLEY_TI_CL6X_VERSION
25323 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25324 #undef JSON_HEDLEY_TI_CL7X_VERSION
25325 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25326 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25327 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25328 #undef JSON_HEDLEY_TI_VERSION
25329 #undef JSON_HEDLEY_TI_VERSION_CHECK
25330 #undef JSON_HEDLEY_UNAVAILABLE
25331 #undef JSON_HEDLEY_UNLIKELY
25332 #undef JSON_HEDLEY_UNPREDICTABLE
25333 #undef JSON_HEDLEY_UNREACHABLE
25334 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25335 #undef JSON_HEDLEY_VERSION
25336 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25337 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25338 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25339 #undef JSON_HEDLEY_VERSION_ENCODE
25340 #undef JSON_HEDLEY_WARNING
25341 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
25342 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25343 #undef JSON_HEDLEY_FALL_THROUGH
25344 
25345 
25346 
25347 #endif  // INCLUDE_NLOHMANN_JSON_HPP_
25348