1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++
4 |  |  |__   |  |  | | | |  version 3.9.1
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
32 
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 9
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36 
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
41 #include <iosfwd> // istream, ostream
42 #include <iterator> // random_access_iterator_tag
43 #include <memory> // unique_ptr
44 #include <numeric> // accumulate
45 #include <string> // string, stoi, to_string
46 #include <utility> // declval, forward, move, pair, swap
47 #include <vector> // vector
48 
49 // #include <nlohmann/adl_serializer.hpp>
50 
51 
52 #include <utility>
53 
54 // #include <nlohmann/detail/conversions/from_json.hpp>
55 
56 
57 #include <algorithm> // transform
58 #include <array> // array
59 #include <forward_list> // forward_list
60 #include <iterator> // inserter, front_inserter, end
61 #include <map> // map
62 #include <string> // string
63 #include <tuple> // tuple, make_tuple
64 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
65 #include <unordered_map> // unordered_map
66 #include <utility> // pair, declval
67 #include <valarray> // valarray
68 
69 // #include <nlohmann/detail/exceptions.hpp>
70 
71 
72 #include <exception> // exception
73 #include <stdexcept> // runtime_error
74 #include <string> // to_string
75 
76 // #include <nlohmann/detail/input/position_t.hpp>
77 
78 
79 #include <cstddef> // size_t
80 
81 namespace nlohmann
82 {
83 namespace detail
84 {
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                                     continue;
6763                                 }
6764                             }
6765                         }
6766 
6767                         default:
6768                             continue;
6769                     }
6770                 }
6771             }
6772 
6773             // unexpected character after reading '/'
6774             default:
6775             {
6776                 error_message = "invalid comment; expecting '/' or '*' after '/'";
6777                 return false;
6778             }
6779         }
6780     }
6781 
6782     JSON_HEDLEY_NON_NULL(2)
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         while (ignore_comments && current == '/')
7394         {
7395             if (!scan_comment())
7396             {
7397                 return token_type::parse_error;
7398             }
7399 
7400             // skip following whitespace
7401             skip_whitespace();
7402         }
7403 
7404         switch (current)
7405         {
7406             // structural characters
7407             case '[':
7408                 return token_type::begin_array;
7409             case ']':
7410                 return token_type::end_array;
7411             case '{':
7412                 return token_type::begin_object;
7413             case '}':
7414                 return token_type::end_object;
7415             case ':':
7416                 return token_type::name_separator;
7417             case ',':
7418                 return token_type::value_separator;
7419 
7420             // literals
7421             case 't':
7422             {
7423                 std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7424                 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7425             }
7426             case 'f':
7427             {
7428                 std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7429                 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7430             }
7431             case 'n':
7432             {
7433                 std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7434                 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7435             }
7436 
7437             // string
7438             case '\"':
7439                 return scan_string();
7440 
7441             // number
7442             case '-':
7443             case '0':
7444             case '1':
7445             case '2':
7446             case '3':
7447             case '4':
7448             case '5':
7449             case '6':
7450             case '7':
7451             case '8':
7452             case '9':
7453                 return scan_number();
7454 
7455             // end of input (the null byte is needed when parsing from
7456             // string literals)
7457             case '\0':
7458             case std::char_traits<char_type>::eof():
7459                 return token_type::end_of_input;
7460 
7461             // error
7462             default:
7463                 error_message = "invalid literal";
7464                 return token_type::parse_error;
7465         }
7466     }
7467 
7468   private:
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::const_iterator;
16412     using typename Container::size_type;
16413     using typename Container::value_type;
16414 
16415     // Explicit constructors instead of `using Container::Container`
16416     // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_mapnlohmann::ordered_map16417     ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16418     template <class It>
ordered_mapnlohmann::ordered_map16419     ordered_map(It first, It last, const Allocator& alloc = Allocator())
16420         : Container{first, last, alloc} {}
ordered_mapnlohmann::ordered_map16421     ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16422         : Container{init, alloc} {}
16423 
emplacenlohmann::ordered_map16424     std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16425     {
16426         for (auto it = this->begin(); it != this->end(); ++it)
16427         {
16428             if (it->first == key)
16429             {
16430                 return {it, false};
16431             }
16432         }
16433         Container::emplace_back(key, t);
16434         return {--this->end(), true};
16435     }
16436 
operator []nlohmann::ordered_map16437     T& operator[](const Key& key)
16438     {
16439         return emplace(key, T{}).first->second;
16440     }
16441 
operator []nlohmann::ordered_map16442     const T& operator[](const Key& key) const
16443     {
16444         return at(key);
16445     }
16446 
atnlohmann::ordered_map16447     T& at(const Key& key)
16448     {
16449         for (auto it = this->begin(); it != this->end(); ++it)
16450         {
16451             if (it->first == key)
16452             {
16453                 return it->second;
16454             }
16455         }
16456 
16457         throw std::out_of_range("key not found");
16458     }
16459 
atnlohmann::ordered_map16460     const T& at(const Key& key) const
16461     {
16462         for (auto it = this->begin(); it != this->end(); ++it)
16463         {
16464             if (it->first == key)
16465             {
16466                 return it->second;
16467             }
16468         }
16469 
16470         throw std::out_of_range("key not found");
16471     }
16472 
erasenlohmann::ordered_map16473     size_type erase(const Key& key)
16474     {
16475         for (auto it = this->begin(); it != this->end(); ++it)
16476         {
16477             if (it->first == key)
16478             {
16479                 // Since we cannot move const Keys, re-construct them in place
16480                 for (auto next = it; ++next != this->end(); ++it)
16481                 {
16482                     it->~value_type(); // Destroy but keep allocation
16483                     new (&*it) value_type{std::move(*next)};
16484                 }
16485                 Container::pop_back();
16486                 return 1;
16487             }
16488         }
16489         return 0;
16490     }
16491 
erasenlohmann::ordered_map16492     iterator erase(iterator pos)
16493     {
16494         auto it = pos;
16495 
16496         // Since we cannot move const Keys, re-construct them in place
16497         for (auto next = it; ++next != this->end(); ++it)
16498         {
16499             it->~value_type(); // Destroy but keep allocation
16500             new (&*it) value_type{std::move(*next)};
16501         }
16502         Container::pop_back();
16503         return pos;
16504     }
16505 
countnlohmann::ordered_map16506     size_type count(const Key& key) const
16507     {
16508         for (auto it = this->begin(); it != this->end(); ++it)
16509         {
16510             if (it->first == key)
16511             {
16512                 return 1;
16513             }
16514         }
16515         return 0;
16516     }
16517 
findnlohmann::ordered_map16518     iterator find(const Key& key)
16519     {
16520         for (auto it = this->begin(); it != this->end(); ++it)
16521         {
16522             if (it->first == key)
16523             {
16524                 return it;
16525             }
16526         }
16527         return Container::end();
16528     }
16529 
findnlohmann::ordered_map16530     const_iterator find(const Key& key) const
16531     {
16532         for (auto it = this->begin(); it != this->end(); ++it)
16533         {
16534             if (it->first == key)
16535             {
16536                 return it;
16537             }
16538         }
16539         return Container::end();
16540     }
16541 
insertnlohmann::ordered_map16542     std::pair<iterator, bool> insert( value_type&& value )
16543     {
16544         return emplace(value.first, std::move(value.second));
16545     }
16546 
insertnlohmann::ordered_map16547     std::pair<iterator, bool> insert( const value_type& value )
16548     {
16549         for (auto it = this->begin(); it != this->end(); ++it)
16550         {
16551             if (it->first == value.first)
16552             {
16553                 return {it, false};
16554             }
16555         }
16556         Container::push_back(value);
16557         return {--this->end(), true};
16558     }
16559 };
16560 
16561 }  // namespace nlohmann
16562 
16563 
16564 /*!
16565 @brief namespace for Niels Lohmann
16566 @see https://github.com/nlohmann
16567 @since version 1.0.0
16568 */
16569 namespace nlohmann
16570 {
16571 
16572 /*!
16573 @brief a class to store JSON values
16574 
16575 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
16576 in @ref object_t)
16577 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
16578 in @ref array_t)
16579 @tparam StringType type for JSON strings and object keys (`std::string` by
16580 default; will be used in @ref string_t)
16581 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
16582 in @ref boolean_t)
16583 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
16584 default; will be used in @ref number_integer_t)
16585 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
16586 `uint64_t` by default; will be used in @ref number_unsigned_t)
16587 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
16588 default; will be used in @ref number_float_t)
16589 @tparam BinaryType type for packed binary data for compatibility with binary
16590 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
16591 @ref binary_t)
16592 @tparam AllocatorType type of the allocator to use (`std::allocator` by
16593 default)
16594 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
16595 and `from_json()` (@ref adl_serializer by default)
16596 
16597 @requirement The class satisfies the following concept requirements:
16598 - Basic
16599  - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
16600    JSON values can be default constructed. The result will be a JSON null
16601    value.
16602  - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
16603    A JSON value can be constructed from an rvalue argument.
16604  - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
16605    A JSON value can be copy-constructed from an lvalue expression.
16606  - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
16607    A JSON value van be assigned from an rvalue argument.
16608  - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
16609    A JSON value can be copy-assigned from an lvalue expression.
16610  - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
16611    JSON values can be destructed.
16612 - Layout
16613  - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
16614    JSON values have
16615    [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
16616    All non-static data members are private and standard layout types, the
16617    class has no virtual functions or (virtual) base classes.
16618 - Library-wide
16619  - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
16620    JSON values can be compared with `==`, see @ref
16621    operator==(const_reference,const_reference).
16622  - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
16623    JSON values can be compared with `<`, see @ref
16624    operator<(const_reference,const_reference).
16625  - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
16626    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
16627    other compatible types, using unqualified function call @ref swap().
16628  - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
16629    JSON values can be compared against `std::nullptr_t` objects which are used
16630    to model the `null` value.
16631 - Container
16632  - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
16633    JSON values can be used like STL containers and provide iterator access.
16634  - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
16635    JSON values can be used like STL containers and provide reverse iterator
16636    access.
16637 
16638 @invariant The member variables @a m_value and @a m_type have the following
16639 relationship:
16640 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
16641 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
16642 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
16643 The invariants are checked by member function assert_invariant().
16644 
16645 @internal
16646 @note ObjectType trick from https://stackoverflow.com/a/9860911
16647 @endinternal
16648 
16649 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
16650 Format](http://rfc7159.net/rfc7159)
16651 
16652 @since version 1.0.0
16653 
16654 @nosubgrouping
16655 */
16656 NLOHMANN_BASIC_JSON_TPL_DECLARATION
16657 class basic_json
16658 {
16659   private:
16660     template<detail::value_t> friend struct detail::external_constructor;
16661     friend ::nlohmann::json_pointer<basic_json>;
16662 
16663     template<typename BasicJsonType, typename InputType>
16664     friend class ::nlohmann::detail::parser;
16665     friend ::nlohmann::detail::serializer<basic_json>;
16666     template<typename BasicJsonType>
16667     friend class ::nlohmann::detail::iter_impl;
16668     template<typename BasicJsonType, typename CharType>
16669     friend class ::nlohmann::detail::binary_writer;
16670     template<typename BasicJsonType, typename InputType, typename SAX>
16671     friend class ::nlohmann::detail::binary_reader;
16672     template<typename BasicJsonType>
16673     friend class ::nlohmann::detail::json_sax_dom_parser;
16674     template<typename BasicJsonType>
16675     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16676 
16677     /// workaround type for MSVC
16678     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16679 
16680     // convenience aliases for types residing in namespace detail;
16681     using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16682 
16683     template<typename InputAdapterType>
parser(InputAdapterType adapter,detail::parser_callback_t<basic_json> cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)16684     static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16685         InputAdapterType adapter,
16686         detail::parser_callback_t<basic_json>cb = nullptr,
16687         const bool allow_exceptions = true,
16688         const bool ignore_comments = false
16689                                  )
16690     {
16691         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16692                 std::move(cb), allow_exceptions, ignore_comments);
16693     }
16694 
16695     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16696     template<typename BasicJsonType>
16697     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16698     template<typename BasicJsonType>
16699     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16700     template<typename Iterator>
16701     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16702     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16703 
16704     template<typename CharType>
16705     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16706 
16707     template<typename InputType>
16708     using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16709     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16710 
16711     using serializer = ::nlohmann::detail::serializer<basic_json>;
16712 
16713   public:
16714     using value_t = detail::value_t;
16715     /// JSON Pointer, see @ref nlohmann::json_pointer
16716     using json_pointer = ::nlohmann::json_pointer<basic_json>;
16717     template<typename T, typename SFINAE>
16718     using json_serializer = JSONSerializer<T, SFINAE>;
16719     /// how to treat decoding errors
16720     using error_handler_t = detail::error_handler_t;
16721     /// how to treat CBOR tags
16722     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16723     /// helper type for initializer lists of basic_json values
16724     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16725 
16726     using input_format_t = detail::input_format_t;
16727     /// SAX interface type, see @ref nlohmann::json_sax
16728     using json_sax_t = json_sax<basic_json>;
16729 
16730     ////////////////
16731     // exceptions //
16732     ////////////////
16733 
16734     /// @name exceptions
16735     /// Classes to implement user-defined exceptions.
16736     /// @{
16737 
16738     /// @copydoc detail::exception
16739     using exception = detail::exception;
16740     /// @copydoc detail::parse_error
16741     using parse_error = detail::parse_error;
16742     /// @copydoc detail::invalid_iterator
16743     using invalid_iterator = detail::invalid_iterator;
16744     /// @copydoc detail::type_error
16745     using type_error = detail::type_error;
16746     /// @copydoc detail::out_of_range
16747     using out_of_range = detail::out_of_range;
16748     /// @copydoc detail::other_error
16749     using other_error = detail::other_error;
16750 
16751     /// @}
16752 
16753 
16754     /////////////////////
16755     // container types //
16756     /////////////////////
16757 
16758     /// @name container types
16759     /// The canonic container types to use @ref basic_json like any other STL
16760     /// container.
16761     /// @{
16762 
16763     /// the type of elements in a basic_json container
16764     using value_type = basic_json;
16765 
16766     /// the type of an element reference
16767     using reference = value_type&;
16768     /// the type of an element const reference
16769     using const_reference = const value_type&;
16770 
16771     /// a type to represent differences between iterators
16772     using difference_type = std::ptrdiff_t;
16773     /// a type to represent container sizes
16774     using size_type = std::size_t;
16775 
16776     /// the allocator type
16777     using allocator_type = AllocatorType<basic_json>;
16778 
16779     /// the type of an element pointer
16780     using pointer = typename std::allocator_traits<allocator_type>::pointer;
16781     /// the type of an element const pointer
16782     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16783 
16784     /// an iterator for a basic_json container
16785     using iterator = iter_impl<basic_json>;
16786     /// a const iterator for a basic_json container
16787     using const_iterator = iter_impl<const basic_json>;
16788     /// a reverse iterator for a basic_json container
16789     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16790     /// a const reverse iterator for a basic_json container
16791     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16792 
16793     /// @}
16794 
16795 
16796     /*!
16797     @brief returns the allocator associated with the container
16798     */
get_allocator()16799     static allocator_type get_allocator()
16800     {
16801         return allocator_type();
16802     }
16803 
16804     /*!
16805     @brief returns version information on the library
16806 
16807     This function returns a JSON object with information about the library,
16808     including the version number and information on the platform and compiler.
16809 
16810     @return JSON object holding version information
16811     key         | description
16812     ----------- | ---------------
16813     `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).
16814     `copyright` | The copyright line for the library as string.
16815     `name`      | The name of the library as string.
16816     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
16817     `url`       | The URL of the project as string.
16818     `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).
16819 
16820     @liveexample{The following code shows an example output of the `meta()`
16821     function.,meta}
16822 
16823     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16824     changes to any JSON value.
16825 
16826     @complexity Constant.
16827 
16828     @since 2.1.0
16829     */
16830     JSON_HEDLEY_WARN_UNUSED_RESULT
meta()16831     static basic_json meta()
16832     {
16833         basic_json result;
16834 
16835         result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16836         result["name"] = "JSON for Modern C++";
16837         result["url"] = "https://github.com/nlohmann/json";
16838         result["version"]["string"] =
16839             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16840             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16841             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16842         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16843         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16844         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16845 
16846 #ifdef _WIN32
16847         result["platform"] = "win32";
16848 #elif defined __linux__
16849         result["platform"] = "linux";
16850 #elif defined __APPLE__
16851         result["platform"] = "apple";
16852 #elif defined __unix__
16853         result["platform"] = "unix";
16854 #else
16855         result["platform"] = "unknown";
16856 #endif
16857 
16858 #if defined(__ICC) || defined(__INTEL_COMPILER)
16859         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16860 #elif defined(__clang__)
16861         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16862 #elif defined(__GNUC__) || defined(__GNUG__)
16863         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16864 #elif defined(__HP_cc) || defined(__HP_aCC)
16865         result["compiler"] = "hp"
16866 #elif defined(__IBMCPP__)
16867         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16868 #elif defined(_MSC_VER)
16869         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16870 #elif defined(__PGI)
16871         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16872 #elif defined(__SUNPRO_CC)
16873         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16874 #else
16875         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16876 #endif
16877 
16878 #ifdef __cplusplus
16879         result["compiler"]["c++"] = std::to_string(__cplusplus);
16880 #else
16881         result["compiler"]["c++"] = "unknown";
16882 #endif
16883         return result;
16884     }
16885 
16886 
16887     ///////////////////////////
16888     // JSON value data types //
16889     ///////////////////////////
16890 
16891     /// @name JSON value data types
16892     /// The data types to store a JSON value. These types are derived from
16893     /// the template arguments passed to class @ref basic_json.
16894     /// @{
16895 
16896 #if defined(JSON_HAS_CPP_14)
16897     // Use transparent comparator if possible, combined with perfect forwarding
16898     // on find() and count() calls prevents unnecessary string construction.
16899     using object_comparator_t = std::less<>;
16900 #else
16901     using object_comparator_t = std::less<StringType>;
16902 #endif
16903 
16904     /*!
16905     @brief a type for an object
16906 
16907     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
16908     > An object is an unordered collection of zero or more name/value pairs,
16909     > where a name is a string and a value is a string, number, boolean, null,
16910     > object, or array.
16911 
16912     To store objects in C++, a type is defined by the template parameters
16913     described below.
16914 
16915     @tparam ObjectType  the container to store objects (e.g., `std::map` or
16916     `std::unordered_map`)
16917     @tparam StringType the type of the keys or names (e.g., `std::string`).
16918     The comparison function `std::less<StringType>` is used to order elements
16919     inside the container.
16920     @tparam AllocatorType the allocator to use for objects (e.g.,
16921     `std::allocator`)
16922 
16923     #### Default type
16924 
16925     With the default values for @a ObjectType (`std::map`), @a StringType
16926     (`std::string`), and @a AllocatorType (`std::allocator`), the default
16927     value for @a object_t is:
16928 
16929     @code {.cpp}
16930     std::map<
16931       std::string, // key_type
16932       basic_json, // value_type
16933       std::less<std::string>, // key_compare
16934       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
16935     >
16936     @endcode
16937 
16938     #### Behavior
16939 
16940     The choice of @a object_t influences the behavior of the JSON class. With
16941     the default type, objects have the following behavior:
16942 
16943     - When all names are unique, objects will be interoperable in the sense
16944       that all software implementations receiving that object will agree on
16945       the name-value mappings.
16946     - When the names within an object are not unique, it is unspecified which
16947       one of the values for a given key will be chosen. For instance,
16948       `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
16949       `{"key": 2}`.
16950     - Internally, name/value pairs are stored in lexicographical order of the
16951       names. Objects will also be serialized (see @ref dump) in this order.
16952       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
16953       and serialized as `{"a": 2, "b": 1}`.
16954     - When comparing objects, the order of the name/value pairs is irrelevant.
16955       This makes objects interoperable in the sense that they will not be
16956       affected by these differences. For instance, `{"b": 1, "a": 2}` and
16957       `{"a": 2, "b": 1}` will be treated as equal.
16958 
16959     #### Limits
16960 
16961     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
16962     > An implementation may set limits on the maximum depth of nesting.
16963 
16964     In this class, the object's limit of nesting is not explicitly constrained.
16965     However, a maximum depth of nesting may be introduced by the compiler or
16966     runtime environment. A theoretical limit can be queried by calling the
16967     @ref max_size function of a JSON object.
16968 
16969     #### Storage
16970 
16971     Objects are stored as pointers in a @ref basic_json type. That is, for any
16972     access to object values, a pointer of type `object_t*` must be
16973     dereferenced.
16974 
16975     @sa @ref array_t -- type for an array value
16976 
16977     @since version 1.0.0
16978 
16979     @note The order name/value pairs are added to the object is *not*
16980     preserved by the library. Therefore, iterating an object may return
16981     name/value pairs in a different order than they were originally stored. In
16982     fact, keys will be traversed in alphabetical order as `std::map` with
16983     `std::less` is used by default. Please note this behavior conforms to [RFC
16984     7159](http://rfc7159.net/rfc7159), because any order implements the
16985     specified "unordered" nature of JSON objects.
16986     */
16987     using object_t = ObjectType<StringType,
16988           basic_json,
16989           object_comparator_t,
16990           AllocatorType<std::pair<const StringType,
16991           basic_json>>>;
16992 
16993     /*!
16994     @brief a type for an array
16995 
16996     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
16997     > An array is an ordered sequence of zero or more values.
16998 
16999     To store objects in C++, a type is defined by the template parameters
17000     explained below.
17001 
17002     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
17003     `std::list`)
17004     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
17005 
17006     #### Default type
17007 
17008     With the default values for @a ArrayType (`std::vector`) and @a
17009     AllocatorType (`std::allocator`), the default value for @a array_t is:
17010 
17011     @code {.cpp}
17012     std::vector<
17013       basic_json, // value_type
17014       std::allocator<basic_json> // allocator_type
17015     >
17016     @endcode
17017 
17018     #### Limits
17019 
17020     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17021     > An implementation may set limits on the maximum depth of nesting.
17022 
17023     In this class, the array's limit of nesting is not explicitly constrained.
17024     However, a maximum depth of nesting may be introduced by the compiler or
17025     runtime environment. A theoretical limit can be queried by calling the
17026     @ref max_size function of a JSON array.
17027 
17028     #### Storage
17029 
17030     Arrays are stored as pointers in a @ref basic_json type. That is, for any
17031     access to array values, a pointer of type `array_t*` must be dereferenced.
17032 
17033     @sa @ref object_t -- type for an object value
17034 
17035     @since version 1.0.0
17036     */
17037     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17038 
17039     /*!
17040     @brief a type for a string
17041 
17042     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
17043     > A string is a sequence of zero or more Unicode characters.
17044 
17045     To store objects in C++, a type is defined by the template parameter
17046     described below. Unicode values are split by the JSON class into
17047     byte-sized characters during deserialization.
17048 
17049     @tparam StringType  the container to store strings (e.g., `std::string`).
17050     Note this container is used for keys/names in objects, see @ref object_t.
17051 
17052     #### Default type
17053 
17054     With the default values for @a StringType (`std::string`), the default
17055     value for @a string_t is:
17056 
17057     @code {.cpp}
17058     std::string
17059     @endcode
17060 
17061     #### Encoding
17062 
17063     Strings are stored in UTF-8 encoding. Therefore, functions like
17064     `std::string::size()` or `std::string::length()` return the number of
17065     bytes in the string rather than the number of characters or glyphs.
17066 
17067     #### String comparison
17068 
17069     [RFC 7159](http://rfc7159.net/rfc7159) states:
17070     > Software implementations are typically required to test names of object
17071     > members for equality. Implementations that transform the textual
17072     > representation into sequences of Unicode code units and then perform the
17073     > comparison numerically, code unit by code unit, are interoperable in the
17074     > sense that implementations will agree in all cases on equality or
17075     > inequality of two strings. For example, implementations that compare
17076     > strings with escaped characters unconverted may incorrectly find that
17077     > `"a\\b"` and `"a\u005Cb"` are not equal.
17078 
17079     This implementation is interoperable as it does compare strings code unit
17080     by code unit.
17081 
17082     #### Storage
17083 
17084     String values are stored as pointers in a @ref basic_json type. That is,
17085     for any access to string values, a pointer of type `string_t*` must be
17086     dereferenced.
17087 
17088     @since version 1.0.0
17089     */
17090     using string_t = StringType;
17091 
17092     /*!
17093     @brief a type for a boolean
17094 
17095     [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
17096     type which differentiates the two literals `true` and `false`.
17097 
17098     To store objects in C++, a type is defined by the template parameter @a
17099     BooleanType which chooses the type to use.
17100 
17101     #### Default type
17102 
17103     With the default values for @a BooleanType (`bool`), the default value for
17104     @a boolean_t is:
17105 
17106     @code {.cpp}
17107     bool
17108     @endcode
17109 
17110     #### Storage
17111 
17112     Boolean values are stored directly inside a @ref basic_json type.
17113 
17114     @since version 1.0.0
17115     */
17116     using boolean_t = BooleanType;
17117 
17118     /*!
17119     @brief a type for a number (integer)
17120 
17121     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17122     > The representation of numbers is similar to that used in most
17123     > programming languages. A number is represented in base 10 using decimal
17124     > digits. It contains an integer component that may be prefixed with an
17125     > optional minus sign, which may be followed by a fraction part and/or an
17126     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17127     > cannot be represented in the grammar below (such as Infinity and NaN)
17128     > are not permitted.
17129 
17130     This description includes both integer and floating-point numbers.
17131     However, C++ allows more precise storage if it is known whether the number
17132     is a signed integer, an unsigned integer or a floating-point number.
17133     Therefore, three different types, @ref number_integer_t, @ref
17134     number_unsigned_t and @ref number_float_t are used.
17135 
17136     To store integer numbers in C++, a type is defined by the template
17137     parameter @a NumberIntegerType which chooses the type to use.
17138 
17139     #### Default type
17140 
17141     With the default values for @a NumberIntegerType (`int64_t`), the default
17142     value for @a number_integer_t is:
17143 
17144     @code {.cpp}
17145     int64_t
17146     @endcode
17147 
17148     #### Default behavior
17149 
17150     - The restrictions about leading zeros is not enforced in C++. Instead,
17151       leading zeros in integer literals lead to an interpretation as octal
17152       number. Internally, the value will be stored as decimal number. For
17153       instance, the C++ integer literal `010` will be serialized to `8`.
17154       During deserialization, leading zeros yield an error.
17155     - Not-a-number (NaN) values will be serialized to `null`.
17156 
17157     #### Limits
17158 
17159     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17160     > An implementation may set limits on the range and precision of numbers.
17161 
17162     When the default type is used, the maximal integer number that can be
17163     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
17164     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
17165     that are out of range will yield over/underflow when used in a
17166     constructor. During deserialization, too large or small integer numbers
17167     will be automatically be stored as @ref number_unsigned_t or @ref
17168     number_float_t.
17169 
17170     [RFC 7159](http://rfc7159.net/rfc7159) further states:
17171     > Note that when such software is used, numbers that are integers and are
17172     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17173     > that implementations will agree exactly on their numeric values.
17174 
17175     As this range is a subrange of the exactly supported range [INT64_MIN,
17176     INT64_MAX], this class's integer type is interoperable.
17177 
17178     #### Storage
17179 
17180     Integer number values are stored directly inside a @ref basic_json type.
17181 
17182     @sa @ref number_float_t -- type for number values (floating-point)
17183 
17184     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17185 
17186     @since version 1.0.0
17187     */
17188     using number_integer_t = NumberIntegerType;
17189 
17190     /*!
17191     @brief a type for a number (unsigned)
17192 
17193     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17194     > The representation of numbers is similar to that used in most
17195     > programming languages. A number is represented in base 10 using decimal
17196     > digits. It contains an integer component that may be prefixed with an
17197     > optional minus sign, which may be followed by a fraction part and/or an
17198     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17199     > cannot be represented in the grammar below (such as Infinity and NaN)
17200     > are not permitted.
17201 
17202     This description includes both integer and floating-point numbers.
17203     However, C++ allows more precise storage if it is known whether the number
17204     is a signed integer, an unsigned integer or a floating-point number.
17205     Therefore, three different types, @ref number_integer_t, @ref
17206     number_unsigned_t and @ref number_float_t are used.
17207 
17208     To store unsigned integer numbers in C++, a type is defined by the
17209     template parameter @a NumberUnsignedType which chooses the type to use.
17210 
17211     #### Default type
17212 
17213     With the default values for @a NumberUnsignedType (`uint64_t`), the
17214     default value for @a number_unsigned_t is:
17215 
17216     @code {.cpp}
17217     uint64_t
17218     @endcode
17219 
17220     #### Default behavior
17221 
17222     - The restrictions about leading zeros is not enforced in C++. Instead,
17223       leading zeros in integer literals lead to an interpretation as octal
17224       number. Internally, the value will be stored as decimal number. For
17225       instance, the C++ integer literal `010` will be serialized to `8`.
17226       During deserialization, leading zeros yield an error.
17227     - Not-a-number (NaN) values will be serialized to `null`.
17228 
17229     #### Limits
17230 
17231     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17232     > An implementation may set limits on the range and precision of numbers.
17233 
17234     When the default type is used, the maximal integer number that can be
17235     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
17236     number that can be stored is `0`. Integer numbers that are out of range
17237     will yield over/underflow when used in a constructor. During
17238     deserialization, too large or small integer numbers will be automatically
17239     be stored as @ref number_integer_t or @ref number_float_t.
17240 
17241     [RFC 7159](http://rfc7159.net/rfc7159) further states:
17242     > Note that when such software is used, numbers that are integers and are
17243     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17244     > that implementations will agree exactly on their numeric values.
17245 
17246     As this range is a subrange (when considered in conjunction with the
17247     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
17248     this class's integer type is interoperable.
17249 
17250     #### Storage
17251 
17252     Integer number values are stored directly inside a @ref basic_json type.
17253 
17254     @sa @ref number_float_t -- type for number values (floating-point)
17255     @sa @ref number_integer_t -- type for number values (integer)
17256 
17257     @since version 2.0.0
17258     */
17259     using number_unsigned_t = NumberUnsignedType;
17260 
17261     /*!
17262     @brief a type for a number (floating-point)
17263 
17264     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17265     > The representation of numbers is similar to that used in most
17266     > programming languages. A number is represented in base 10 using decimal
17267     > digits. It contains an integer component that may be prefixed with an
17268     > optional minus sign, which may be followed by a fraction part and/or an
17269     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17270     > cannot be represented in the grammar below (such as Infinity and NaN)
17271     > are not permitted.
17272 
17273     This description includes both integer and floating-point numbers.
17274     However, C++ allows more precise storage if it is known whether the number
17275     is a signed integer, an unsigned integer or a floating-point number.
17276     Therefore, three different types, @ref number_integer_t, @ref
17277     number_unsigned_t and @ref number_float_t are used.
17278 
17279     To store floating-point numbers in C++, a type is defined by the template
17280     parameter @a NumberFloatType which chooses the type to use.
17281 
17282     #### Default type
17283 
17284     With the default values for @a NumberFloatType (`double`), the default
17285     value for @a number_float_t is:
17286 
17287     @code {.cpp}
17288     double
17289     @endcode
17290 
17291     #### Default behavior
17292 
17293     - The restrictions about leading zeros is not enforced in C++. Instead,
17294       leading zeros in floating-point literals will be ignored. Internally,
17295       the value will be stored as decimal number. For instance, the C++
17296       floating-point literal `01.2` will be serialized to `1.2`. During
17297       deserialization, leading zeros yield an error.
17298     - Not-a-number (NaN) values will be serialized to `null`.
17299 
17300     #### Limits
17301 
17302     [RFC 7159](http://rfc7159.net/rfc7159) states:
17303     > This specification allows implementations to set limits on the range and
17304     > precision of numbers accepted. Since software that implements IEEE
17305     > 754-2008 binary64 (double precision) numbers is generally available and
17306     > widely used, good interoperability can be achieved by implementations
17307     > that expect no more precision or range than these provide, in the sense
17308     > that implementations will approximate JSON numbers within the expected
17309     > precision.
17310 
17311     This implementation does exactly follow this approach, as it uses double
17312     precision floating-point numbers. Note values smaller than
17313     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
17314     will be stored as NaN internally and be serialized to `null`.
17315 
17316     #### Storage
17317 
17318     Floating-point number values are stored directly inside a @ref basic_json
17319     type.
17320 
17321     @sa @ref number_integer_t -- type for number values (integer)
17322 
17323     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17324 
17325     @since version 1.0.0
17326     */
17327     using number_float_t = NumberFloatType;
17328 
17329     /*!
17330     @brief a type for a packed binary type
17331 
17332     This type is a type designed to carry binary data that appears in various
17333     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
17334     BSON's generic binary subtype. This type is NOT a part of standard JSON and
17335     exists solely for compatibility with these binary types. As such, it is
17336     simply defined as an ordered sequence of zero or more byte values.
17337 
17338     Additionally, as an implementation detail, the subtype of the binary data is
17339     carried around as a `std::uint8_t`, which is compatible with both of the
17340     binary data formats that use binary subtyping, (though the specific
17341     numbering is incompatible with each other, and it is up to the user to
17342     translate between them).
17343 
17344     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
17345     as:
17346     > Major type 2: a byte string. The string's length in bytes is represented
17347     > following the rules for positive integers (major type 0).
17348 
17349     [MessagePack's documentation on the bin type
17350     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
17351     describes this type as:
17352     > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
17353     > in addition to the size of the byte array.
17354 
17355     [BSON's specifications](http://bsonspec.org/spec.html) describe several
17356     binary types; however, this type is intended to represent the generic binary
17357     type which has the description:
17358     > Generic binary subtype - This is the most commonly used binary subtype and
17359     > should be the 'default' for drivers and tools.
17360 
17361     None of these impose any limitations on the internal representation other
17362     than the basic unit of storage be some type of array whose parts are
17363     decomposable into bytes.
17364 
17365     The default representation of this binary format is a
17366     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
17367     array in modern C++.
17368 
17369     #### Default type
17370 
17371     The default values for @a BinaryType is `std::vector<std::uint8_t>`
17372 
17373     #### Storage
17374 
17375     Binary Arrays are stored as pointers in a @ref basic_json type. That is,
17376     for any access to array values, a pointer of the type `binary_t*` must be
17377     dereferenced.
17378 
17379     #### Notes on subtypes
17380 
17381     - CBOR
17382        - Binary values are represented as byte strings. No subtypes are
17383          supported and will be ignored when CBOR is written.
17384     - MessagePack
17385        - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
17386          or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
17387          is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
17388          The subtype is then added as singed 8-bit integer.
17389        - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
17390     - BSON
17391        - If a subtype is given, it is used and added as unsigned 8-bit integer.
17392        - If no subtype is given, the generic binary subtype 0x00 is used.
17393 
17394     @sa @ref binary -- create a binary array
17395 
17396     @since version 3.8.0
17397     */
17398     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17399     /// @}
17400 
17401   private:
17402 
17403     /// helper for exception-safe object creation
17404     template<typename T, typename... Args>
17405     JSON_HEDLEY_RETURNS_NON_NULL
create(Args &&...args)17406     static T* create(Args&& ... args)
17407     {
17408         AllocatorType<T> alloc;
17409         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17410 
17411         auto deleter = [&](T * object)
17412         {
17413             AllocatorTraits::deallocate(alloc, object, 1);
17414         };
17415         std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17416         AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17417         JSON_ASSERT(object != nullptr);
17418         return object.release();
17419     }
17420 
17421     ////////////////////////
17422     // JSON value storage //
17423     ////////////////////////
17424 
17425     /*!
17426     @brief a JSON value
17427 
17428     The actual storage for a JSON value of the @ref basic_json class. This
17429     union combines the different storage types for the JSON value types
17430     defined in @ref value_t.
17431 
17432     JSON type | value_t type    | used type
17433     --------- | --------------- | ------------------------
17434     object    | object          | pointer to @ref object_t
17435     array     | array           | pointer to @ref array_t
17436     string    | string          | pointer to @ref string_t
17437     boolean   | boolean         | @ref boolean_t
17438     number    | number_integer  | @ref number_integer_t
17439     number    | number_unsigned | @ref number_unsigned_t
17440     number    | number_float    | @ref number_float_t
17441     binary    | binary          | pointer to @ref binary_t
17442     null      | null            | *no value is stored*
17443 
17444     @note Variable-length types (objects, arrays, and strings) are stored as
17445     pointers. The size of the union should not exceed 64 bits if the default
17446     value types are used.
17447 
17448     @since version 1.0.0
17449     */
17450     union json_value
17451     {
17452         /// object (stored with pointer to save storage)
17453         object_t* object;
17454         /// array (stored with pointer to save storage)
17455         array_t* array;
17456         /// string (stored with pointer to save storage)
17457         string_t* string;
17458         /// binary (stored with pointer to save storage)
17459         binary_t* binary;
17460         /// boolean
17461         boolean_t boolean;
17462         /// number (integer)
17463         number_integer_t number_integer;
17464         /// number (unsigned integer)
17465         number_unsigned_t number_unsigned;
17466         /// number (floating-point)
17467         number_float_t number_float;
17468 
17469         /// default constructor (for null values)
17470         json_value() = default;
17471         /// constructor for booleans
json_value(boolean_t v)17472         json_value(boolean_t v) noexcept : boolean(v) {}
17473         /// constructor for numbers (integer)
json_value(number_integer_t v)17474         json_value(number_integer_t v) noexcept : number_integer(v) {}
17475         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)17476         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17477         /// constructor for numbers (floating-point)
json_value(number_float_t v)17478         json_value(number_float_t v) noexcept : number_float(v) {}
17479         /// constructor for empty values of a given type
json_value(value_t t)17480         json_value(value_t t)
17481         {
17482             switch (t)
17483             {
17484                 case value_t::object:
17485                 {
17486                     object = create<object_t>();
17487                     break;
17488                 }
17489 
17490                 case value_t::array:
17491                 {
17492                     array = create<array_t>();
17493                     break;
17494                 }
17495 
17496                 case value_t::string:
17497                 {
17498                     string = create<string_t>("");
17499                     break;
17500                 }
17501 
17502                 case value_t::binary:
17503                 {
17504                     binary = create<binary_t>();
17505                     break;
17506                 }
17507 
17508                 case value_t::boolean:
17509                 {
17510                     boolean = boolean_t(false);
17511                     break;
17512                 }
17513 
17514                 case value_t::number_integer:
17515                 {
17516                     number_integer = number_integer_t(0);
17517                     break;
17518                 }
17519 
17520                 case value_t::number_unsigned:
17521                 {
17522                     number_unsigned = number_unsigned_t(0);
17523                     break;
17524                 }
17525 
17526                 case value_t::number_float:
17527                 {
17528                     number_float = number_float_t(0.0);
17529                     break;
17530                 }
17531 
17532                 case value_t::null:
17533                 {
17534                     object = nullptr;  // silence warning, see #821
17535                     break;
17536                 }
17537 
17538                 default:
17539                 {
17540                     object = nullptr;  // silence warning, see #821
17541                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17542                     {
17543                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17544                     }
17545                     break;
17546                 }
17547             }
17548         }
17549 
17550         /// constructor for strings
json_value(const string_t & value)17551         json_value(const string_t& value)
17552         {
17553             string = create<string_t>(value);
17554         }
17555 
17556         /// constructor for rvalue strings
json_value(string_t && value)17557         json_value(string_t&& value)
17558         {
17559             string = create<string_t>(std::move(value));
17560         }
17561 
17562         /// constructor for objects
json_value(const object_t & value)17563         json_value(const object_t& value)
17564         {
17565             object = create<object_t>(value);
17566         }
17567 
17568         /// constructor for rvalue objects
json_value(object_t && value)17569         json_value(object_t&& value)
17570         {
17571             object = create<object_t>(std::move(value));
17572         }
17573 
17574         /// constructor for arrays
json_value(const array_t & value)17575         json_value(const array_t& value)
17576         {
17577             array = create<array_t>(value);
17578         }
17579 
17580         /// constructor for rvalue arrays
json_value(array_t && value)17581         json_value(array_t&& value)
17582         {
17583             array = create<array_t>(std::move(value));
17584         }
17585 
17586         /// constructor for binary arrays
json_value(const typename binary_t::container_type & value)17587         json_value(const typename binary_t::container_type& value)
17588         {
17589             binary = create<binary_t>(value);
17590         }
17591 
17592         /// constructor for rvalue binary arrays
json_value(typename binary_t::container_type && value)17593         json_value(typename binary_t::container_type&& value)
17594         {
17595             binary = create<binary_t>(std::move(value));
17596         }
17597 
17598         /// constructor for binary arrays (internal type)
json_value(const binary_t & value)17599         json_value(const binary_t& value)
17600         {
17601             binary = create<binary_t>(value);
17602         }
17603 
17604         /// constructor for rvalue binary arrays (internal type)
json_value(binary_t && value)17605         json_value(binary_t&& value)
17606         {
17607             binary = create<binary_t>(std::move(value));
17608         }
17609 
destroy(value_t t)17610         void destroy(value_t t) noexcept
17611         {
17612             // flatten the current json_value to a heap-allocated stack
17613             std::vector<basic_json> stack;
17614 
17615             // move the top-level items to stack
17616             if (t == value_t::array)
17617             {
17618                 stack.reserve(array->size());
17619                 std::move(array->begin(), array->end(), std::back_inserter(stack));
17620             }
17621             else if (t == value_t::object)
17622             {
17623                 stack.reserve(object->size());
17624                 for (auto&& it : *object)
17625                 {
17626                     stack.push_back(std::move(it.second));
17627                 }
17628             }
17629 
17630             while (!stack.empty())
17631             {
17632                 // move the last item to local variable to be processed
17633                 basic_json current_item(std::move(stack.back()));
17634                 stack.pop_back();
17635 
17636                 // if current_item is array/object, move
17637                 // its children to the stack to be processed later
17638                 if (current_item.is_array())
17639                 {
17640                     std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17641                               std::back_inserter(stack));
17642 
17643                     current_item.m_value.array->clear();
17644                 }
17645                 else if (current_item.is_object())
17646                 {
17647                     for (auto&& it : *current_item.m_value.object)
17648                     {
17649                         stack.push_back(std::move(it.second));
17650                     }
17651 
17652                     current_item.m_value.object->clear();
17653                 }
17654 
17655                 // it's now safe that current_item get destructed
17656                 // since it doesn't have any children
17657             }
17658 
17659             switch (t)
17660             {
17661                 case value_t::object:
17662                 {
17663                     AllocatorType<object_t> alloc;
17664                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17665                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17666                     break;
17667                 }
17668 
17669                 case value_t::array:
17670                 {
17671                     AllocatorType<array_t> alloc;
17672                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17673                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17674                     break;
17675                 }
17676 
17677                 case value_t::string:
17678                 {
17679                     AllocatorType<string_t> alloc;
17680                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17681                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17682                     break;
17683                 }
17684 
17685                 case value_t::binary:
17686                 {
17687                     AllocatorType<binary_t> alloc;
17688                     std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17689                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17690                     break;
17691                 }
17692 
17693                 default:
17694                 {
17695                     break;
17696                 }
17697             }
17698         }
17699     };
17700 
17701     /*!
17702     @brief checks the class invariants
17703 
17704     This function asserts the class invariants. It needs to be called at the
17705     end of every constructor to make sure that created objects respect the
17706     invariant. Furthermore, it has to be called each time the type of a JSON
17707     value is changed, because the invariant expresses a relationship between
17708     @a m_type and @a m_value.
17709     */
assert_invariant() const17710     void assert_invariant() const noexcept
17711     {
17712         JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17713         JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17714         JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17715         JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17716     }
17717 
17718   public:
17719     //////////////////////////
17720     // JSON parser callback //
17721     //////////////////////////
17722 
17723     /*!
17724     @brief parser event types
17725 
17726     The parser callback distinguishes the following events:
17727     - `object_start`: the parser read `{` and started to process a JSON object
17728     - `key`: the parser read a key of a value in an object
17729     - `object_end`: the parser read `}` and finished processing a JSON object
17730     - `array_start`: the parser read `[` and started to process a JSON array
17731     - `array_end`: the parser read `]` and finished processing a JSON array
17732     - `value`: the parser finished reading a JSON value
17733 
17734     @image html callback_events.png "Example when certain parse events are triggered"
17735 
17736     @sa @ref parser_callback_t for more information and examples
17737     */
17738     using parse_event_t = detail::parse_event_t;
17739 
17740     /*!
17741     @brief per-element parser callback type
17742 
17743     With a parser callback function, the result of parsing a JSON text can be
17744     influenced. When passed to @ref parse, it is called on certain events
17745     (passed as @ref parse_event_t via parameter @a event) with a set recursion
17746     depth @a depth and context JSON value @a parsed. The return value of the
17747     callback function is a boolean indicating whether the element that emitted
17748     the callback shall be kept or not.
17749 
17750     We distinguish six scenarios (determined by the event type) in which the
17751     callback function can be called. The following table describes the values
17752     of the parameters @a depth, @a event, and @a parsed.
17753 
17754     parameter @a event | description | parameter @a depth | parameter @a parsed
17755     ------------------ | ----------- | ------------------ | -------------------
17756     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
17757     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
17758     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
17759     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
17760     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
17761     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
17762 
17763     @image html callback_events.png "Example when certain parse events are triggered"
17764 
17765     Discarding a value (i.e., returning `false`) has different effects
17766     depending on the context in which function was called:
17767 
17768     - Discarded values in structured types are skipped. That is, the parser
17769       will behave as if the discarded value was never read.
17770     - In case a value outside a structured type is skipped, it is replaced
17771       with `null`. This case happens if the top-level element is skipped.
17772 
17773     @param[in] depth  the depth of the recursion during parsing
17774 
17775     @param[in] event  an event of type parse_event_t indicating the context in
17776     the callback function has been called
17777 
17778     @param[in,out] parsed  the current intermediate parse result; note that
17779     writing to this value has no effect for parse_event_t::key events
17780 
17781     @return Whether the JSON value which called the function during parsing
17782     should be kept (`true`) or not (`false`). In the latter case, it is either
17783     skipped completely or replaced by an empty discarded object.
17784 
17785     @sa @ref parse for examples
17786 
17787     @since version 1.0.0
17788     */
17789     using parser_callback_t = detail::parser_callback_t<basic_json>;
17790 
17791     //////////////////
17792     // constructors //
17793     //////////////////
17794 
17795     /// @name constructors and destructors
17796     /// Constructors of class @ref basic_json, copy/move constructor, copy
17797     /// assignment, static functions creating objects, and the destructor.
17798     /// @{
17799 
17800     /*!
17801     @brief create an empty value with a given type
17802 
17803     Create an empty JSON value with a given type. The value will be default
17804     initialized with an empty value which depends on the type:
17805 
17806     Value type  | initial value
17807     ----------- | -------------
17808     null        | `null`
17809     boolean     | `false`
17810     string      | `""`
17811     number      | `0`
17812     object      | `{}`
17813     array       | `[]`
17814     binary      | empty array
17815 
17816     @param[in] v  the type of the value to create
17817 
17818     @complexity Constant.
17819 
17820     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17821     changes to any JSON value.
17822 
17823     @liveexample{The following code shows the constructor for different @ref
17824     value_t values,basic_json__value_t}
17825 
17826     @sa @ref clear() -- restores the postcondition of this constructor
17827 
17828     @since version 1.0.0
17829     */
basic_json(const value_t v)17830     basic_json(const value_t v)
17831         : m_type(v), m_value(v)
17832     {
17833         assert_invariant();
17834     }
17835 
17836     /*!
17837     @brief create a null object
17838 
17839     Create a `null` JSON value. It either takes a null pointer as parameter
17840     (explicitly creating `null`) or no parameter (implicitly creating `null`).
17841     The passed null pointer itself is not read -- it is only used to choose
17842     the right constructor.
17843 
17844     @complexity Constant.
17845 
17846     @exceptionsafety No-throw guarantee: this constructor never throws
17847     exceptions.
17848 
17849     @liveexample{The following code shows the constructor with and without a
17850     null pointer parameter.,basic_json__nullptr_t}
17851 
17852     @since version 1.0.0
17853     */
basic_json(std::nullptr_t=nullptr)17854     basic_json(std::nullptr_t = nullptr) noexcept
17855         : basic_json(value_t::null)
17856     {
17857         assert_invariant();
17858     }
17859 
17860     /*!
17861     @brief create a JSON value
17862 
17863     This is a "catch all" constructor for all compatible JSON types; that is,
17864     types for which a `to_json()` method exists. The constructor forwards the
17865     parameter @a val to that method (to `json_serializer<U>::to_json` method
17866     with `U = uncvref_t<CompatibleType>`, to be exact).
17867 
17868     Template type @a CompatibleType includes, but is not limited to, the
17869     following types:
17870     - **arrays**: @ref array_t and all kinds of compatible containers such as
17871       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
17872       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
17873       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
17874       which a @ref basic_json value can be constructed.
17875     - **objects**: @ref object_t and all kinds of compatible associative
17876       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
17877       and `std::unordered_multimap` with a `key_type` compatible to
17878       @ref string_t and a `value_type` from which a @ref basic_json value can
17879       be constructed.
17880     - **strings**: @ref string_t, string literals, and all compatible string
17881       containers can be used.
17882     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
17883       @ref number_float_t, and all convertible number types such as `int`,
17884       `size_t`, `int64_t`, `float` or `double` can be used.
17885     - **boolean**: @ref boolean_t / `bool` can be used.
17886     - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
17887       unfortunately because string literals cannot be distinguished from binary
17888       character arrays by the C++ type system, all types compatible with `const
17889       char*` will be directed to the string constructor instead.  This is both
17890       for backwards compatibility, and due to the fact that a binary type is not
17891       a standard JSON type.
17892 
17893     See the examples below.
17894 
17895     @tparam CompatibleType a type such that:
17896     - @a CompatibleType is not derived from `std::istream`,
17897     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
17898          constructors),
17899     - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
17900     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
17901          @ref json_pointer, @ref iterator, etc ...)
17902     - @ref @ref json_serializer<U> has a
17903          `to_json(basic_json_t&, CompatibleType&&)` method
17904 
17905     @tparam U = `uncvref_t<CompatibleType>`
17906 
17907     @param[in] val the value to be forwarded to the respective constructor
17908 
17909     @complexity Usually linear in the size of the passed @a val, also
17910                 depending on the implementation of the called `to_json()`
17911                 method.
17912 
17913     @exceptionsafety Depends on the called constructor. For types directly
17914     supported by the library (i.e., all types for which no `to_json()` function
17915     was provided), strong guarantee holds: if an exception is thrown, there are
17916     no changes to any JSON value.
17917 
17918     @liveexample{The following code shows the constructor with several
17919     compatible types.,basic_json__CompatibleType}
17920 
17921     @since version 2.1.0
17922     */
17923     template < typename CompatibleType,
17924                typename U = detail::uncvref_t<CompatibleType>,
17925                detail::enable_if_t <
17926                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val)17927     basic_json(CompatibleType && val) noexcept(noexcept(
17928                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17929                                            std::forward<CompatibleType>(val))))
17930     {
17931         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17932         assert_invariant();
17933     }
17934 
17935     /*!
17936     @brief create a JSON value from an existing one
17937 
17938     This is a constructor for existing @ref basic_json types.
17939     It does not hijack copy/move constructors, since the parameter has different
17940     template arguments than the current ones.
17941 
17942     The constructor tries to convert the internal @ref m_value of the parameter.
17943 
17944     @tparam BasicJsonType a type such that:
17945     - @a BasicJsonType is a @ref basic_json type.
17946     - @a BasicJsonType has different template arguments than @ref basic_json_t.
17947 
17948     @param[in] val the @ref basic_json value to be converted.
17949 
17950     @complexity Usually linear in the size of the passed @a val, also
17951                 depending on the implementation of the called `to_json()`
17952                 method.
17953 
17954     @exceptionsafety Depends on the called constructor. For types directly
17955     supported by the library (i.e., all types for which no `to_json()` function
17956     was provided), strong guarantee holds: if an exception is thrown, there are
17957     no changes to any JSON value.
17958 
17959     @since version 3.2.0
17960     */
17961     template < typename BasicJsonType,
17962                detail::enable_if_t <
17963                    detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType & val)17964     basic_json(const BasicJsonType& val)
17965     {
17966         using other_boolean_t = typename BasicJsonType::boolean_t;
17967         using other_number_float_t = typename BasicJsonType::number_float_t;
17968         using other_number_integer_t = typename BasicJsonType::number_integer_t;
17969         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17970         using other_string_t = typename BasicJsonType::string_t;
17971         using other_object_t = typename BasicJsonType::object_t;
17972         using other_array_t = typename BasicJsonType::array_t;
17973         using other_binary_t = typename BasicJsonType::binary_t;
17974 
17975         switch (val.type())
17976         {
17977             case value_t::boolean:
17978                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
17979                 break;
17980             case value_t::number_float:
17981                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
17982                 break;
17983             case value_t::number_integer:
17984                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
17985                 break;
17986             case value_t::number_unsigned:
17987                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
17988                 break;
17989             case value_t::string:
17990                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
17991                 break;
17992             case value_t::object:
17993                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
17994                 break;
17995             case value_t::array:
17996                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
17997                 break;
17998             case value_t::binary:
17999                 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18000                 break;
18001             case value_t::null:
18002                 *this = nullptr;
18003                 break;
18004             case value_t::discarded:
18005                 m_type = value_t::discarded;
18006                 break;
18007             default:            // LCOV_EXCL_LINE
18008                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
18009         }
18010         assert_invariant();
18011     }
18012 
18013     /*!
18014     @brief create a container (array or object) from an initializer list
18015 
18016     Creates a JSON value of type array or object from the passed initializer
18017     list @a init. In case @a type_deduction is `true` (default), the type of
18018     the JSON value to be created is deducted from the initializer list @a init
18019     according to the following rules:
18020 
18021     1. If the list is empty, an empty JSON object value `{}` is created.
18022     2. If the list consists of pairs whose first element is a string, a JSON
18023        object value is created where the first elements of the pairs are
18024        treated as keys and the second elements are as values.
18025     3. In all other cases, an array is created.
18026 
18027     The rules aim to create the best fit between a C++ initializer list and
18028     JSON values. The rationale is as follows:
18029 
18030     1. The empty initializer list is written as `{}` which is exactly an empty
18031        JSON object.
18032     2. C++ has no way of describing mapped types other than to list a list of
18033        pairs. As JSON requires that keys must be of type string, rule 2 is the
18034        weakest constraint one can pose on initializer lists to interpret them
18035        as an object.
18036     3. In all other cases, the initializer list could not be interpreted as
18037        JSON object type, so interpreting it as JSON array type is safe.
18038 
18039     With the rules described above, the following JSON values cannot be
18040     expressed by an initializer list:
18041 
18042     - the empty array (`[]`): use @ref array(initializer_list_t)
18043       with an empty initializer list in this case
18044     - arrays whose elements satisfy rule 2: use @ref
18045       array(initializer_list_t) with the same initializer list
18046       in this case
18047 
18048     @note When used without parentheses around an empty initializer list, @ref
18049     basic_json() is called instead of this function, yielding the JSON null
18050     value.
18051 
18052     @param[in] init  initializer list with JSON values
18053 
18054     @param[in] type_deduction internal parameter; when set to `true`, the type
18055     of the JSON value is deducted from the initializer list @a init; when set
18056     to `false`, the type provided via @a manual_type is forced. This mode is
18057     used by the functions @ref array(initializer_list_t) and
18058     @ref object(initializer_list_t).
18059 
18060     @param[in] manual_type internal parameter; when @a type_deduction is set
18061     to `false`, the created JSON value will use the provided type (only @ref
18062     value_t::array and @ref value_t::object are valid); when @a type_deduction
18063     is set to `true`, this parameter has no effect
18064 
18065     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
18066     `value_t::object`, but @a init contains an element which is not a pair
18067     whose first element is a string. In this case, the constructor could not
18068     create an object. If @a type_deduction would have be `true`, an array
18069     would have been created. See @ref object(initializer_list_t)
18070     for an example.
18071 
18072     @complexity Linear in the size of the initializer list @a init.
18073 
18074     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18075     changes to any JSON value.
18076 
18077     @liveexample{The example below shows how JSON values are created from
18078     initializer lists.,basic_json__list_init_t}
18079 
18080     @sa @ref array(initializer_list_t) -- create a JSON array
18081     value from an initializer list
18082     @sa @ref object(initializer_list_t) -- create a JSON object
18083     value from an initializer list
18084 
18085     @since version 1.0.0
18086     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)18087     basic_json(initializer_list_t init,
18088                bool type_deduction = true,
18089                value_t manual_type = value_t::array)
18090     {
18091         // check if each element is an array with two elements whose first
18092         // element is a string
18093         bool is_an_object = std::all_of(init.begin(), init.end(),
18094                                         [](const detail::json_ref<basic_json>& element_ref)
18095         {
18096             return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18097         });
18098 
18099         // adjust type if type deduction is not wanted
18100         if (!type_deduction)
18101         {
18102             // if array is wanted, do not create an object though possible
18103             if (manual_type == value_t::array)
18104             {
18105                 is_an_object = false;
18106             }
18107 
18108             // if object is wanted but impossible, throw an exception
18109             if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18110             {
18111                 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18112             }
18113         }
18114 
18115         if (is_an_object)
18116         {
18117             // the initializer list is a list of pairs -> create object
18118             m_type = value_t::object;
18119             m_value = value_t::object;
18120 
18121             std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18122             {
18123                 auto element = element_ref.moved_or_copied();
18124                 m_value.object->emplace(
18125                     std::move(*((*element.m_value.array)[0].m_value.string)),
18126                     std::move((*element.m_value.array)[1]));
18127             });
18128         }
18129         else
18130         {
18131             // the initializer list describes an array -> create array
18132             m_type = value_t::array;
18133             m_value.array = create<array_t>(init.begin(), init.end());
18134         }
18135 
18136         assert_invariant();
18137     }
18138 
18139     /*!
18140     @brief explicitly create a binary array (without subtype)
18141 
18142     Creates a JSON binary array value from a given binary container. Binary
18143     values are part of various binary formats, such as CBOR, MessagePack, and
18144     BSON. This constructor is used to create a value for serialization to those
18145     formats.
18146 
18147     @note Note, this function exists because of the difficulty in correctly
18148     specifying the correct template overload in the standard value ctor, as both
18149     JSON arrays and JSON binary arrays are backed with some form of a
18150     `std::vector`. Because JSON binary arrays are a non-standard extension it
18151     was decided that it would be best to prevent automatic initialization of a
18152     binary array type, for backwards compatibility and so it does not happen on
18153     accident.
18154 
18155     @param[in] init container containing bytes to use as binary type
18156 
18157     @return JSON binary array value
18158 
18159     @complexity Linear in the size of @a init.
18160 
18161     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18162     changes to any JSON value.
18163 
18164     @since version 3.8.0
18165     */
18166     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init)18167     static basic_json binary(const typename binary_t::container_type& init)
18168     {
18169         auto res = basic_json();
18170         res.m_type = value_t::binary;
18171         res.m_value = init;
18172         return res;
18173     }
18174 
18175     /*!
18176     @brief explicitly create a binary array (with subtype)
18177 
18178     Creates a JSON binary array value from a given binary container. Binary
18179     values are part of various binary formats, such as CBOR, MessagePack, and
18180     BSON. This constructor is used to create a value for serialization to those
18181     formats.
18182 
18183     @note Note, this function exists because of the difficulty in correctly
18184     specifying the correct template overload in the standard value ctor, as both
18185     JSON arrays and JSON binary arrays are backed with some form of a
18186     `std::vector`. Because JSON binary arrays are a non-standard extension it
18187     was decided that it would be best to prevent automatic initialization of a
18188     binary array type, for backwards compatibility and so it does not happen on
18189     accident.
18190 
18191     @param[in] init container containing bytes to use as binary type
18192     @param[in] subtype subtype to use in MessagePack and BSON
18193 
18194     @return JSON binary array value
18195 
18196     @complexity Linear in the size of @a init.
18197 
18198     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18199     changes to any JSON value.
18200 
18201     @since version 3.8.0
18202     */
18203     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init,std::uint8_t subtype)18204     static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18205     {
18206         auto res = basic_json();
18207         res.m_type = value_t::binary;
18208         res.m_value = binary_t(init, subtype);
18209         return res;
18210     }
18211 
18212     /// @copydoc binary(const typename binary_t::container_type&)
18213     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init)18214     static basic_json binary(typename binary_t::container_type&& init)
18215     {
18216         auto res = basic_json();
18217         res.m_type = value_t::binary;
18218         res.m_value = std::move(init);
18219         return res;
18220     }
18221 
18222     /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
18223     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init,std::uint8_t subtype)18224     static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18225     {
18226         auto res = basic_json();
18227         res.m_type = value_t::binary;
18228         res.m_value = binary_t(std::move(init), subtype);
18229         return res;
18230     }
18231 
18232     /*!
18233     @brief explicitly create an array from an initializer list
18234 
18235     Creates a JSON array value from a given initializer list. That is, given a
18236     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
18237     initializer list is empty, the empty array `[]` is created.
18238 
18239     @note This function is only needed to express two edge cases that cannot
18240     be realized with the initializer list constructor (@ref
18241     basic_json(initializer_list_t, bool, value_t)). These cases
18242     are:
18243     1. creating an array whose elements are all pairs whose first element is a
18244     string -- in this case, the initializer list constructor would create an
18245     object, taking the first elements as keys
18246     2. creating an empty array -- passing the empty initializer list to the
18247     initializer list constructor yields an empty object
18248 
18249     @param[in] init  initializer list with JSON values to create an array from
18250     (optional)
18251 
18252     @return JSON array value
18253 
18254     @complexity Linear in the size of @a init.
18255 
18256     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18257     changes to any JSON value.
18258 
18259     @liveexample{The following code shows an example for the `array`
18260     function.,array}
18261 
18262     @sa @ref basic_json(initializer_list_t, bool, value_t) --
18263     create a JSON value from an initializer list
18264     @sa @ref object(initializer_list_t) -- create a JSON object
18265     value from an initializer list
18266 
18267     @since version 1.0.0
18268     */
18269     JSON_HEDLEY_WARN_UNUSED_RESULT
array(initializer_list_t init={})18270     static basic_json array(initializer_list_t init = {})
18271     {
18272         return basic_json(init, false, value_t::array);
18273     }
18274 
18275     /*!
18276     @brief explicitly create an object from an initializer list
18277 
18278     Creates a JSON object value from a given initializer list. The initializer
18279     lists elements must be pairs, and their first elements must be strings. If
18280     the initializer list is empty, the empty object `{}` is created.
18281 
18282     @note This function is only added for symmetry reasons. In contrast to the
18283     related function @ref array(initializer_list_t), there are
18284     no cases which can only be expressed by this function. That is, any
18285     initializer list @a init can also be passed to the initializer list
18286     constructor @ref basic_json(initializer_list_t, bool, value_t).
18287 
18288     @param[in] init  initializer list to create an object from (optional)
18289 
18290     @return JSON object value
18291 
18292     @throw type_error.301 if @a init is not a list of pairs whose first
18293     elements are strings. In this case, no object can be created. When such a
18294     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
18295     an array would have been created from the passed initializer list @a init.
18296     See example below.
18297 
18298     @complexity Linear in the size of @a init.
18299 
18300     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18301     changes to any JSON value.
18302 
18303     @liveexample{The following code shows an example for the `object`
18304     function.,object}
18305 
18306     @sa @ref basic_json(initializer_list_t, bool, value_t) --
18307     create a JSON value from an initializer list
18308     @sa @ref array(initializer_list_t) -- create a JSON array
18309     value from an initializer list
18310 
18311     @since version 1.0.0
18312     */
18313     JSON_HEDLEY_WARN_UNUSED_RESULT
object(initializer_list_t init={})18314     static basic_json object(initializer_list_t init = {})
18315     {
18316         return basic_json(init, false, value_t::object);
18317     }
18318 
18319     /*!
18320     @brief construct an array with count copies of given value
18321 
18322     Constructs a JSON array value by creating @a cnt copies of a passed value.
18323     In case @a cnt is `0`, an empty array is created.
18324 
18325     @param[in] cnt  the number of JSON copies of @a val to create
18326     @param[in] val  the JSON value to copy
18327 
18328     @post `std::distance(begin(),end()) == cnt` holds.
18329 
18330     @complexity Linear in @a cnt.
18331 
18332     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18333     changes to any JSON value.
18334 
18335     @liveexample{The following code shows examples for the @ref
18336     basic_json(size_type\, const basic_json&)
18337     constructor.,basic_json__size_type_basic_json}
18338 
18339     @since version 1.0.0
18340     */
basic_json(size_type cnt,const basic_json & val)18341     basic_json(size_type cnt, const basic_json& val)
18342         : m_type(value_t::array)
18343     {
18344         m_value.array = create<array_t>(cnt, val);
18345         assert_invariant();
18346     }
18347 
18348     /*!
18349     @brief construct a JSON container given an iterator range
18350 
18351     Constructs the JSON value with the contents of the range `[first, last)`.
18352     The semantics depends on the different types a JSON value can have:
18353     - In case of a null type, invalid_iterator.206 is thrown.
18354     - In case of other primitive types (number, boolean, or string), @a first
18355       must be `begin()` and @a last must be `end()`. In this case, the value is
18356       copied. Otherwise, invalid_iterator.204 is thrown.
18357     - In case of structured types (array, object), the constructor behaves as
18358       similar versions for `std::vector` or `std::map`; that is, a JSON array
18359       or object is constructed from the values in the range.
18360 
18361     @tparam InputIT an input iterator type (@ref iterator or @ref
18362     const_iterator)
18363 
18364     @param[in] first begin of the range to copy from (included)
18365     @param[in] last end of the range to copy from (excluded)
18366 
18367     @pre Iterators @a first and @a last must be initialized. **This
18368          precondition is enforced with an assertion (see warning).** If
18369          assertions are switched off, a violation of this precondition yields
18370          undefined behavior.
18371 
18372     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
18373          checked efficiently. Only certain edge cases are detected; see the
18374          description of the exceptions below. A violation of this precondition
18375          yields undefined behavior.
18376 
18377     @warning A precondition is enforced with a runtime assertion that will
18378              result in calling `std::abort` if this precondition is not met.
18379              Assertions can be disabled by defining `NDEBUG` at compile time.
18380              See https://en.cppreference.com/w/cpp/error/assert for more
18381              information.
18382 
18383     @throw invalid_iterator.201 if iterators @a first and @a last are not
18384     compatible (i.e., do not belong to the same JSON value). In this case,
18385     the range `[first, last)` is undefined.
18386     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
18387     primitive type (number, boolean, or string), but @a first does not point
18388     to the first element any more. In this case, the range `[first, last)` is
18389     undefined. See example code below.
18390     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
18391     null value. In this case, the range `[first, last)` is undefined.
18392 
18393     @complexity Linear in distance between @a first and @a last.
18394 
18395     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18396     changes to any JSON value.
18397 
18398     @liveexample{The example below shows several ways to create JSON values by
18399     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
18400 
18401     @since version 1.0.0
18402     */
18403     template < class InputIT, typename std::enable_if <
18404                    std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18405                    std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
basic_json(InputIT first,InputIT last)18406     basic_json(InputIT first, InputIT last)
18407     {
18408         JSON_ASSERT(first.m_object != nullptr);
18409         JSON_ASSERT(last.m_object != nullptr);
18410 
18411         // make sure iterator fits the current value
18412         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18413         {
18414             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18415         }
18416 
18417         // copy type from first iterator
18418         m_type = first.m_object->m_type;
18419 
18420         // check if iterator range is complete for primitive values
18421         switch (m_type)
18422         {
18423             case value_t::boolean:
18424             case value_t::number_float:
18425             case value_t::number_integer:
18426             case value_t::number_unsigned:
18427             case value_t::string:
18428             {
18429                 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18430                                          || !last.m_it.primitive_iterator.is_end()))
18431                 {
18432                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18433                 }
18434                 break;
18435             }
18436 
18437             default:
18438                 break;
18439         }
18440 
18441         switch (m_type)
18442         {
18443             case value_t::number_integer:
18444             {
18445                 m_value.number_integer = first.m_object->m_value.number_integer;
18446                 break;
18447             }
18448 
18449             case value_t::number_unsigned:
18450             {
18451                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18452                 break;
18453             }
18454 
18455             case value_t::number_float:
18456             {
18457                 m_value.number_float = first.m_object->m_value.number_float;
18458                 break;
18459             }
18460 
18461             case value_t::boolean:
18462             {
18463                 m_value.boolean = first.m_object->m_value.boolean;
18464                 break;
18465             }
18466 
18467             case value_t::string:
18468             {
18469                 m_value = *first.m_object->m_value.string;
18470                 break;
18471             }
18472 
18473             case value_t::object:
18474             {
18475                 m_value.object = create<object_t>(first.m_it.object_iterator,
18476                                                   last.m_it.object_iterator);
18477                 break;
18478             }
18479 
18480             case value_t::array:
18481             {
18482                 m_value.array = create<array_t>(first.m_it.array_iterator,
18483                                                 last.m_it.array_iterator);
18484                 break;
18485             }
18486 
18487             case value_t::binary:
18488             {
18489                 m_value = *first.m_object->m_value.binary;
18490                 break;
18491             }
18492 
18493             default:
18494                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18495                                                     std::string(first.m_object->type_name())));
18496         }
18497 
18498         assert_invariant();
18499     }
18500 
18501 
18502     ///////////////////////////////////////
18503     // other constructors and destructor //
18504     ///////////////////////////////////////
18505 
18506     template<typename JsonRef,
18507              detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18508                                  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef & ref)18509     basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18510 
18511     /*!
18512     @brief copy constructor
18513 
18514     Creates a copy of a given JSON value.
18515 
18516     @param[in] other  the JSON value to copy
18517 
18518     @post `*this == other`
18519 
18520     @complexity Linear in the size of @a other.
18521 
18522     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18523     changes to any JSON value.
18524 
18525     @requirement This function helps `basic_json` satisfying the
18526     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18527     requirements:
18528     - The complexity is linear.
18529     - As postcondition, it holds: `other == basic_json(other)`.
18530 
18531     @liveexample{The following code shows an example for the copy
18532     constructor.,basic_json__basic_json}
18533 
18534     @since version 1.0.0
18535     */
basic_json(const basic_json & other)18536     basic_json(const basic_json& other)
18537         : m_type(other.m_type)
18538     {
18539         // check of passed value is valid
18540         other.assert_invariant();
18541 
18542         switch (m_type)
18543         {
18544             case value_t::object:
18545             {
18546                 m_value = *other.m_value.object;
18547                 break;
18548             }
18549 
18550             case value_t::array:
18551             {
18552                 m_value = *other.m_value.array;
18553                 break;
18554             }
18555 
18556             case value_t::string:
18557             {
18558                 m_value = *other.m_value.string;
18559                 break;
18560             }
18561 
18562             case value_t::boolean:
18563             {
18564                 m_value = other.m_value.boolean;
18565                 break;
18566             }
18567 
18568             case value_t::number_integer:
18569             {
18570                 m_value = other.m_value.number_integer;
18571                 break;
18572             }
18573 
18574             case value_t::number_unsigned:
18575             {
18576                 m_value = other.m_value.number_unsigned;
18577                 break;
18578             }
18579 
18580             case value_t::number_float:
18581             {
18582                 m_value = other.m_value.number_float;
18583                 break;
18584             }
18585 
18586             case value_t::binary:
18587             {
18588                 m_value = *other.m_value.binary;
18589                 break;
18590             }
18591 
18592             default:
18593                 break;
18594         }
18595 
18596         assert_invariant();
18597     }
18598 
18599     /*!
18600     @brief move constructor
18601 
18602     Move constructor. Constructs a JSON value with the contents of the given
18603     value @a other using move semantics. It "steals" the resources from @a
18604     other and leaves it as JSON null value.
18605 
18606     @param[in,out] other  value to move to this object
18607 
18608     @post `*this` has the same value as @a other before the call.
18609     @post @a other is a JSON null value.
18610 
18611     @complexity Constant.
18612 
18613     @exceptionsafety No-throw guarantee: this constructor never throws
18614     exceptions.
18615 
18616     @requirement This function helps `basic_json` satisfying the
18617     [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
18618     requirements.
18619 
18620     @liveexample{The code below shows the move constructor explicitly called
18621     via std::move.,basic_json__moveconstructor}
18622 
18623     @since version 1.0.0
18624     */
basic_json(basic_json && other)18625     basic_json(basic_json&& other) noexcept
18626         : m_type(std::move(other.m_type)),
18627           m_value(std::move(other.m_value))
18628     {
18629         // check that passed value is valid
18630         other.assert_invariant();
18631 
18632         // invalidate payload
18633         other.m_type = value_t::null;
18634         other.m_value = {};
18635 
18636         assert_invariant();
18637     }
18638 
18639     /*!
18640     @brief copy assignment
18641 
18642     Copy assignment operator. Copies a JSON value via the "copy and swap"
18643     strategy: It is expressed in terms of the copy constructor, destructor,
18644     and the `swap()` member function.
18645 
18646     @param[in] other  value to copy from
18647 
18648     @complexity Linear.
18649 
18650     @requirement This function helps `basic_json` satisfying the
18651     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18652     requirements:
18653     - The complexity is linear.
18654 
18655     @liveexample{The code below shows and example for the copy assignment. It
18656     creates a copy of value `a` which is then swapped with `b`. Finally\, the
18657     copy of `a` (which is the null value after the swap) is
18658     destroyed.,basic_json__copyassignment}
18659 
18660     @since version 1.0.0
18661     */
operator =(basic_json other)18662     basic_json& operator=(basic_json other) noexcept (
18663         std::is_nothrow_move_constructible<value_t>::value&&
18664         std::is_nothrow_move_assignable<value_t>::value&&
18665         std::is_nothrow_move_constructible<json_value>::value&&
18666         std::is_nothrow_move_assignable<json_value>::value
18667     )
18668     {
18669         // check that passed value is valid
18670         other.assert_invariant();
18671 
18672         using std::swap;
18673         swap(m_type, other.m_type);
18674         swap(m_value, other.m_value);
18675 
18676         assert_invariant();
18677         return *this;
18678     }
18679 
18680     /*!
18681     @brief destructor
18682 
18683     Destroys the JSON value and frees all allocated memory.
18684 
18685     @complexity Linear.
18686 
18687     @requirement This function helps `basic_json` satisfying the
18688     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18689     requirements:
18690     - The complexity is linear.
18691     - All stored elements are destroyed and all memory is freed.
18692 
18693     @since version 1.0.0
18694     */
~basic_json()18695     ~basic_json() noexcept
18696     {
18697         assert_invariant();
18698         m_value.destroy(m_type);
18699     }
18700 
18701     /// @}
18702 
18703   public:
18704     ///////////////////////
18705     // object inspection //
18706     ///////////////////////
18707 
18708     /// @name object inspection
18709     /// Functions to inspect the type of a JSON value.
18710     /// @{
18711 
18712     /*!
18713     @brief serialization
18714 
18715     Serialization function for JSON values. The function tries to mimic
18716     Python's `json.dumps()` function, and currently supports its @a indent
18717     and @a ensure_ascii parameters.
18718 
18719     @param[in] indent If indent is nonnegative, then array elements and object
18720     members will be pretty-printed with that indent level. An indent level of
18721     `0` will only insert newlines. `-1` (the default) selects the most compact
18722     representation.
18723     @param[in] indent_char The character to use for indentation if @a indent is
18724     greater than `0`. The default is ` ` (space).
18725     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
18726     in the output are escaped with `\uXXXX` sequences, and the result consists
18727     of ASCII characters only.
18728     @param[in] error_handler  how to react on decoding errors; there are three
18729     possible values: `strict` (throws and exception in case a decoding error
18730     occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
18731     and `ignore` (ignore invalid UTF-8 sequences during serialization; all
18732     bytes are copied to the output unchanged).
18733 
18734     @return string containing the serialization of the JSON value
18735 
18736     @throw type_error.316 if a string stored inside the JSON value is not
18737                           UTF-8 encoded and @a error_handler is set to strict
18738 
18739     @note Binary values are serialized as object containing two keys:
18740       - "bytes": an array of bytes as integers
18741       - "subtype": the subtype as integer or "null" if the binary has no subtype
18742 
18743     @complexity Linear.
18744 
18745     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18746     changes in the JSON value.
18747 
18748     @liveexample{The following example shows the effect of different @a indent\,
18749     @a indent_char\, and @a ensure_ascii parameters to the result of the
18750     serialization.,dump}
18751 
18752     @see https://docs.python.org/2/library/json.html#json.dump
18753 
18754     @since version 1.0.0; indentation character @a indent_char, option
18755            @a ensure_ascii and exceptions added in version 3.0.0; error
18756            handlers added in version 3.4.0; serialization of binary values added
18757            in version 3.8.0.
18758     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const18759     string_t dump(const int indent = -1,
18760                   const char indent_char = ' ',
18761                   const bool ensure_ascii = false,
18762                   const error_handler_t error_handler = error_handler_t::strict) const
18763     {
18764         string_t result;
18765         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18766 
18767         if (indent >= 0)
18768         {
18769             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18770         }
18771         else
18772         {
18773             s.dump(*this, false, ensure_ascii, 0);
18774         }
18775 
18776         return result;
18777     }
18778 
18779     /*!
18780     @brief return the type of the JSON value (explicit)
18781 
18782     Return the type of the JSON value as a value from the @ref value_t
18783     enumeration.
18784 
18785     @return the type of the JSON value
18786             Value type                | return value
18787             ------------------------- | -------------------------
18788             null                      | value_t::null
18789             boolean                   | value_t::boolean
18790             string                    | value_t::string
18791             number (integer)          | value_t::number_integer
18792             number (unsigned integer) | value_t::number_unsigned
18793             number (floating-point)   | value_t::number_float
18794             object                    | value_t::object
18795             array                     | value_t::array
18796             binary                    | value_t::binary
18797             discarded                 | value_t::discarded
18798 
18799     @complexity Constant.
18800 
18801     @exceptionsafety No-throw guarantee: this member function never throws
18802     exceptions.
18803 
18804     @liveexample{The following code exemplifies `type()` for all JSON
18805     types.,type}
18806 
18807     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
18808     @sa @ref type_name() -- return the type as string
18809 
18810     @since version 1.0.0
18811     */
type() const18812     constexpr value_t type() const noexcept
18813     {
18814         return m_type;
18815     }
18816 
18817     /*!
18818     @brief return whether type is primitive
18819 
18820     This function returns true if and only if the JSON type is primitive
18821     (string, number, boolean, or null).
18822 
18823     @return `true` if type is primitive (string, number, boolean, or null),
18824     `false` otherwise.
18825 
18826     @complexity Constant.
18827 
18828     @exceptionsafety No-throw guarantee: this member function never throws
18829     exceptions.
18830 
18831     @liveexample{The following code exemplifies `is_primitive()` for all JSON
18832     types.,is_primitive}
18833 
18834     @sa @ref is_structured() -- returns whether JSON value is structured
18835     @sa @ref is_null() -- returns whether JSON value is `null`
18836     @sa @ref is_string() -- returns whether JSON value is a string
18837     @sa @ref is_boolean() -- returns whether JSON value is a boolean
18838     @sa @ref is_number() -- returns whether JSON value is a number
18839     @sa @ref is_binary() -- returns whether JSON value is a binary array
18840 
18841     @since version 1.0.0
18842     */
is_primitive() const18843     constexpr bool is_primitive() const noexcept
18844     {
18845         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18846     }
18847 
18848     /*!
18849     @brief return whether type is structured
18850 
18851     This function returns true if and only if the JSON type is structured
18852     (array or object).
18853 
18854     @return `true` if type is structured (array or object), `false` otherwise.
18855 
18856     @complexity Constant.
18857 
18858     @exceptionsafety No-throw guarantee: this member function never throws
18859     exceptions.
18860 
18861     @liveexample{The following code exemplifies `is_structured()` for all JSON
18862     types.,is_structured}
18863 
18864     @sa @ref is_primitive() -- returns whether value is primitive
18865     @sa @ref is_array() -- returns whether value is an array
18866     @sa @ref is_object() -- returns whether value is an object
18867 
18868     @since version 1.0.0
18869     */
is_structured() const18870     constexpr bool is_structured() const noexcept
18871     {
18872         return is_array() || is_object();
18873     }
18874 
18875     /*!
18876     @brief return whether value is null
18877 
18878     This function returns true if and only if the JSON value is null.
18879 
18880     @return `true` if type is null, `false` otherwise.
18881 
18882     @complexity Constant.
18883 
18884     @exceptionsafety No-throw guarantee: this member function never throws
18885     exceptions.
18886 
18887     @liveexample{The following code exemplifies `is_null()` for all JSON
18888     types.,is_null}
18889 
18890     @since version 1.0.0
18891     */
is_null() const18892     constexpr bool is_null() const noexcept
18893     {
18894         return m_type == value_t::null;
18895     }
18896 
18897     /*!
18898     @brief return whether value is a boolean
18899 
18900     This function returns true if and only if the JSON value is a boolean.
18901 
18902     @return `true` if type is boolean, `false` otherwise.
18903 
18904     @complexity Constant.
18905 
18906     @exceptionsafety No-throw guarantee: this member function never throws
18907     exceptions.
18908 
18909     @liveexample{The following code exemplifies `is_boolean()` for all JSON
18910     types.,is_boolean}
18911 
18912     @since version 1.0.0
18913     */
is_boolean() const18914     constexpr bool is_boolean() const noexcept
18915     {
18916         return m_type == value_t::boolean;
18917     }
18918 
18919     /*!
18920     @brief return whether value is a number
18921 
18922     This function returns true if and only if the JSON value is a number. This
18923     includes both integer (signed and unsigned) and floating-point values.
18924 
18925     @return `true` if type is number (regardless whether integer, unsigned
18926     integer or floating-type), `false` otherwise.
18927 
18928     @complexity Constant.
18929 
18930     @exceptionsafety No-throw guarantee: this member function never throws
18931     exceptions.
18932 
18933     @liveexample{The following code exemplifies `is_number()` for all JSON
18934     types.,is_number}
18935 
18936     @sa @ref is_number_integer() -- check if value is an integer or unsigned
18937     integer number
18938     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
18939     number
18940     @sa @ref is_number_float() -- check if value is a floating-point number
18941 
18942     @since version 1.0.0
18943     */
is_number() const18944     constexpr bool is_number() const noexcept
18945     {
18946         return is_number_integer() || is_number_float();
18947     }
18948 
18949     /*!
18950     @brief return whether value is an integer number
18951 
18952     This function returns true if and only if the JSON value is a signed or
18953     unsigned integer number. This excludes floating-point values.
18954 
18955     @return `true` if type is an integer or unsigned integer number, `false`
18956     otherwise.
18957 
18958     @complexity Constant.
18959 
18960     @exceptionsafety No-throw guarantee: this member function never throws
18961     exceptions.
18962 
18963     @liveexample{The following code exemplifies `is_number_integer()` for all
18964     JSON types.,is_number_integer}
18965 
18966     @sa @ref is_number() -- check if value is a number
18967     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
18968     number
18969     @sa @ref is_number_float() -- check if value is a floating-point number
18970 
18971     @since version 1.0.0
18972     */
is_number_integer() const18973     constexpr bool is_number_integer() const noexcept
18974     {
18975         return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18976     }
18977 
18978     /*!
18979     @brief return whether value is an unsigned integer number
18980 
18981     This function returns true if and only if the JSON value is an unsigned
18982     integer number. This excludes floating-point and signed integer values.
18983 
18984     @return `true` if type is an unsigned integer number, `false` otherwise.
18985 
18986     @complexity Constant.
18987 
18988     @exceptionsafety No-throw guarantee: this member function never throws
18989     exceptions.
18990 
18991     @liveexample{The following code exemplifies `is_number_unsigned()` for all
18992     JSON types.,is_number_unsigned}
18993 
18994     @sa @ref is_number() -- check if value is a number
18995     @sa @ref is_number_integer() -- check if value is an integer or unsigned
18996     integer number
18997     @sa @ref is_number_float() -- check if value is a floating-point number
18998 
18999     @since version 2.0.0
19000     */
is_number_unsigned() const19001     constexpr bool is_number_unsigned() const noexcept
19002     {
19003         return m_type == value_t::number_unsigned;
19004     }
19005 
19006     /*!
19007     @brief return whether value is a floating-point number
19008 
19009     This function returns true if and only if the JSON value is a
19010     floating-point number. This excludes signed and unsigned integer values.
19011 
19012     @return `true` if type is a floating-point number, `false` otherwise.
19013 
19014     @complexity Constant.
19015 
19016     @exceptionsafety No-throw guarantee: this member function never throws
19017     exceptions.
19018 
19019     @liveexample{The following code exemplifies `is_number_float()` for all
19020     JSON types.,is_number_float}
19021 
19022     @sa @ref is_number() -- check if value is number
19023     @sa @ref is_number_integer() -- check if value is an integer number
19024     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19025     number
19026 
19027     @since version 1.0.0
19028     */
is_number_float() const19029     constexpr bool is_number_float() const noexcept
19030     {
19031         return m_type == value_t::number_float;
19032     }
19033 
19034     /*!
19035     @brief return whether value is an object
19036 
19037     This function returns true if and only if the JSON value is an object.
19038 
19039     @return `true` if type is object, `false` otherwise.
19040 
19041     @complexity Constant.
19042 
19043     @exceptionsafety No-throw guarantee: this member function never throws
19044     exceptions.
19045 
19046     @liveexample{The following code exemplifies `is_object()` for all JSON
19047     types.,is_object}
19048 
19049     @since version 1.0.0
19050     */
is_object() const19051     constexpr bool is_object() const noexcept
19052     {
19053         return m_type == value_t::object;
19054     }
19055 
19056     /*!
19057     @brief return whether value is an array
19058 
19059     This function returns true if and only if the JSON value is an array.
19060 
19061     @return `true` if type is array, `false` otherwise.
19062 
19063     @complexity Constant.
19064 
19065     @exceptionsafety No-throw guarantee: this member function never throws
19066     exceptions.
19067 
19068     @liveexample{The following code exemplifies `is_array()` for all JSON
19069     types.,is_array}
19070 
19071     @since version 1.0.0
19072     */
is_array() const19073     constexpr bool is_array() const noexcept
19074     {
19075         return m_type == value_t::array;
19076     }
19077 
19078     /*!
19079     @brief return whether value is a string
19080 
19081     This function returns true if and only if the JSON value is a string.
19082 
19083     @return `true` if type is string, `false` otherwise.
19084 
19085     @complexity Constant.
19086 
19087     @exceptionsafety No-throw guarantee: this member function never throws
19088     exceptions.
19089 
19090     @liveexample{The following code exemplifies `is_string()` for all JSON
19091     types.,is_string}
19092 
19093     @since version 1.0.0
19094     */
is_string() const19095     constexpr bool is_string() const noexcept
19096     {
19097         return m_type == value_t::string;
19098     }
19099 
19100     /*!
19101     @brief return whether value is a binary array
19102 
19103     This function returns true if and only if the JSON value is a binary array.
19104 
19105     @return `true` if type is binary array, `false` otherwise.
19106 
19107     @complexity Constant.
19108 
19109     @exceptionsafety No-throw guarantee: this member function never throws
19110     exceptions.
19111 
19112     @liveexample{The following code exemplifies `is_binary()` for all JSON
19113     types.,is_binary}
19114 
19115     @since version 3.8.0
19116     */
is_binary() const19117     constexpr bool is_binary() const noexcept
19118     {
19119         return m_type == value_t::binary;
19120     }
19121 
19122     /*!
19123     @brief return whether value is discarded
19124 
19125     This function returns true if and only if the JSON value was discarded
19126     during parsing with a callback function (see @ref parser_callback_t).
19127 
19128     @note This function will always be `false` for JSON values after parsing.
19129     That is, discarded values can only occur during parsing, but will be
19130     removed when inside a structured value or replaced by null in other cases.
19131 
19132     @return `true` if type is discarded, `false` otherwise.
19133 
19134     @complexity Constant.
19135 
19136     @exceptionsafety No-throw guarantee: this member function never throws
19137     exceptions.
19138 
19139     @liveexample{The following code exemplifies `is_discarded()` for all JSON
19140     types.,is_discarded}
19141 
19142     @since version 1.0.0
19143     */
is_discarded() const19144     constexpr bool is_discarded() const noexcept
19145     {
19146         return m_type == value_t::discarded;
19147     }
19148 
19149     /*!
19150     @brief return the type of the JSON value (implicit)
19151 
19152     Implicitly return the type of the JSON value as a value from the @ref
19153     value_t enumeration.
19154 
19155     @return the type of the JSON value
19156 
19157     @complexity Constant.
19158 
19159     @exceptionsafety No-throw guarantee: this member function never throws
19160     exceptions.
19161 
19162     @liveexample{The following code exemplifies the @ref value_t operator for
19163     all JSON types.,operator__value_t}
19164 
19165     @sa @ref type() -- return the type of the JSON value (explicit)
19166     @sa @ref type_name() -- return the type as string
19167 
19168     @since version 1.0.0
19169     */
operator value_t() const19170     constexpr operator value_t() const noexcept
19171     {
19172         return m_type;
19173     }
19174 
19175     /// @}
19176 
19177   private:
19178     //////////////////
19179     // value access //
19180     //////////////////
19181 
19182     /// get a boolean (explicit)
get_impl(boolean_t *) const19183     boolean_t get_impl(boolean_t* /*unused*/) const
19184     {
19185         if (JSON_HEDLEY_LIKELY(is_boolean()))
19186         {
19187             return m_value.boolean;
19188         }
19189 
19190         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19191     }
19192 
19193     /// get a pointer to the value (object)
get_impl_ptr(object_t *)19194     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19195     {
19196         return is_object() ? m_value.object : nullptr;
19197     }
19198 
19199     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const19200     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19201     {
19202         return is_object() ? m_value.object : nullptr;
19203     }
19204 
19205     /// get a pointer to the value (array)
get_impl_ptr(array_t *)19206     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19207     {
19208         return is_array() ? m_value.array : nullptr;
19209     }
19210 
19211     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const19212     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19213     {
19214         return is_array() ? m_value.array : nullptr;
19215     }
19216 
19217     /// get a pointer to the value (string)
get_impl_ptr(string_t *)19218     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19219     {
19220         return is_string() ? m_value.string : nullptr;
19221     }
19222 
19223     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const19224     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19225     {
19226         return is_string() ? m_value.string : nullptr;
19227     }
19228 
19229     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)19230     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19231     {
19232         return is_boolean() ? &m_value.boolean : nullptr;
19233     }
19234 
19235     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const19236     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19237     {
19238         return is_boolean() ? &m_value.boolean : nullptr;
19239     }
19240 
19241     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)19242     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19243     {
19244         return is_number_integer() ? &m_value.number_integer : nullptr;
19245     }
19246 
19247     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const19248     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19249     {
19250         return is_number_integer() ? &m_value.number_integer : nullptr;
19251     }
19252 
19253     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)19254     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19255     {
19256         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19257     }
19258 
19259     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const19260     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19261     {
19262         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19263     }
19264 
19265     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)19266     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19267     {
19268         return is_number_float() ? &m_value.number_float : nullptr;
19269     }
19270 
19271     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const19272     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19273     {
19274         return is_number_float() ? &m_value.number_float : nullptr;
19275     }
19276 
19277     /// get a pointer to the value (binary)
get_impl_ptr(binary_t *)19278     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19279     {
19280         return is_binary() ? m_value.binary : nullptr;
19281     }
19282 
19283     /// get a pointer to the value (binary)
get_impl_ptr(const binary_t *) const19284     constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19285     {
19286         return is_binary() ? m_value.binary : nullptr;
19287     }
19288 
19289     /*!
19290     @brief helper function to implement get_ref()
19291 
19292     This function helps to implement get_ref() without code duplication for
19293     const and non-const overloads
19294 
19295     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
19296 
19297     @throw type_error.303 if ReferenceType does not match underlying value
19298     type of the current JSON
19299     */
19300     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)19301     static ReferenceType get_ref_impl(ThisType& obj)
19302     {
19303         // delegate the call to get_ptr<>()
19304         auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19305 
19306         if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19307         {
19308             return *ptr;
19309         }
19310 
19311         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19312     }
19313 
19314   public:
19315     /// @name value access
19316     /// Direct access to the stored value of a JSON value.
19317     /// @{
19318 
19319     /*!
19320     @brief get special-case overload
19321 
19322     This overloads avoids a lot of template boilerplate, it can be seen as the
19323     identity method
19324 
19325     @tparam BasicJsonType == @ref basic_json
19326 
19327     @return a copy of *this
19328 
19329     @complexity Constant.
19330 
19331     @since version 2.1.0
19332     */
19333     template<typename BasicJsonType, detail::enable_if_t<
19334                  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19335                  int> = 0>
get() const19336     basic_json get() const
19337     {
19338         return *this;
19339     }
19340 
19341     /*!
19342     @brief get special-case overload
19343 
19344     This overloads converts the current @ref basic_json in a different
19345     @ref basic_json type
19346 
19347     @tparam BasicJsonType == @ref basic_json
19348 
19349     @return a copy of *this, converted into @tparam BasicJsonType
19350 
19351     @complexity Depending on the implementation of the called `from_json()`
19352                 method.
19353 
19354     @since version 3.2.0
19355     */
19356     template < typename BasicJsonType, detail::enable_if_t <
19357                    !std::is_same<BasicJsonType, basic_json>::value&&
19358                    detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19359     BasicJsonType get() const
19360     {
19361         return *this;
19362     }
19363 
19364     /*!
19365     @brief get a value (explicit)
19366 
19367     Explicit type conversion between the JSON value and a compatible value
19368     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19369     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19370     The value is converted by calling the @ref json_serializer<ValueType>
19371     `from_json()` method.
19372 
19373     The function is equivalent to executing
19374     @code {.cpp}
19375     ValueType ret;
19376     JSONSerializer<ValueType>::from_json(*this, ret);
19377     return ret;
19378     @endcode
19379 
19380     This overloads is chosen if:
19381     - @a ValueType is not @ref basic_json,
19382     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19383       `void from_json(const basic_json&, ValueType&)`, and
19384     - @ref json_serializer<ValueType> does not have a `from_json()` method of
19385       the form `ValueType from_json(const basic_json&)`
19386 
19387     @tparam ValueTypeCV the provided value type
19388     @tparam ValueType the returned value type
19389 
19390     @return copy of the JSON value, converted to @a ValueType
19391 
19392     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19393 
19394     @liveexample{The example below shows several conversions from JSON values
19395     to other types. There a few things to note: (1) Floating-point numbers can
19396     be converted to integers\, (2) A JSON array can be converted to a standard
19397     `std::vector<short>`\, (3) A JSON object can be converted to C++
19398     associative containers such as `std::unordered_map<std::string\,
19399     json>`.,get__ValueType_const}
19400 
19401     @since version 2.1.0
19402     */
19403     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19404                detail::enable_if_t <
19405                    !detail::is_basic_json<ValueType>::value &&
19406                    detail::has_from_json<basic_json_t, ValueType>::value &&
19407                    !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19408                    int > = 0 >
19409     ValueType get() const noexcept(noexcept(
19410                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19411     {
19412         // we cannot static_assert on ValueTypeCV being non-const, because
19413         // there is support for get<const basic_json_t>(), which is why we
19414         // still need the uncvref
19415         static_assert(!std::is_reference<ValueTypeCV>::value,
19416                       "get() cannot be used with reference types, you might want to use get_ref()");
19417         static_assert(std::is_default_constructible<ValueType>::value,
19418                       "types must be DefaultConstructible when used with get()");
19419 
19420         ValueType ret;
19421         JSONSerializer<ValueType>::from_json(*this, ret);
19422         return ret;
19423     }
19424 
19425     /*!
19426     @brief get a value (explicit); special case
19427 
19428     Explicit type conversion between the JSON value and a compatible value
19429     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19430     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19431     The value is converted by calling the @ref json_serializer<ValueType>
19432     `from_json()` method.
19433 
19434     The function is equivalent to executing
19435     @code {.cpp}
19436     return JSONSerializer<ValueTypeCV>::from_json(*this);
19437     @endcode
19438 
19439     This overloads is chosen if:
19440     - @a ValueType is not @ref basic_json and
19441     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19442       `ValueType from_json(const basic_json&)`
19443 
19444     @note If @ref json_serializer<ValueType> has both overloads of
19445     `from_json()`, this one is chosen.
19446 
19447     @tparam ValueTypeCV the provided value type
19448     @tparam ValueType the returned value type
19449 
19450     @return copy of the JSON value, converted to @a ValueType
19451 
19452     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19453 
19454     @since version 2.1.0
19455     */
19456     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19457                detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19458                                      detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19459                                      int > = 0 >
19460     ValueType get() const noexcept(noexcept(
19461                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19462     {
19463         static_assert(!std::is_reference<ValueTypeCV>::value,
19464                       "get() cannot be used with reference types, you might want to use get_ref()");
19465         return JSONSerializer<ValueType>::from_json(*this);
19466     }
19467 
19468     /*!
19469     @brief get a value (explicit)
19470 
19471     Explicit type conversion between the JSON value and a compatible value.
19472     The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
19473     `from_json()` method.
19474 
19475     The function is equivalent to executing
19476     @code {.cpp}
19477     ValueType v;
19478     JSONSerializer<ValueType>::from_json(*this, v);
19479     @endcode
19480 
19481     This overloads is chosen if:
19482     - @a ValueType is not @ref basic_json,
19483     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19484       `void from_json(const basic_json&, ValueType&)`, and
19485 
19486     @tparam ValueType the input parameter type.
19487 
19488     @return the input parameter, allowing chaining calls.
19489 
19490     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19491 
19492     @liveexample{The example below shows several conversions from JSON values
19493     to other types. There a few things to note: (1) Floating-point numbers can
19494     be converted to integers\, (2) A JSON array can be converted to a standard
19495     `std::vector<short>`\, (3) A JSON object can be converted to C++
19496     associative containers such as `std::unordered_map<std::string\,
19497     json>`.,get_to}
19498 
19499     @since version 3.3.0
19500     */
19501     template < typename ValueType,
19502                detail::enable_if_t <
19503                    !detail::is_basic_json<ValueType>::value&&
19504                    detail::has_from_json<basic_json_t, ValueType>::value,
19505                    int > = 0 >
19506     ValueType & get_to(ValueType& v) const noexcept(noexcept(
19507                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19508     {
19509         JSONSerializer<ValueType>::from_json(*this, v);
19510         return v;
19511     }
19512 
19513     // specialization to allow to call get_to with a basic_json value
19514     // see https://github.com/nlohmann/json/issues/2175
19515     template<typename ValueType,
19516              detail::enable_if_t <
19517                  detail::is_basic_json<ValueType>::value,
19518                  int> = 0>
19519     ValueType & get_to(ValueType& v) const
19520     {
19521         v = *this;
19522         return v;
19523     }
19524 
19525     template <
19526         typename T, std::size_t N,
19527         typename Array = T (&)[N],
19528         detail::enable_if_t <
19529             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19530     Array get_to(T (&v)[N]) const
19531     noexcept(noexcept(JSONSerializer<Array>::from_json(
19532                           std::declval<const basic_json_t&>(), v)))
19533     {
19534         JSONSerializer<Array>::from_json(*this, v);
19535         return v;
19536     }
19537 
19538 
19539     /*!
19540     @brief get a pointer value (implicit)
19541 
19542     Implicit pointer access to the internally stored JSON value. No copies are
19543     made.
19544 
19545     @warning Writing data to the pointee of the result yields an undefined
19546     state.
19547 
19548     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19549     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19550     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
19551     assertion.
19552 
19553     @return pointer to the internally stored JSON value if the requested
19554     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19555 
19556     @complexity Constant.
19557 
19558     @liveexample{The example below shows how pointers to internal values of a
19559     JSON value can be requested. Note that no type conversions are made and a
19560     `nullptr` is returned if the value and the requested pointer type does not
19561     match.,get_ptr}
19562 
19563     @since version 1.0.0
19564     */
19565     template<typename PointerType, typename std::enable_if<
19566                  std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()19567     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19568     {
19569         // delegate the call to get_impl_ptr<>()
19570         return get_impl_ptr(static_cast<PointerType>(nullptr));
19571     }
19572 
19573     /*!
19574     @brief get a pointer value (implicit)
19575     @copydoc get_ptr()
19576     */
19577     template < typename PointerType, typename std::enable_if <
19578                    std::is_pointer<PointerType>::value&&
19579                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
get_ptr() const19580     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19581     {
19582         // delegate the call to get_impl_ptr<>() const
19583         return get_impl_ptr(static_cast<PointerType>(nullptr));
19584     }
19585 
19586     /*!
19587     @brief get a pointer value (explicit)
19588 
19589     Explicit pointer access to the internally stored JSON value. No copies are
19590     made.
19591 
19592     @warning The pointer becomes invalid if the underlying JSON object
19593     changes.
19594 
19595     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19596     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19597     @ref number_unsigned_t, or @ref number_float_t.
19598 
19599     @return pointer to the internally stored JSON value if the requested
19600     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19601 
19602     @complexity Constant.
19603 
19604     @liveexample{The example below shows how pointers to internal values of a
19605     JSON value can be requested. Note that no type conversions are made and a
19606     `nullptr` is returned if the value and the requested pointer type does not
19607     match.,get__PointerType}
19608 
19609     @sa @ref get_ptr() for explicit pointer-member access
19610 
19611     @since version 1.0.0
19612     */
19613     template<typename PointerType, typename std::enable_if<
19614                  std::is_pointer<PointerType>::value, int>::type = 0>
get()19615     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19616     {
19617         // delegate the call to get_ptr
19618         return get_ptr<PointerType>();
19619     }
19620 
19621     /*!
19622     @brief get a pointer value (explicit)
19623     @copydoc get()
19624     */
19625     template<typename PointerType, typename std::enable_if<
19626                  std::is_pointer<PointerType>::value, int>::type = 0>
get() const19627     constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19628     {
19629         // delegate the call to get_ptr
19630         return get_ptr<PointerType>();
19631     }
19632 
19633     /*!
19634     @brief get a reference value (implicit)
19635 
19636     Implicit reference access to the internally stored JSON value. No copies
19637     are made.
19638 
19639     @warning Writing data to the referee of the result yields an undefined
19640     state.
19641 
19642     @tparam ReferenceType reference type; must be a reference to @ref array_t,
19643     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
19644     @ref number_float_t. Enforced by static assertion.
19645 
19646     @return reference to the internally stored JSON value if the requested
19647     reference type @a ReferenceType fits to the JSON value; throws
19648     type_error.303 otherwise
19649 
19650     @throw type_error.303 in case passed type @a ReferenceType is incompatible
19651     with the stored JSON value; see example below
19652 
19653     @complexity Constant.
19654 
19655     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
19656 
19657     @since version 1.1.0
19658     */
19659     template<typename ReferenceType, typename std::enable_if<
19660                  std::is_reference<ReferenceType>::value, int>::type = 0>
19661     ReferenceType get_ref()
19662     {
19663         // delegate call to get_ref_impl
19664         return get_ref_impl<ReferenceType>(*this);
19665     }
19666 
19667     /*!
19668     @brief get a reference value (implicit)
19669     @copydoc get_ref()
19670     */
19671     template < typename ReferenceType, typename std::enable_if <
19672                    std::is_reference<ReferenceType>::value&&
19673                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19674     ReferenceType get_ref() const
19675     {
19676         // delegate call to get_ref_impl
19677         return get_ref_impl<ReferenceType>(*this);
19678     }
19679 
19680     /*!
19681     @brief get a value (implicit)
19682 
19683     Implicit type conversion between the JSON value and a compatible value.
19684     The call is realized by calling @ref get() const.
19685 
19686     @tparam ValueType non-pointer type compatible to the JSON value, for
19687     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
19688     `std::vector` types for JSON arrays. The character type of @ref string_t
19689     as well as an initializer list of this type is excluded to avoid
19690     ambiguities as these types implicitly convert to `std::string`.
19691 
19692     @return copy of the JSON value, converted to type @a ValueType
19693 
19694     @throw type_error.302 in case passed type @a ValueType is incompatible
19695     to the JSON value type (e.g., the JSON value is of type boolean, but a
19696     string is requested); see example below
19697 
19698     @complexity Linear in the size of the JSON value.
19699 
19700     @liveexample{The example below shows several conversions from JSON values
19701     to other types. There a few things to note: (1) Floating-point numbers can
19702     be converted to integers\, (2) A JSON array can be converted to a standard
19703     `std::vector<short>`\, (3) A JSON object can be converted to C++
19704     associative containers such as `std::unordered_map<std::string\,
19705     json>`.,operator__ValueType}
19706 
19707     @since version 1.0.0
19708     */
19709     template < typename ValueType, typename std::enable_if <
19710                    !std::is_pointer<ValueType>::value&&
19711                    !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19712                    !std::is_same<ValueType, typename string_t::value_type>::value&&
19713                    !detail::is_basic_json<ValueType>::value
19714                    && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19715 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19716                    && !std::is_same<ValueType, typename std::string_view>::value
19717 #endif
19718                    && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19719                    , int >::type = 0 >
operator ValueType() const19720     JSON_EXPLICIT operator ValueType() const
19721     {
19722         // delegate the call to get<>() const
19723         return get<ValueType>();
19724     }
19725 
19726     /*!
19727     @return reference to the binary value
19728 
19729     @throw type_error.302 if the value is not binary
19730 
19731     @sa @ref is_binary() to check if the value is binary
19732 
19733     @since version 3.8.0
19734     */
get_binary()19735     binary_t& get_binary()
19736     {
19737         if (!is_binary())
19738         {
19739             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19740         }
19741 
19742         return *get_ptr<binary_t*>();
19743     }
19744 
19745     /// @copydoc get_binary()
get_binary() const19746     const binary_t& get_binary() const
19747     {
19748         if (!is_binary())
19749         {
19750             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19751         }
19752 
19753         return *get_ptr<const binary_t*>();
19754     }
19755 
19756     /// @}
19757 
19758 
19759     ////////////////////
19760     // element access //
19761     ////////////////////
19762 
19763     /// @name element access
19764     /// Access to the JSON value.
19765     /// @{
19766 
19767     /*!
19768     @brief access specified array element with bounds checking
19769 
19770     Returns a reference to the element at specified location @a idx, with
19771     bounds checking.
19772 
19773     @param[in] idx  index of the element to access
19774 
19775     @return reference to the element at index @a idx
19776 
19777     @throw type_error.304 if the JSON value is not an array; in this case,
19778     calling `at` with an index makes no sense. See example below.
19779     @throw out_of_range.401 if the index @a idx is out of range of the array;
19780     that is, `idx >= size()`. See example below.
19781 
19782     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19783     changes in the JSON value.
19784 
19785     @complexity Constant.
19786 
19787     @since version 1.0.0
19788 
19789     @liveexample{The example below shows how array elements can be read and
19790     written using `at()`. It also demonstrates the different exceptions that
19791     can be thrown.,at__size_type}
19792     */
at(size_type idx)19793     reference at(size_type idx)
19794     {
19795         // at only works for arrays
19796         if (JSON_HEDLEY_LIKELY(is_array()))
19797         {
19798             JSON_TRY
19799             {
19800                 return m_value.array->at(idx);
19801             }
19802             JSON_CATCH (std::out_of_range&)
19803             {
19804                 // create better exception explanation
19805                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19806             }
19807         }
19808         else
19809         {
19810             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19811         }
19812     }
19813 
19814     /*!
19815     @brief access specified array element with bounds checking
19816 
19817     Returns a const reference to the element at specified location @a idx,
19818     with bounds checking.
19819 
19820     @param[in] idx  index of the element to access
19821 
19822     @return const reference to the element at index @a idx
19823 
19824     @throw type_error.304 if the JSON value is not an array; in this case,
19825     calling `at` with an index makes no sense. See example below.
19826     @throw out_of_range.401 if the index @a idx is out of range of the array;
19827     that is, `idx >= size()`. See example below.
19828 
19829     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19830     changes in the JSON value.
19831 
19832     @complexity Constant.
19833 
19834     @since version 1.0.0
19835 
19836     @liveexample{The example below shows how array elements can be read using
19837     `at()`. It also demonstrates the different exceptions that can be thrown.,
19838     at__size_type_const}
19839     */
at(size_type idx) const19840     const_reference at(size_type idx) const
19841     {
19842         // at only works for arrays
19843         if (JSON_HEDLEY_LIKELY(is_array()))
19844         {
19845             JSON_TRY
19846             {
19847                 return m_value.array->at(idx);
19848             }
19849             JSON_CATCH (std::out_of_range&)
19850             {
19851                 // create better exception explanation
19852                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19853             }
19854         }
19855         else
19856         {
19857             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19858         }
19859     }
19860 
19861     /*!
19862     @brief access specified object element with bounds checking
19863 
19864     Returns a reference to the element at with specified key @a key, with
19865     bounds checking.
19866 
19867     @param[in] key  key of the element to access
19868 
19869     @return reference to the element at key @a key
19870 
19871     @throw type_error.304 if the JSON value is not an object; in this case,
19872     calling `at` with a key makes no sense. See example below.
19873     @throw out_of_range.403 if the key @a key is is not stored in the object;
19874     that is, `find(key) == end()`. See example below.
19875 
19876     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19877     changes in the JSON value.
19878 
19879     @complexity Logarithmic in the size of the container.
19880 
19881     @sa @ref operator[](const typename object_t::key_type&) for unchecked
19882     access by reference
19883     @sa @ref value() for access by value with a default value
19884 
19885     @since version 1.0.0
19886 
19887     @liveexample{The example below shows how object elements can be read and
19888     written using `at()`. It also demonstrates the different exceptions that
19889     can be thrown.,at__object_t_key_type}
19890     */
at(const typename object_t::key_type & key)19891     reference at(const typename object_t::key_type& key)
19892     {
19893         // at only works for objects
19894         if (JSON_HEDLEY_LIKELY(is_object()))
19895         {
19896             JSON_TRY
19897             {
19898                 return m_value.object->at(key);
19899             }
19900             JSON_CATCH (std::out_of_range&)
19901             {
19902                 // create better exception explanation
19903                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19904             }
19905         }
19906         else
19907         {
19908             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19909         }
19910     }
19911 
19912     /*!
19913     @brief access specified object element with bounds checking
19914 
19915     Returns a const reference to the element at with specified key @a key,
19916     with bounds checking.
19917 
19918     @param[in] key  key of the element to access
19919 
19920     @return const reference to the element at key @a key
19921 
19922     @throw type_error.304 if the JSON value is not an object; in this case,
19923     calling `at` with a key makes no sense. See example below.
19924     @throw out_of_range.403 if the key @a key is is not stored in the object;
19925     that is, `find(key) == end()`. See example below.
19926 
19927     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19928     changes in the JSON value.
19929 
19930     @complexity Logarithmic in the size of the container.
19931 
19932     @sa @ref operator[](const typename object_t::key_type&) for unchecked
19933     access by reference
19934     @sa @ref value() for access by value with a default value
19935 
19936     @since version 1.0.0
19937 
19938     @liveexample{The example below shows how object elements can be read using
19939     `at()`. It also demonstrates the different exceptions that can be thrown.,
19940     at__object_t_key_type_const}
19941     */
at(const typename object_t::key_type & key) const19942     const_reference at(const typename object_t::key_type& key) const
19943     {
19944         // at only works for objects
19945         if (JSON_HEDLEY_LIKELY(is_object()))
19946         {
19947             JSON_TRY
19948             {
19949                 return m_value.object->at(key);
19950             }
19951             JSON_CATCH (std::out_of_range&)
19952             {
19953                 // create better exception explanation
19954                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19955             }
19956         }
19957         else
19958         {
19959             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19960         }
19961     }
19962 
19963     /*!
19964     @brief access specified array element
19965 
19966     Returns a reference to the element at specified location @a idx.
19967 
19968     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
19969     then the array is silently filled up with `null` values to make `idx` a
19970     valid reference to the last stored element.
19971 
19972     @param[in] idx  index of the element to access
19973 
19974     @return reference to the element at index @a idx
19975 
19976     @throw type_error.305 if the JSON value is not an array or null; in that
19977     cases, using the [] operator with an index makes no sense.
19978 
19979     @complexity Constant if @a idx is in the range of the array. Otherwise
19980     linear in `idx - size()`.
19981 
19982     @liveexample{The example below shows how array elements can be read and
19983     written using `[]` operator. Note the addition of `null`
19984     values.,operatorarray__size_type}
19985 
19986     @since version 1.0.0
19987     */
operator [](size_type idx)19988     reference operator[](size_type idx)
19989     {
19990         // implicitly convert null value to an empty array
19991         if (is_null())
19992         {
19993             m_type = value_t::array;
19994             m_value.array = create<array_t>();
19995             assert_invariant();
19996         }
19997 
19998         // operator[] only works for arrays
19999         if (JSON_HEDLEY_LIKELY(is_array()))
20000         {
20001             // fill up array with null values if given idx is outside range
20002             if (idx >= m_value.array->size())
20003             {
20004                 m_value.array->insert(m_value.array->end(),
20005                                       idx - m_value.array->size() + 1,
20006                                       basic_json());
20007             }
20008 
20009             return m_value.array->operator[](idx);
20010         }
20011 
20012         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20013     }
20014 
20015     /*!
20016     @brief access specified array element
20017 
20018     Returns a const reference to the element at specified location @a idx.
20019 
20020     @param[in] idx  index of the element to access
20021 
20022     @return const reference to the element at index @a idx
20023 
20024     @throw type_error.305 if the JSON value is not an array; in that case,
20025     using the [] operator with an index makes no sense.
20026 
20027     @complexity Constant.
20028 
20029     @liveexample{The example below shows how array elements can be read using
20030     the `[]` operator.,operatorarray__size_type_const}
20031 
20032     @since version 1.0.0
20033     */
operator [](size_type idx) const20034     const_reference operator[](size_type idx) const
20035     {
20036         // const operator[] only works for arrays
20037         if (JSON_HEDLEY_LIKELY(is_array()))
20038         {
20039             return m_value.array->operator[](idx);
20040         }
20041 
20042         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20043     }
20044 
20045     /*!
20046     @brief access specified object element
20047 
20048     Returns a reference to the element at with specified key @a key.
20049 
20050     @note If @a key is not found in the object, then it is silently added to
20051     the object and filled with a `null` value to make `key` a valid reference.
20052     In case the value was `null` before, it is converted to an object.
20053 
20054     @param[in] key  key of the element to access
20055 
20056     @return reference to the element at key @a key
20057 
20058     @throw type_error.305 if the JSON value is not an object or null; in that
20059     cases, using the [] operator with a key makes no sense.
20060 
20061     @complexity Logarithmic in the size of the container.
20062 
20063     @liveexample{The example below shows how object elements can be read and
20064     written using the `[]` operator.,operatorarray__key_type}
20065 
20066     @sa @ref at(const typename object_t::key_type&) for access by reference
20067     with range checking
20068     @sa @ref value() for access by value with a default value
20069 
20070     @since version 1.0.0
20071     */
operator [](const typename object_t::key_type & key)20072     reference operator[](const typename object_t::key_type& key)
20073     {
20074         // implicitly convert null value to an empty object
20075         if (is_null())
20076         {
20077             m_type = value_t::object;
20078             m_value.object = create<object_t>();
20079             assert_invariant();
20080         }
20081 
20082         // operator[] only works for objects
20083         if (JSON_HEDLEY_LIKELY(is_object()))
20084         {
20085             return m_value.object->operator[](key);
20086         }
20087 
20088         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20089     }
20090 
20091     /*!
20092     @brief read-only access specified object element
20093 
20094     Returns a const reference to the element at with specified key @a key. No
20095     bounds checking is performed.
20096 
20097     @warning If the element with key @a key does not exist, the behavior is
20098     undefined.
20099 
20100     @param[in] key  key of the element to access
20101 
20102     @return const reference to the element at key @a key
20103 
20104     @pre The element with key @a key must exist. **This precondition is
20105          enforced with an assertion.**
20106 
20107     @throw type_error.305 if the JSON value is not an object; in that case,
20108     using the [] operator with a key makes no sense.
20109 
20110     @complexity Logarithmic in the size of the container.
20111 
20112     @liveexample{The example below shows how object elements can be read using
20113     the `[]` operator.,operatorarray__key_type_const}
20114 
20115     @sa @ref at(const typename object_t::key_type&) for access by reference
20116     with range checking
20117     @sa @ref value() for access by value with a default value
20118 
20119     @since version 1.0.0
20120     */
operator [](const typename object_t::key_type & key) const20121     const_reference operator[](const typename object_t::key_type& key) const
20122     {
20123         // const operator[] only works for objects
20124         if (JSON_HEDLEY_LIKELY(is_object()))
20125         {
20126             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20127             return m_value.object->find(key)->second;
20128         }
20129 
20130         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20131     }
20132 
20133     /*!
20134     @brief access specified object element
20135 
20136     Returns a reference to the element at with specified key @a key.
20137 
20138     @note If @a key is not found in the object, then it is silently added to
20139     the object and filled with a `null` value to make `key` a valid reference.
20140     In case the value was `null` before, it is converted to an object.
20141 
20142     @param[in] key  key of the element to access
20143 
20144     @return reference to the element at key @a key
20145 
20146     @throw type_error.305 if the JSON value is not an object or null; in that
20147     cases, using the [] operator with a key makes no sense.
20148 
20149     @complexity Logarithmic in the size of the container.
20150 
20151     @liveexample{The example below shows how object elements can be read and
20152     written using the `[]` operator.,operatorarray__key_type}
20153 
20154     @sa @ref at(const typename object_t::key_type&) for access by reference
20155     with range checking
20156     @sa @ref value() for access by value with a default value
20157 
20158     @since version 1.1.0
20159     */
20160     template<typename T>
20161     JSON_HEDLEY_NON_NULL(2)
operator [](T * key)20162     reference operator[](T* key)
20163     {
20164         // implicitly convert null to object
20165         if (is_null())
20166         {
20167             m_type = value_t::object;
20168             m_value = value_t::object;
20169             assert_invariant();
20170         }
20171 
20172         // at only works for objects
20173         if (JSON_HEDLEY_LIKELY(is_object()))
20174         {
20175             return m_value.object->operator[](key);
20176         }
20177 
20178         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20179     }
20180 
20181     /*!
20182     @brief read-only access specified object element
20183 
20184     Returns a const reference to the element at with specified key @a key. No
20185     bounds checking is performed.
20186 
20187     @warning If the element with key @a key does not exist, the behavior is
20188     undefined.
20189 
20190     @param[in] key  key of the element to access
20191 
20192     @return const reference to the element at key @a key
20193 
20194     @pre The element with key @a key must exist. **This precondition is
20195          enforced with an assertion.**
20196 
20197     @throw type_error.305 if the JSON value is not an object; in that case,
20198     using the [] operator with a key makes no sense.
20199 
20200     @complexity Logarithmic in the size of the container.
20201 
20202     @liveexample{The example below shows how object elements can be read using
20203     the `[]` operator.,operatorarray__key_type_const}
20204 
20205     @sa @ref at(const typename object_t::key_type&) for access by reference
20206     with range checking
20207     @sa @ref value() for access by value with a default value
20208 
20209     @since version 1.1.0
20210     */
20211     template<typename T>
20212     JSON_HEDLEY_NON_NULL(2)
operator [](T * key) const20213     const_reference operator[](T* key) const
20214     {
20215         // at only works for objects
20216         if (JSON_HEDLEY_LIKELY(is_object()))
20217         {
20218             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20219             return m_value.object->find(key)->second;
20220         }
20221 
20222         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20223     }
20224 
20225     /*!
20226     @brief access specified object element with default value
20227 
20228     Returns either a copy of an object's element at the specified key @a key
20229     or a given default value if no element with key @a key exists.
20230 
20231     The function is basically equivalent to executing
20232     @code {.cpp}
20233     try {
20234         return at(key);
20235     } catch(out_of_range) {
20236         return default_value;
20237     }
20238     @endcode
20239 
20240     @note Unlike @ref at(const typename object_t::key_type&), this function
20241     does not throw if the given key @a key was not found.
20242 
20243     @note Unlike @ref operator[](const typename object_t::key_type& key), this
20244     function does not implicitly add an element to the position defined by @a
20245     key. This function is furthermore also applicable to const objects.
20246 
20247     @param[in] key  key of the element to access
20248     @param[in] default_value  the value to return if @a key is not found
20249 
20250     @tparam ValueType type compatible to JSON values, for instance `int` for
20251     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20252     JSON arrays. Note the type of the expected value at @a key and the default
20253     value @a default_value must be compatible.
20254 
20255     @return copy of the element at key @a key or @a default_value if @a key
20256     is not found
20257 
20258     @throw type_error.302 if @a default_value does not match the type of the
20259     value at @a key
20260     @throw type_error.306 if the JSON value is not an object; in that case,
20261     using `value()` with a key makes no sense.
20262 
20263     @complexity Logarithmic in the size of the container.
20264 
20265     @liveexample{The example below shows how object elements can be queried
20266     with a default value.,basic_json__value}
20267 
20268     @sa @ref at(const typename object_t::key_type&) for access by reference
20269     with range checking
20270     @sa @ref operator[](const typename object_t::key_type&) for unchecked
20271     access by reference
20272 
20273     @since version 1.0.0
20274     */
20275     // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20276     template < class ValueType, typename std::enable_if <
20277                    detail::is_getable<basic_json_t, ValueType>::value
20278                    && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20279     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20280     {
20281         // at only works for objects
20282         if (JSON_HEDLEY_LIKELY(is_object()))
20283         {
20284             // if key is found, return value and given default value otherwise
20285             const auto it = find(key);
20286             if (it != end())
20287             {
20288                 return it->template get<ValueType>();
20289             }
20290 
20291             return default_value;
20292         }
20293 
20294         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20295     }
20296 
20297     /*!
20298     @brief overload for a default value of type const char*
20299     @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
20300     */
value(const typename object_t::key_type & key,const char * default_value) const20301     string_t value(const typename object_t::key_type& key, const char* default_value) const
20302     {
20303         return value(key, string_t(default_value));
20304     }
20305 
20306     /*!
20307     @brief access specified object element via JSON Pointer with default value
20308 
20309     Returns either a copy of an object's element at the specified key @a key
20310     or a given default value if no element with key @a key exists.
20311 
20312     The function is basically equivalent to executing
20313     @code {.cpp}
20314     try {
20315         return at(ptr);
20316     } catch(out_of_range) {
20317         return default_value;
20318     }
20319     @endcode
20320 
20321     @note Unlike @ref at(const json_pointer&), this function does not throw
20322     if the given key @a key was not found.
20323 
20324     @param[in] ptr  a JSON pointer to the element to access
20325     @param[in] default_value  the value to return if @a ptr found no value
20326 
20327     @tparam ValueType type compatible to JSON values, for instance `int` for
20328     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20329     JSON arrays. Note the type of the expected value at @a key and the default
20330     value @a default_value must be compatible.
20331 
20332     @return copy of the element at key @a key or @a default_value if @a key
20333     is not found
20334 
20335     @throw type_error.302 if @a default_value does not match the type of the
20336     value at @a ptr
20337     @throw type_error.306 if the JSON value is not an object; in that case,
20338     using `value()` with a key makes no sense.
20339 
20340     @complexity Logarithmic in the size of the container.
20341 
20342     @liveexample{The example below shows how object elements can be queried
20343     with a default value.,basic_json__value_ptr}
20344 
20345     @sa @ref operator[](const json_pointer&) for unchecked access by reference
20346 
20347     @since version 2.0.2
20348     */
20349     template<class ValueType, typename std::enable_if<
20350                  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20351     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20352     {
20353         // at only works for objects
20354         if (JSON_HEDLEY_LIKELY(is_object()))
20355         {
20356             // if pointer resolves a value, return it or use default value
20357             JSON_TRY
20358             {
20359                 return ptr.get_checked(this).template get<ValueType>();
20360             }
20361             JSON_INTERNAL_CATCH (out_of_range&)
20362             {
20363                 return default_value;
20364             }
20365         }
20366 
20367         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20368     }
20369 
20370     /*!
20371     @brief overload for a default value of type const char*
20372     @copydoc basic_json::value(const json_pointer&, ValueType) const
20373     */
20374     JSON_HEDLEY_NON_NULL(3)
value(const json_pointer & ptr,const char * default_value) const20375     string_t value(const json_pointer& ptr, const char* default_value) const
20376     {
20377         return value(ptr, string_t(default_value));
20378     }
20379 
20380     /*!
20381     @brief access the first element
20382 
20383     Returns a reference to the first element in the container. For a JSON
20384     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
20385 
20386     @return In case of a structured type (array or object), a reference to the
20387     first element is returned. In case of number, string, boolean, or binary
20388     values, a reference to the value is returned.
20389 
20390     @complexity Constant.
20391 
20392     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20393     or an empty array or object (undefined behavior, **guarded by
20394     assertions**).
20395     @post The JSON value remains unchanged.
20396 
20397     @throw invalid_iterator.214 when called on `null` value
20398 
20399     @liveexample{The following code shows an example for `front()`.,front}
20400 
20401     @sa @ref back() -- access the last element
20402 
20403     @since version 1.0.0
20404     */
front()20405     reference front()
20406     {
20407         return *begin();
20408     }
20409 
20410     /*!
20411     @copydoc basic_json::front()
20412     */
front() const20413     const_reference front() const
20414     {
20415         return *cbegin();
20416     }
20417 
20418     /*!
20419     @brief access the last element
20420 
20421     Returns a reference to the last element in the container. For a JSON
20422     container `c`, the expression `c.back()` is equivalent to
20423     @code {.cpp}
20424     auto tmp = c.end();
20425     --tmp;
20426     return *tmp;
20427     @endcode
20428 
20429     @return In case of a structured type (array or object), a reference to the
20430     last element is returned. In case of number, string, boolean, or binary
20431     values, a reference to the value is returned.
20432 
20433     @complexity Constant.
20434 
20435     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20436     or an empty array or object (undefined behavior, **guarded by
20437     assertions**).
20438     @post The JSON value remains unchanged.
20439 
20440     @throw invalid_iterator.214 when called on a `null` value. See example
20441     below.
20442 
20443     @liveexample{The following code shows an example for `back()`.,back}
20444 
20445     @sa @ref front() -- access the first element
20446 
20447     @since version 1.0.0
20448     */
back()20449     reference back()
20450     {
20451         auto tmp = end();
20452         --tmp;
20453         return *tmp;
20454     }
20455 
20456     /*!
20457     @copydoc basic_json::back()
20458     */
back() const20459     const_reference back() const
20460     {
20461         auto tmp = cend();
20462         --tmp;
20463         return *tmp;
20464     }
20465 
20466     /*!
20467     @brief remove element given an iterator
20468 
20469     Removes the element specified by iterator @a pos. The iterator @a pos must
20470     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
20471     but is not dereferenceable) cannot be used as a value for @a pos.
20472 
20473     If called on a primitive type other than `null`, the resulting JSON value
20474     will be `null`.
20475 
20476     @param[in] pos iterator to the element to remove
20477     @return Iterator following the last removed element. If the iterator @a
20478     pos refers to the last element, the `end()` iterator is returned.
20479 
20480     @tparam IteratorType an @ref iterator or @ref const_iterator
20481 
20482     @post Invalidates iterators and references at or after the point of the
20483     erase, including the `end()` iterator.
20484 
20485     @throw type_error.307 if called on a `null` value; example: `"cannot use
20486     erase() with null"`
20487     @throw invalid_iterator.202 if called on an iterator which does not belong
20488     to the current JSON value; example: `"iterator does not fit current
20489     value"`
20490     @throw invalid_iterator.205 if called on a primitive type with invalid
20491     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
20492     out of range"`
20493 
20494     @complexity The complexity depends on the type:
20495     - objects: amortized constant
20496     - arrays: linear in distance between @a pos and the end of the container
20497     - strings and binary: linear in the length of the member
20498     - other types: constant
20499 
20500     @liveexample{The example shows the result of `erase()` for different JSON
20501     types.,erase__IteratorType}
20502 
20503     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20504     the given range
20505     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20506     from an object at the given key
20507     @sa @ref erase(const size_type) -- removes the element from an array at
20508     the given index
20509 
20510     @since version 1.0.0
20511     */
20512     template < class IteratorType, typename std::enable_if <
20513                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20514                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20515                = 0 >
20516     IteratorType erase(IteratorType pos)
20517     {
20518         // make sure iterator fits the current value
20519         if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20520         {
20521             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20522         }
20523 
20524         IteratorType result = end();
20525 
20526         switch (m_type)
20527         {
20528             case value_t::boolean:
20529             case value_t::number_float:
20530             case value_t::number_integer:
20531             case value_t::number_unsigned:
20532             case value_t::string:
20533             case value_t::binary:
20534             {
20535                 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20536                 {
20537                     JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20538                 }
20539 
20540                 if (is_string())
20541                 {
20542                     AllocatorType<string_t> alloc;
20543                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20544                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20545                     m_value.string = nullptr;
20546                 }
20547                 else if (is_binary())
20548                 {
20549                     AllocatorType<binary_t> alloc;
20550                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20551                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20552                     m_value.binary = nullptr;
20553                 }
20554 
20555                 m_type = value_t::null;
20556                 assert_invariant();
20557                 break;
20558             }
20559 
20560             case value_t::object:
20561             {
20562                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20563                 break;
20564             }
20565 
20566             case value_t::array:
20567             {
20568                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20569                 break;
20570             }
20571 
20572             default:
20573                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20574         }
20575 
20576         return result;
20577     }
20578 
20579     /*!
20580     @brief remove elements given an iterator range
20581 
20582     Removes the element specified by the range `[first; last)`. The iterator
20583     @a first does not need to be dereferenceable if `first == last`: erasing
20584     an empty range is a no-op.
20585 
20586     If called on a primitive type other than `null`, the resulting JSON value
20587     will be `null`.
20588 
20589     @param[in] first iterator to the beginning of the range to remove
20590     @param[in] last iterator past the end of the range to remove
20591     @return Iterator following the last removed element. If the iterator @a
20592     second refers to the last element, the `end()` iterator is returned.
20593 
20594     @tparam IteratorType an @ref iterator or @ref const_iterator
20595 
20596     @post Invalidates iterators and references at or after the point of the
20597     erase, including the `end()` iterator.
20598 
20599     @throw type_error.307 if called on a `null` value; example: `"cannot use
20600     erase() with null"`
20601     @throw invalid_iterator.203 if called on iterators which does not belong
20602     to the current JSON value; example: `"iterators do not fit current value"`
20603     @throw invalid_iterator.204 if called on a primitive type with invalid
20604     iterators (i.e., if `first != begin()` and `last != end()`); example:
20605     `"iterators out of range"`
20606 
20607     @complexity The complexity depends on the type:
20608     - objects: `log(size()) + std::distance(first, last)`
20609     - arrays: linear in the distance between @a first and @a last, plus linear
20610       in the distance between @a last and end of the container
20611     - strings and binary: linear in the length of the member
20612     - other types: constant
20613 
20614     @liveexample{The example shows the result of `erase()` for different JSON
20615     types.,erase__IteratorType_IteratorType}
20616 
20617     @sa @ref erase(IteratorType) -- removes the element at a given position
20618     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20619     from an object at the given key
20620     @sa @ref erase(const size_type) -- removes the element from an array at
20621     the given index
20622 
20623     @since version 1.0.0
20624     */
20625     template < class IteratorType, typename std::enable_if <
20626                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20627                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20628                = 0 >
20629     IteratorType erase(IteratorType first, IteratorType last)
20630     {
20631         // make sure iterator fits the current value
20632         if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20633         {
20634             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20635         }
20636 
20637         IteratorType result = end();
20638 
20639         switch (m_type)
20640         {
20641             case value_t::boolean:
20642             case value_t::number_float:
20643             case value_t::number_integer:
20644             case value_t::number_unsigned:
20645             case value_t::string:
20646             case value_t::binary:
20647             {
20648                 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20649                                        || !last.m_it.primitive_iterator.is_end()))
20650                 {
20651                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20652                 }
20653 
20654                 if (is_string())
20655                 {
20656                     AllocatorType<string_t> alloc;
20657                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20658                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20659                     m_value.string = nullptr;
20660                 }
20661                 else if (is_binary())
20662                 {
20663                     AllocatorType<binary_t> alloc;
20664                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20665                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20666                     m_value.binary = nullptr;
20667                 }
20668 
20669                 m_type = value_t::null;
20670                 assert_invariant();
20671                 break;
20672             }
20673 
20674             case value_t::object:
20675             {
20676                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20677                                               last.m_it.object_iterator);
20678                 break;
20679             }
20680 
20681             case value_t::array:
20682             {
20683                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20684                                              last.m_it.array_iterator);
20685                 break;
20686             }
20687 
20688             default:
20689                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20690         }
20691 
20692         return result;
20693     }
20694 
20695     /*!
20696     @brief remove element from a JSON object given a key
20697 
20698     Removes elements from a JSON object with the key value @a key.
20699 
20700     @param[in] key value of the elements to remove
20701 
20702     @return Number of elements removed. If @a ObjectType is the default
20703     `std::map` type, the return value will always be `0` (@a key was not
20704     found) or `1` (@a key was found).
20705 
20706     @post References and iterators to the erased elements are invalidated.
20707     Other references and iterators are not affected.
20708 
20709     @throw type_error.307 when called on a type other than JSON object;
20710     example: `"cannot use erase() with null"`
20711 
20712     @complexity `log(size()) + count(key)`
20713 
20714     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
20715 
20716     @sa @ref erase(IteratorType) -- removes the element at a given position
20717     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20718     the given range
20719     @sa @ref erase(const size_type) -- removes the element from an array at
20720     the given index
20721 
20722     @since version 1.0.0
20723     */
erase(const typename object_t::key_type & key)20724     size_type erase(const typename object_t::key_type& key)
20725     {
20726         // this erase only works for objects
20727         if (JSON_HEDLEY_LIKELY(is_object()))
20728         {
20729             return m_value.object->erase(key);
20730         }
20731 
20732         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20733     }
20734 
20735     /*!
20736     @brief remove element from a JSON array given an index
20737 
20738     Removes element from a JSON array at the index @a idx.
20739 
20740     @param[in] idx index of the element to remove
20741 
20742     @throw type_error.307 when called on a type other than JSON object;
20743     example: `"cannot use erase() with null"`
20744     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
20745     is out of range"`
20746 
20747     @complexity Linear in distance between @a idx and the end of the container.
20748 
20749     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
20750 
20751     @sa @ref erase(IteratorType) -- removes the element at a given position
20752     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20753     the given range
20754     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20755     from an object at the given key
20756 
20757     @since version 1.0.0
20758     */
erase(const size_type idx)20759     void erase(const size_type idx)
20760     {
20761         // this erase only works for arrays
20762         if (JSON_HEDLEY_LIKELY(is_array()))
20763         {
20764             if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20765             {
20766                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20767             }
20768 
20769             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20770         }
20771         else
20772         {
20773             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20774         }
20775     }
20776 
20777     /// @}
20778 
20779 
20780     ////////////
20781     // lookup //
20782     ////////////
20783 
20784     /// @name lookup
20785     /// @{
20786 
20787     /*!
20788     @brief find an element in a JSON object
20789 
20790     Finds an element in a JSON object with key equivalent to @a key. If the
20791     element is not found or the JSON value is not an object, end() is
20792     returned.
20793 
20794     @note This method always returns @ref end() when executed on a JSON type
20795           that is not an object.
20796 
20797     @param[in] key key value of the element to search for.
20798 
20799     @return Iterator to an element with key equivalent to @a key. If no such
20800     element is found or the JSON value is not an object, past-the-end (see
20801     @ref end()) iterator is returned.
20802 
20803     @complexity Logarithmic in the size of the JSON object.
20804 
20805     @liveexample{The example shows how `find()` is used.,find__key_type}
20806 
20807     @sa @ref contains(KeyT&&) const -- checks whether a key exists
20808 
20809     @since version 1.0.0
20810     */
20811     template<typename KeyT>
find(KeyT && key)20812     iterator find(KeyT&& key)
20813     {
20814         auto result = end();
20815 
20816         if (is_object())
20817         {
20818             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20819         }
20820 
20821         return result;
20822     }
20823 
20824     /*!
20825     @brief find an element in a JSON object
20826     @copydoc find(KeyT&&)
20827     */
20828     template<typename KeyT>
find(KeyT && key) const20829     const_iterator find(KeyT&& key) const
20830     {
20831         auto result = cend();
20832 
20833         if (is_object())
20834         {
20835             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20836         }
20837 
20838         return result;
20839     }
20840 
20841     /*!
20842     @brief returns the number of occurrences of a key in a JSON object
20843 
20844     Returns the number of elements with key @a key. If ObjectType is the
20845     default `std::map` type, the return value will always be `0` (@a key was
20846     not found) or `1` (@a key was found).
20847 
20848     @note This method always returns `0` when executed on a JSON type that is
20849           not an object.
20850 
20851     @param[in] key key value of the element to count
20852 
20853     @return Number of elements with key @a key. If the JSON value is not an
20854     object, the return value will be `0`.
20855 
20856     @complexity Logarithmic in the size of the JSON object.
20857 
20858     @liveexample{The example shows how `count()` is used.,count}
20859 
20860     @since version 1.0.0
20861     */
20862     template<typename KeyT>
count(KeyT && key) const20863     size_type count(KeyT&& key) const
20864     {
20865         // return 0 for all nonobject types
20866         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20867     }
20868 
20869     /*!
20870     @brief check the existence of an element in a JSON object
20871 
20872     Check whether an element exists in a JSON object with key equivalent to
20873     @a key. If the element is not found or the JSON value is not an object,
20874     false is returned.
20875 
20876     @note This method always returns false when executed on a JSON type
20877           that is not an object.
20878 
20879     @param[in] key key value to check its existence.
20880 
20881     @return true if an element with specified @a key exists. If no such
20882     element with such key is found or the JSON value is not an object,
20883     false is returned.
20884 
20885     @complexity Logarithmic in the size of the JSON object.
20886 
20887     @liveexample{The following code shows an example for `contains()`.,contains}
20888 
20889     @sa @ref find(KeyT&&) -- returns an iterator to an object element
20890     @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
20891 
20892     @since version 3.6.0
20893     */
20894     template < typename KeyT, typename std::enable_if <
20895                    !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
contains(KeyT && key) const20896     bool contains(KeyT && key) const
20897     {
20898         return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20899     }
20900 
20901     /*!
20902     @brief check the existence of an element in a JSON object given a JSON pointer
20903 
20904     Check whether the given JSON pointer @a ptr can be resolved in the current
20905     JSON value.
20906 
20907     @note This method can be executed on any JSON value type.
20908 
20909     @param[in] ptr JSON pointer to check its existence.
20910 
20911     @return true if the JSON pointer can be resolved to a stored value, false
20912     otherwise.
20913 
20914     @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
20915 
20916     @throw parse_error.106   if an array index begins with '0'
20917     @throw parse_error.109   if an array index was not a number
20918 
20919     @complexity Logarithmic in the size of the JSON object.
20920 
20921     @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
20922 
20923     @sa @ref contains(KeyT &&) const -- checks the existence of a key
20924 
20925     @since version 3.7.0
20926     */
contains(const json_pointer & ptr) const20927     bool contains(const json_pointer& ptr) const
20928     {
20929         return ptr.contains(this);
20930     }
20931 
20932     /// @}
20933 
20934 
20935     ///////////////
20936     // iterators //
20937     ///////////////
20938 
20939     /// @name iterators
20940     /// @{
20941 
20942     /*!
20943     @brief returns an iterator to the first element
20944 
20945     Returns an iterator to the first element.
20946 
20947     @image html range-begin-end.svg "Illustration from cppreference.com"
20948 
20949     @return iterator to the first element
20950 
20951     @complexity Constant.
20952 
20953     @requirement This function helps `basic_json` satisfying the
20954     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
20955     requirements:
20956     - The complexity is constant.
20957 
20958     @liveexample{The following code shows an example for `begin()`.,begin}
20959 
20960     @sa @ref cbegin() -- returns a const iterator to the beginning
20961     @sa @ref end() -- returns an iterator to the end
20962     @sa @ref cend() -- returns a const iterator to the end
20963 
20964     @since version 1.0.0
20965     */
begin()20966     iterator begin() noexcept
20967     {
20968         iterator result(this);
20969         result.set_begin();
20970         return result;
20971     }
20972 
20973     /*!
20974     @copydoc basic_json::cbegin()
20975     */
begin() const20976     const_iterator begin() const noexcept
20977     {
20978         return cbegin();
20979     }
20980 
20981     /*!
20982     @brief returns a const iterator to the first element
20983 
20984     Returns a const iterator to the first element.
20985 
20986     @image html range-begin-end.svg "Illustration from cppreference.com"
20987 
20988     @return const iterator to the first element
20989 
20990     @complexity Constant.
20991 
20992     @requirement This function helps `basic_json` satisfying the
20993     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
20994     requirements:
20995     - The complexity is constant.
20996     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
20997 
20998     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
20999 
21000     @sa @ref begin() -- returns an iterator to the beginning
21001     @sa @ref end() -- returns an iterator to the end
21002     @sa @ref cend() -- returns a const iterator to the end
21003 
21004     @since version 1.0.0
21005     */
cbegin() const21006     const_iterator cbegin() const noexcept
21007     {
21008         const_iterator result(this);
21009         result.set_begin();
21010         return result;
21011     }
21012 
21013     /*!
21014     @brief returns an iterator to one past the last element
21015 
21016     Returns an iterator to one past the last element.
21017 
21018     @image html range-begin-end.svg "Illustration from cppreference.com"
21019 
21020     @return iterator one past the last element
21021 
21022     @complexity Constant.
21023 
21024     @requirement This function helps `basic_json` satisfying the
21025     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21026     requirements:
21027     - The complexity is constant.
21028 
21029     @liveexample{The following code shows an example for `end()`.,end}
21030 
21031     @sa @ref cend() -- returns a const iterator to the end
21032     @sa @ref begin() -- returns an iterator to the beginning
21033     @sa @ref cbegin() -- returns a const iterator to the beginning
21034 
21035     @since version 1.0.0
21036     */
end()21037     iterator end() noexcept
21038     {
21039         iterator result(this);
21040         result.set_end();
21041         return result;
21042     }
21043 
21044     /*!
21045     @copydoc basic_json::cend()
21046     */
end() const21047     const_iterator end() const noexcept
21048     {
21049         return cend();
21050     }
21051 
21052     /*!
21053     @brief returns a const iterator to one past the last element
21054 
21055     Returns a const iterator to one past the last element.
21056 
21057     @image html range-begin-end.svg "Illustration from cppreference.com"
21058 
21059     @return const iterator one past the last element
21060 
21061     @complexity Constant.
21062 
21063     @requirement This function helps `basic_json` satisfying the
21064     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21065     requirements:
21066     - The complexity is constant.
21067     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
21068 
21069     @liveexample{The following code shows an example for `cend()`.,cend}
21070 
21071     @sa @ref end() -- returns an iterator to the end
21072     @sa @ref begin() -- returns an iterator to the beginning
21073     @sa @ref cbegin() -- returns a const iterator to the beginning
21074 
21075     @since version 1.0.0
21076     */
cend() const21077     const_iterator cend() const noexcept
21078     {
21079         const_iterator result(this);
21080         result.set_end();
21081         return result;
21082     }
21083 
21084     /*!
21085     @brief returns an iterator to the reverse-beginning
21086 
21087     Returns an iterator to the reverse-beginning; that is, the last element.
21088 
21089     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21090 
21091     @complexity Constant.
21092 
21093     @requirement This function helps `basic_json` satisfying the
21094     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21095     requirements:
21096     - The complexity is constant.
21097     - Has the semantics of `reverse_iterator(end())`.
21098 
21099     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
21100 
21101     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21102     @sa @ref rend() -- returns a reverse iterator to the end
21103     @sa @ref crend() -- returns a const reverse iterator to the end
21104 
21105     @since version 1.0.0
21106     */
rbegin()21107     reverse_iterator rbegin() noexcept
21108     {
21109         return reverse_iterator(end());
21110     }
21111 
21112     /*!
21113     @copydoc basic_json::crbegin()
21114     */
rbegin() const21115     const_reverse_iterator rbegin() const noexcept
21116     {
21117         return crbegin();
21118     }
21119 
21120     /*!
21121     @brief returns an iterator to the reverse-end
21122 
21123     Returns an iterator to the reverse-end; that is, one before the first
21124     element.
21125 
21126     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21127 
21128     @complexity Constant.
21129 
21130     @requirement This function helps `basic_json` satisfying the
21131     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21132     requirements:
21133     - The complexity is constant.
21134     - Has the semantics of `reverse_iterator(begin())`.
21135 
21136     @liveexample{The following code shows an example for `rend()`.,rend}
21137 
21138     @sa @ref crend() -- returns a const reverse iterator to the end
21139     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21140     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21141 
21142     @since version 1.0.0
21143     */
rend()21144     reverse_iterator rend() noexcept
21145     {
21146         return reverse_iterator(begin());
21147     }
21148 
21149     /*!
21150     @copydoc basic_json::crend()
21151     */
rend() const21152     const_reverse_iterator rend() const noexcept
21153     {
21154         return crend();
21155     }
21156 
21157     /*!
21158     @brief returns a const reverse iterator to the last element
21159 
21160     Returns a const iterator to the reverse-beginning; that is, the last
21161     element.
21162 
21163     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21164 
21165     @complexity Constant.
21166 
21167     @requirement This function helps `basic_json` satisfying the
21168     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21169     requirements:
21170     - The complexity is constant.
21171     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
21172 
21173     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
21174 
21175     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21176     @sa @ref rend() -- returns a reverse iterator to the end
21177     @sa @ref crend() -- returns a const reverse iterator to the end
21178 
21179     @since version 1.0.0
21180     */
crbegin() const21181     const_reverse_iterator crbegin() const noexcept
21182     {
21183         return const_reverse_iterator(cend());
21184     }
21185 
21186     /*!
21187     @brief returns a const reverse iterator to one before the first
21188 
21189     Returns a const reverse iterator to the reverse-end; that is, one before
21190     the first element.
21191 
21192     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21193 
21194     @complexity Constant.
21195 
21196     @requirement This function helps `basic_json` satisfying the
21197     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21198     requirements:
21199     - The complexity is constant.
21200     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
21201 
21202     @liveexample{The following code shows an example for `crend()`.,crend}
21203 
21204     @sa @ref rend() -- returns a reverse iterator to the end
21205     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21206     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21207 
21208     @since version 1.0.0
21209     */
crend() const21210     const_reverse_iterator crend() const noexcept
21211     {
21212         return const_reverse_iterator(cbegin());
21213     }
21214 
21215   public:
21216     /*!
21217     @brief wrapper to access iterator member functions in range-based for
21218 
21219     This function allows to access @ref iterator::key() and @ref
21220     iterator::value() during range-based for loops. In these loops, a
21221     reference to the JSON values is returned, so there is no access to the
21222     underlying iterator.
21223 
21224     For loop without iterator_wrapper:
21225 
21226     @code{cpp}
21227     for (auto it = j_object.begin(); it != j_object.end(); ++it)
21228     {
21229         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21230     }
21231     @endcode
21232 
21233     Range-based for loop without iterator proxy:
21234 
21235     @code{cpp}
21236     for (auto it : j_object)
21237     {
21238         // "it" is of type json::reference and has no key() member
21239         std::cout << "value: " << it << '\n';
21240     }
21241     @endcode
21242 
21243     Range-based for loop with iterator proxy:
21244 
21245     @code{cpp}
21246     for (auto it : json::iterator_wrapper(j_object))
21247     {
21248         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21249     }
21250     @endcode
21251 
21252     @note When iterating over an array, `key()` will return the index of the
21253           element as string (see example).
21254 
21255     @param[in] ref  reference to a JSON value
21256     @return iteration proxy object wrapping @a ref with an interface to use in
21257             range-based for loops
21258 
21259     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
21260 
21261     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21262     changes in the JSON value.
21263 
21264     @complexity Constant.
21265 
21266     @note The name of this function is not yet final and may change in the
21267     future.
21268 
21269     @deprecated This stream operator is deprecated and will be removed in
21270                 future 4.0.0 of the library. Please use @ref items() instead;
21271                 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
21272     */
items()21273     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21274     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21275     {
21276         return ref.items();
21277     }
21278 
21279     /*!
21280     @copydoc iterator_wrapper(reference)
21281     */
items()21282     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21283     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21284     {
21285         return ref.items();
21286     }
21287 
21288     /*!
21289     @brief helper to access iterator member functions in range-based for
21290 
21291     This function allows to access @ref iterator::key() and @ref
21292     iterator::value() during range-based for loops. In these loops, a
21293     reference to the JSON values is returned, so there is no access to the
21294     underlying iterator.
21295 
21296     For loop without `items()` function:
21297 
21298     @code{cpp}
21299     for (auto it = j_object.begin(); it != j_object.end(); ++it)
21300     {
21301         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21302     }
21303     @endcode
21304 
21305     Range-based for loop without `items()` function:
21306 
21307     @code{cpp}
21308     for (auto it : j_object)
21309     {
21310         // "it" is of type json::reference and has no key() member
21311         std::cout << "value: " << it << '\n';
21312     }
21313     @endcode
21314 
21315     Range-based for loop with `items()` function:
21316 
21317     @code{cpp}
21318     for (auto& el : j_object.items())
21319     {
21320         std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
21321     }
21322     @endcode
21323 
21324     The `items()` function also allows to use
21325     [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
21326     (C++17):
21327 
21328     @code{cpp}
21329     for (auto& [key, val] : j_object.items())
21330     {
21331         std::cout << "key: " << key << ", value:" << val << '\n';
21332     }
21333     @endcode
21334 
21335     @note When iterating over an array, `key()` will return the index of the
21336           element as string (see example). For primitive types (e.g., numbers),
21337           `key()` returns an empty string.
21338 
21339     @warning Using `items()` on temporary objects is dangerous. Make sure the
21340              object's lifetime exeeds the iteration. See
21341              <https://github.com/nlohmann/json/issues/2040> for more
21342              information.
21343 
21344     @return iteration proxy object wrapping @a ref with an interface to use in
21345             range-based for loops
21346 
21347     @liveexample{The following code shows how the function is used.,items}
21348 
21349     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21350     changes in the JSON value.
21351 
21352     @complexity Constant.
21353 
21354     @since version 3.1.0, structured bindings support since 3.5.0.
21355     */
items()21356     iteration_proxy<iterator> items() noexcept
21357     {
21358         return iteration_proxy<iterator>(*this);
21359     }
21360 
21361     /*!
21362     @copydoc items()
21363     */
items() const21364     iteration_proxy<const_iterator> items() const noexcept
21365     {
21366         return iteration_proxy<const_iterator>(*this);
21367     }
21368 
21369     /// @}
21370 
21371 
21372     //////////////
21373     // capacity //
21374     //////////////
21375 
21376     /// @name capacity
21377     /// @{
21378 
21379     /*!
21380     @brief checks whether the container is empty.
21381 
21382     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
21383 
21384     @return The return value depends on the different types and is
21385             defined as follows:
21386             Value type  | return value
21387             ----------- | -------------
21388             null        | `true`
21389             boolean     | `false`
21390             string      | `false`
21391             number      | `false`
21392             binary      | `false`
21393             object      | result of function `object_t::empty()`
21394             array       | result of function `array_t::empty()`
21395 
21396     @liveexample{The following code uses `empty()` to check if a JSON
21397     object contains any elements.,empty}
21398 
21399     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21400     the Container concept; that is, their `empty()` functions have constant
21401     complexity.
21402 
21403     @iterators No changes.
21404 
21405     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21406 
21407     @note This function does not return whether a string stored as JSON value
21408     is empty - it returns whether the JSON container itself is empty which is
21409     false in the case of a string.
21410 
21411     @requirement This function helps `basic_json` satisfying the
21412     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21413     requirements:
21414     - The complexity is constant.
21415     - Has the semantics of `begin() == end()`.
21416 
21417     @sa @ref size() -- returns the number of elements
21418 
21419     @since version 1.0.0
21420     */
empty() const21421     bool empty() const noexcept
21422     {
21423         switch (m_type)
21424         {
21425             case value_t::null:
21426             {
21427                 // null values are empty
21428                 return true;
21429             }
21430 
21431             case value_t::array:
21432             {
21433                 // delegate call to array_t::empty()
21434                 return m_value.array->empty();
21435             }
21436 
21437             case value_t::object:
21438             {
21439                 // delegate call to object_t::empty()
21440                 return m_value.object->empty();
21441             }
21442 
21443             default:
21444             {
21445                 // all other types are nonempty
21446                 return false;
21447             }
21448         }
21449     }
21450 
21451     /*!
21452     @brief returns the number of elements
21453 
21454     Returns the number of elements in a JSON value.
21455 
21456     @return The return value depends on the different types and is
21457             defined as follows:
21458             Value type  | return value
21459             ----------- | -------------
21460             null        | `0`
21461             boolean     | `1`
21462             string      | `1`
21463             number      | `1`
21464             binary      | `1`
21465             object      | result of function object_t::size()
21466             array       | result of function array_t::size()
21467 
21468     @liveexample{The following code calls `size()` on the different value
21469     types.,size}
21470 
21471     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21472     the Container concept; that is, their size() functions have constant
21473     complexity.
21474 
21475     @iterators No changes.
21476 
21477     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21478 
21479     @note This function does not return the length of a string stored as JSON
21480     value - it returns the number of elements in the JSON value which is 1 in
21481     the case of a string.
21482 
21483     @requirement This function helps `basic_json` satisfying the
21484     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21485     requirements:
21486     - The complexity is constant.
21487     - Has the semantics of `std::distance(begin(), end())`.
21488 
21489     @sa @ref empty() -- checks whether the container is empty
21490     @sa @ref max_size() -- returns the maximal number of elements
21491 
21492     @since version 1.0.0
21493     */
size() const21494     size_type size() const noexcept
21495     {
21496         switch (m_type)
21497         {
21498             case value_t::null:
21499             {
21500                 // null values are empty
21501                 return 0;
21502             }
21503 
21504             case value_t::array:
21505             {
21506                 // delegate call to array_t::size()
21507                 return m_value.array->size();
21508             }
21509 
21510             case value_t::object:
21511             {
21512                 // delegate call to object_t::size()
21513                 return m_value.object->size();
21514             }
21515 
21516             default:
21517             {
21518                 // all other types have size 1
21519                 return 1;
21520             }
21521         }
21522     }
21523 
21524     /*!
21525     @brief returns the maximum possible number of elements
21526 
21527     Returns the maximum number of elements a JSON value is able to hold due to
21528     system or library implementation limitations, i.e. `std::distance(begin(),
21529     end())` for the JSON value.
21530 
21531     @return The return value depends on the different types and is
21532             defined as follows:
21533             Value type  | return value
21534             ----------- | -------------
21535             null        | `0` (same as `size()`)
21536             boolean     | `1` (same as `size()`)
21537             string      | `1` (same as `size()`)
21538             number      | `1` (same as `size()`)
21539             binary      | `1` (same as `size()`)
21540             object      | result of function `object_t::max_size()`
21541             array       | result of function `array_t::max_size()`
21542 
21543     @liveexample{The following code calls `max_size()` on the different value
21544     types. Note the output is implementation specific.,max_size}
21545 
21546     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21547     the Container concept; that is, their `max_size()` functions have constant
21548     complexity.
21549 
21550     @iterators No changes.
21551 
21552     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21553 
21554     @requirement This function helps `basic_json` satisfying the
21555     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21556     requirements:
21557     - The complexity is constant.
21558     - Has the semantics of returning `b.size()` where `b` is the largest
21559       possible JSON value.
21560 
21561     @sa @ref size() -- returns the number of elements
21562 
21563     @since version 1.0.0
21564     */
max_size() const21565     size_type max_size() const noexcept
21566     {
21567         switch (m_type)
21568         {
21569             case value_t::array:
21570             {
21571                 // delegate call to array_t::max_size()
21572                 return m_value.array->max_size();
21573             }
21574 
21575             case value_t::object:
21576             {
21577                 // delegate call to object_t::max_size()
21578                 return m_value.object->max_size();
21579             }
21580 
21581             default:
21582             {
21583                 // all other types have max_size() == size()
21584                 return size();
21585             }
21586         }
21587     }
21588 
21589     /// @}
21590 
21591 
21592     ///////////////
21593     // modifiers //
21594     ///////////////
21595 
21596     /// @name modifiers
21597     /// @{
21598 
21599     /*!
21600     @brief clears the contents
21601 
21602     Clears the content of a JSON value and resets it to the default value as
21603     if @ref basic_json(value_t) would have been called with the current value
21604     type from @ref type():
21605 
21606     Value type  | initial value
21607     ----------- | -------------
21608     null        | `null`
21609     boolean     | `false`
21610     string      | `""`
21611     number      | `0`
21612     binary      | An empty byte vector
21613     object      | `{}`
21614     array       | `[]`
21615 
21616     @post Has the same effect as calling
21617     @code {.cpp}
21618     *this = basic_json(type());
21619     @endcode
21620 
21621     @liveexample{The example below shows the effect of `clear()` to different
21622     JSON types.,clear}
21623 
21624     @complexity Linear in the size of the JSON value.
21625 
21626     @iterators All iterators, pointers and references related to this container
21627                are invalidated.
21628 
21629     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21630 
21631     @sa @ref basic_json(value_t) -- constructor that creates an object with the
21632         same value than calling `clear()`
21633 
21634     @since version 1.0.0
21635     */
clear()21636     void clear() noexcept
21637     {
21638         switch (m_type)
21639         {
21640             case value_t::number_integer:
21641             {
21642                 m_value.number_integer = 0;
21643                 break;
21644             }
21645 
21646             case value_t::number_unsigned:
21647             {
21648                 m_value.number_unsigned = 0;
21649                 break;
21650             }
21651 
21652             case value_t::number_float:
21653             {
21654                 m_value.number_float = 0.0;
21655                 break;
21656             }
21657 
21658             case value_t::boolean:
21659             {
21660                 m_value.boolean = false;
21661                 break;
21662             }
21663 
21664             case value_t::string:
21665             {
21666                 m_value.string->clear();
21667                 break;
21668             }
21669 
21670             case value_t::binary:
21671             {
21672                 m_value.binary->clear();
21673                 break;
21674             }
21675 
21676             case value_t::array:
21677             {
21678                 m_value.array->clear();
21679                 break;
21680             }
21681 
21682             case value_t::object:
21683             {
21684                 m_value.object->clear();
21685                 break;
21686             }
21687 
21688             default:
21689                 break;
21690         }
21691     }
21692 
21693     /*!
21694     @brief add an object to an array
21695 
21696     Appends the given element @a val to the end of the JSON value. If the
21697     function is called on a JSON null value, an empty array is created before
21698     appending @a val.
21699 
21700     @param[in] val the value to add to the JSON array
21701 
21702     @throw type_error.308 when called on a type other than JSON array or
21703     null; example: `"cannot use push_back() with number"`
21704 
21705     @complexity Amortized constant.
21706 
21707     @liveexample{The example shows how `push_back()` and `+=` can be used to
21708     add elements to a JSON array. Note how the `null` value was silently
21709     converted to a JSON array.,push_back}
21710 
21711     @since version 1.0.0
21712     */
push_back(basic_json && val)21713     void push_back(basic_json&& val)
21714     {
21715         // push_back only works for null objects or arrays
21716         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21717         {
21718             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21719         }
21720 
21721         // transform null object into an array
21722         if (is_null())
21723         {
21724             m_type = value_t::array;
21725             m_value = value_t::array;
21726             assert_invariant();
21727         }
21728 
21729         // add element to array (move semantics)
21730         m_value.array->push_back(std::move(val));
21731         // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21732     }
21733 
21734     /*!
21735     @brief add an object to an array
21736     @copydoc push_back(basic_json&&)
21737     */
operator +=(basic_json && val)21738     reference operator+=(basic_json&& val)
21739     {
21740         push_back(std::move(val));
21741         return *this;
21742     }
21743 
21744     /*!
21745     @brief add an object to an array
21746     @copydoc push_back(basic_json&&)
21747     */
push_back(const basic_json & val)21748     void push_back(const basic_json& val)
21749     {
21750         // push_back only works for null objects or arrays
21751         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21752         {
21753             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21754         }
21755 
21756         // transform null object into an array
21757         if (is_null())
21758         {
21759             m_type = value_t::array;
21760             m_value = value_t::array;
21761             assert_invariant();
21762         }
21763 
21764         // add element to array
21765         m_value.array->push_back(val);
21766     }
21767 
21768     /*!
21769     @brief add an object to an array
21770     @copydoc push_back(basic_json&&)
21771     */
operator +=(const basic_json & val)21772     reference operator+=(const basic_json& val)
21773     {
21774         push_back(val);
21775         return *this;
21776     }
21777 
21778     /*!
21779     @brief add an object to an object
21780 
21781     Inserts the given element @a val to the JSON object. If the function is
21782     called on a JSON null value, an empty object is created before inserting
21783     @a val.
21784 
21785     @param[in] val the value to add to the JSON object
21786 
21787     @throw type_error.308 when called on a type other than JSON object or
21788     null; example: `"cannot use push_back() with number"`
21789 
21790     @complexity Logarithmic in the size of the container, O(log(`size()`)).
21791 
21792     @liveexample{The example shows how `push_back()` and `+=` can be used to
21793     add elements to a JSON object. Note how the `null` value was silently
21794     converted to a JSON object.,push_back__object_t__value}
21795 
21796     @since version 1.0.0
21797     */
push_back(const typename object_t::value_type & val)21798     void push_back(const typename object_t::value_type& val)
21799     {
21800         // push_back only works for null objects or objects
21801         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21802         {
21803             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21804         }
21805 
21806         // transform null object into an object
21807         if (is_null())
21808         {
21809             m_type = value_t::object;
21810             m_value = value_t::object;
21811             assert_invariant();
21812         }
21813 
21814         // add element to array
21815         m_value.object->insert(val);
21816     }
21817 
21818     /*!
21819     @brief add an object to an object
21820     @copydoc push_back(const typename object_t::value_type&)
21821     */
operator +=(const typename object_t::value_type & val)21822     reference operator+=(const typename object_t::value_type& val)
21823     {
21824         push_back(val);
21825         return *this;
21826     }
21827 
21828     /*!
21829     @brief add an object to an object
21830 
21831     This function allows to use `push_back` with an initializer list. In case
21832 
21833     1. the current value is an object,
21834     2. the initializer list @a init contains only two elements, and
21835     3. the first element of @a init is a string,
21836 
21837     @a init is converted into an object element and added using
21838     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
21839     is converted to a JSON value and added using @ref push_back(basic_json&&).
21840 
21841     @param[in] init  an initializer list
21842 
21843     @complexity Linear in the size of the initializer list @a init.
21844 
21845     @note This function is required to resolve an ambiguous overload error,
21846           because pairs like `{"key", "value"}` can be both interpreted as
21847           `object_t::value_type` or `std::initializer_list<basic_json>`, see
21848           https://github.com/nlohmann/json/issues/235 for more information.
21849 
21850     @liveexample{The example shows how initializer lists are treated as
21851     objects when possible.,push_back__initializer_list}
21852     */
push_back(initializer_list_t init)21853     void push_back(initializer_list_t init)
21854     {
21855         if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21856         {
21857             basic_json&& key = init.begin()->moved_or_copied();
21858             push_back(typename object_t::value_type(
21859                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21860         }
21861         else
21862         {
21863             push_back(basic_json(init));
21864         }
21865     }
21866 
21867     /*!
21868     @brief add an object to an object
21869     @copydoc push_back(initializer_list_t)
21870     */
operator +=(initializer_list_t init)21871     reference operator+=(initializer_list_t init)
21872     {
21873         push_back(init);
21874         return *this;
21875     }
21876 
21877     /*!
21878     @brief add an object to an array
21879 
21880     Creates a JSON value from the passed parameters @a args to the end of the
21881     JSON value. If the function is called on a JSON null value, an empty array
21882     is created before appending the value created from @a args.
21883 
21884     @param[in] args arguments to forward to a constructor of @ref basic_json
21885     @tparam Args compatible types to create a @ref basic_json object
21886 
21887     @return reference to the inserted element
21888 
21889     @throw type_error.311 when called on a type other than JSON array or
21890     null; example: `"cannot use emplace_back() with number"`
21891 
21892     @complexity Amortized constant.
21893 
21894     @liveexample{The example shows how `push_back()` can be used to add
21895     elements to a JSON array. Note how the `null` value was silently converted
21896     to a JSON array.,emplace_back}
21897 
21898     @since version 2.0.8, returns reference since 3.7.0
21899     */
21900     template<class... Args>
emplace_back(Args &&...args)21901     reference emplace_back(Args&& ... args)
21902     {
21903         // emplace_back only works for null objects or arrays
21904         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21905         {
21906             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21907         }
21908 
21909         // transform null object into an array
21910         if (is_null())
21911         {
21912             m_type = value_t::array;
21913             m_value = value_t::array;
21914             assert_invariant();
21915         }
21916 
21917         // add element to array (perfect forwarding)
21918 #ifdef JSON_HAS_CPP_17
21919         return m_value.array->emplace_back(std::forward<Args>(args)...);
21920 #else
21921         m_value.array->emplace_back(std::forward<Args>(args)...);
21922         return m_value.array->back();
21923 #endif
21924     }
21925 
21926     /*!
21927     @brief add an object to an object if key does not exist
21928 
21929     Inserts a new element into a JSON object constructed in-place with the
21930     given @a args if there is no element with the key in the container. If the
21931     function is called on a JSON null value, an empty object is created before
21932     appending the value created from @a args.
21933 
21934     @param[in] args arguments to forward to a constructor of @ref basic_json
21935     @tparam Args compatible types to create a @ref basic_json object
21936 
21937     @return a pair consisting of an iterator to the inserted element, or the
21938             already-existing element if no insertion happened, and a bool
21939             denoting whether the insertion took place.
21940 
21941     @throw type_error.311 when called on a type other than JSON object or
21942     null; example: `"cannot use emplace() with number"`
21943 
21944     @complexity Logarithmic in the size of the container, O(log(`size()`)).
21945 
21946     @liveexample{The example shows how `emplace()` can be used to add elements
21947     to a JSON object. Note how the `null` value was silently converted to a
21948     JSON object. Further note how no value is added if there was already one
21949     value stored with the same key.,emplace}
21950 
21951     @since version 2.0.8
21952     */
21953     template<class... Args>
emplace(Args &&...args)21954     std::pair<iterator, bool> emplace(Args&& ... args)
21955     {
21956         // emplace only works for null objects or arrays
21957         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21958         {
21959             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
21960         }
21961 
21962         // transform null object into an object
21963         if (is_null())
21964         {
21965             m_type = value_t::object;
21966             m_value = value_t::object;
21967             assert_invariant();
21968         }
21969 
21970         // add element to array (perfect forwarding)
21971         auto res = m_value.object->emplace(std::forward<Args>(args)...);
21972         // create result iterator and set iterator to the result of emplace
21973         auto it = begin();
21974         it.m_it.object_iterator = res.first;
21975 
21976         // return pair of iterator and boolean
21977         return {it, res.second};
21978     }
21979 
21980     /// Helper for insertion of an iterator
21981     /// @note: This uses std::distance to support GCC 4.8,
21982     ///        see https://github.com/nlohmann/json/pull/1257
21983     template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)21984     iterator insert_iterator(const_iterator pos, Args&& ... args)
21985     {
21986         iterator result(this);
21987         JSON_ASSERT(m_value.array != nullptr);
21988 
21989         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21990         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21991         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21992 
21993         // This could have been written as:
21994         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21995         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21996 
21997         return result;
21998     }
21999 
22000     /*!
22001     @brief inserts element
22002 
22003     Inserts element @a val before iterator @a pos.
22004 
22005     @param[in] pos iterator before which the content will be inserted; may be
22006     the end() iterator
22007     @param[in] val element to insert
22008     @return iterator pointing to the inserted @a val.
22009 
22010     @throw type_error.309 if called on JSON values other than arrays;
22011     example: `"cannot use insert() with string"`
22012     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22013     example: `"iterator does not fit current value"`
22014 
22015     @complexity Constant plus linear in the distance between @a pos and end of
22016     the container.
22017 
22018     @liveexample{The example shows how `insert()` is used.,insert}
22019 
22020     @since version 1.0.0
22021     */
insert(const_iterator pos,const basic_json & val)22022     iterator insert(const_iterator pos, const basic_json& val)
22023     {
22024         // insert only works for arrays
22025         if (JSON_HEDLEY_LIKELY(is_array()))
22026         {
22027             // check if iterator pos fits to this JSON value
22028             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22029             {
22030                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22031             }
22032 
22033             // insert to array and return iterator
22034             return insert_iterator(pos, val);
22035         }
22036 
22037         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22038     }
22039 
22040     /*!
22041     @brief inserts element
22042     @copydoc insert(const_iterator, const basic_json&)
22043     */
insert(const_iterator pos,basic_json && val)22044     iterator insert(const_iterator pos, basic_json&& val)
22045     {
22046         return insert(pos, val);
22047     }
22048 
22049     /*!
22050     @brief inserts elements
22051 
22052     Inserts @a cnt copies of @a val before iterator @a pos.
22053 
22054     @param[in] pos iterator before which the content will be inserted; may be
22055     the end() iterator
22056     @param[in] cnt number of copies of @a val to insert
22057     @param[in] val element to insert
22058     @return iterator pointing to the first element inserted, or @a pos if
22059     `cnt==0`
22060 
22061     @throw type_error.309 if called on JSON values other than arrays; example:
22062     `"cannot use insert() with string"`
22063     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22064     example: `"iterator does not fit current value"`
22065 
22066     @complexity Linear in @a cnt plus linear in the distance between @a pos
22067     and end of the container.
22068 
22069     @liveexample{The example shows how `insert()` is used.,insert__count}
22070 
22071     @since version 1.0.0
22072     */
insert(const_iterator pos,size_type cnt,const basic_json & val)22073     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22074     {
22075         // insert only works for arrays
22076         if (JSON_HEDLEY_LIKELY(is_array()))
22077         {
22078             // check if iterator pos fits to this JSON value
22079             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22080             {
22081                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22082             }
22083 
22084             // insert to array and return iterator
22085             return insert_iterator(pos, cnt, val);
22086         }
22087 
22088         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22089     }
22090 
22091     /*!
22092     @brief inserts elements
22093 
22094     Inserts elements from range `[first, last)` before iterator @a pos.
22095 
22096     @param[in] pos iterator before which the content will be inserted; may be
22097     the end() iterator
22098     @param[in] first begin of the range of elements to insert
22099     @param[in] last end of the range of elements to insert
22100 
22101     @throw type_error.309 if called on JSON values other than arrays; example:
22102     `"cannot use insert() with string"`
22103     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22104     example: `"iterator does not fit current value"`
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     @throw invalid_iterator.211 if @a first or @a last are iterators into
22108     container for which insert is called; example: `"passed iterators may not
22109     belong to container"`
22110 
22111     @return iterator pointing to the first element inserted, or @a pos if
22112     `first==last`
22113 
22114     @complexity Linear in `std::distance(first, last)` plus linear in the
22115     distance between @a pos and end of the container.
22116 
22117     @liveexample{The example shows how `insert()` is used.,insert__range}
22118 
22119     @since version 1.0.0
22120     */
insert(const_iterator pos,const_iterator first,const_iterator last)22121     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22122     {
22123         // insert only works for arrays
22124         if (JSON_HEDLEY_UNLIKELY(!is_array()))
22125         {
22126             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22127         }
22128 
22129         // check if iterator pos fits to this JSON value
22130         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22131         {
22132             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22133         }
22134 
22135         // check if range iterators belong to the same JSON object
22136         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22137         {
22138             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22139         }
22140 
22141         if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22142         {
22143             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22144         }
22145 
22146         // insert to array and return iterator
22147         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22148     }
22149 
22150     /*!
22151     @brief inserts elements
22152 
22153     Inserts elements from initializer list @a ilist before iterator @a pos.
22154 
22155     @param[in] pos iterator before which the content will be inserted; may be
22156     the end() iterator
22157     @param[in] ilist initializer list to insert the values from
22158 
22159     @throw type_error.309 if called on JSON values other than arrays; example:
22160     `"cannot use insert() with string"`
22161     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22162     example: `"iterator does not fit current value"`
22163 
22164     @return iterator pointing to the first element inserted, or @a pos if
22165     `ilist` is empty
22166 
22167     @complexity Linear in `ilist.size()` plus linear in the distance between
22168     @a pos and end of the container.
22169 
22170     @liveexample{The example shows how `insert()` is used.,insert__ilist}
22171 
22172     @since version 1.0.0
22173     */
insert(const_iterator pos,initializer_list_t ilist)22174     iterator insert(const_iterator pos, initializer_list_t ilist)
22175     {
22176         // insert only works for arrays
22177         if (JSON_HEDLEY_UNLIKELY(!is_array()))
22178         {
22179             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22180         }
22181 
22182         // check if iterator pos fits to this JSON value
22183         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22184         {
22185             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22186         }
22187 
22188         // insert to array and return iterator
22189         return insert_iterator(pos, ilist.begin(), ilist.end());
22190     }
22191 
22192     /*!
22193     @brief inserts elements
22194 
22195     Inserts elements from range `[first, last)`.
22196 
22197     @param[in] first begin of the range of elements to insert
22198     @param[in] last end of the range of elements to insert
22199 
22200     @throw type_error.309 if called on JSON values other than objects; example:
22201     `"cannot use insert() with string"`
22202     @throw invalid_iterator.202 if iterator @a first or @a last does does not
22203     point to an object; example: `"iterators first and last must point to
22204     objects"`
22205     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22206     same JSON value; example: `"iterators do not fit"`
22207 
22208     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
22209     of elements to insert.
22210 
22211     @liveexample{The example shows how `insert()` is used.,insert__range_object}
22212 
22213     @since version 3.0.0
22214     */
insert(const_iterator first,const_iterator last)22215     void insert(const_iterator first, const_iterator last)
22216     {
22217         // insert only works for objects
22218         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22219         {
22220             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22221         }
22222 
22223         // check if range iterators belong to the same JSON object
22224         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22225         {
22226             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22227         }
22228 
22229         // passed iterators must belong to objects
22230         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22231         {
22232             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22233         }
22234 
22235         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22236     }
22237 
22238     /*!
22239     @brief updates a JSON object from another object, overwriting existing keys
22240 
22241     Inserts all values from JSON object @a j and overwrites existing keys.
22242 
22243     @param[in] j  JSON object to read values from
22244 
22245     @throw type_error.312 if called on JSON values other than objects; example:
22246     `"cannot use update() with string"`
22247 
22248     @complexity O(N*log(size() + N)), where N is the number of elements to
22249                 insert.
22250 
22251     @liveexample{The example shows how `update()` is used.,update}
22252 
22253     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22254 
22255     @since version 3.0.0
22256     */
update(const_reference j)22257     void update(const_reference j)
22258     {
22259         // implicitly convert null value to an empty object
22260         if (is_null())
22261         {
22262             m_type = value_t::object;
22263             m_value.object = create<object_t>();
22264             assert_invariant();
22265         }
22266 
22267         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22268         {
22269             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22270         }
22271         if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22272         {
22273             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22274         }
22275 
22276         for (auto it = j.cbegin(); it != j.cend(); ++it)
22277         {
22278             m_value.object->operator[](it.key()) = it.value();
22279         }
22280     }
22281 
22282     /*!
22283     @brief updates a JSON object from another object, overwriting existing keys
22284 
22285     Inserts all values from from range `[first, last)` and overwrites existing
22286     keys.
22287 
22288     @param[in] first begin of the range of elements to insert
22289     @param[in] last end of the range of elements to insert
22290 
22291     @throw type_error.312 if called on JSON values other than objects; example:
22292     `"cannot use update() with string"`
22293     @throw invalid_iterator.202 if iterator @a first or @a last does does not
22294     point to an object; example: `"iterators first and last must point to
22295     objects"`
22296     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22297     same JSON value; example: `"iterators do not fit"`
22298 
22299     @complexity O(N*log(size() + N)), where N is the number of elements to
22300                 insert.
22301 
22302     @liveexample{The example shows how `update()` is used__range.,update}
22303 
22304     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22305 
22306     @since version 3.0.0
22307     */
update(const_iterator first,const_iterator last)22308     void update(const_iterator first, const_iterator last)
22309     {
22310         // implicitly convert null value to an empty object
22311         if (is_null())
22312         {
22313             m_type = value_t::object;
22314             m_value.object = create<object_t>();
22315             assert_invariant();
22316         }
22317 
22318         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22319         {
22320             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22321         }
22322 
22323         // check if range iterators belong to the same JSON object
22324         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22325         {
22326             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22327         }
22328 
22329         // passed iterators must belong to objects
22330         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22331                                  || !last.m_object->is_object()))
22332         {
22333             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22334         }
22335 
22336         for (auto it = first; it != last; ++it)
22337         {
22338             m_value.object->operator[](it.key()) = it.value();
22339         }
22340     }
22341 
22342     /*!
22343     @brief exchanges the values
22344 
22345     Exchanges the contents of the JSON value with those of @a other. Does not
22346     invoke any move, copy, or swap operations on individual elements. All
22347     iterators and references remain valid. The past-the-end iterator is
22348     invalidated.
22349 
22350     @param[in,out] other JSON value to exchange the contents with
22351 
22352     @complexity Constant.
22353 
22354     @liveexample{The example below shows how JSON values can be swapped with
22355     `swap()`.,swap__reference}
22356 
22357     @since version 1.0.0
22358     */
swap(reference other)22359     void swap(reference other) noexcept (
22360         std::is_nothrow_move_constructible<value_t>::value&&
22361         std::is_nothrow_move_assignable<value_t>::value&&
22362         std::is_nothrow_move_constructible<json_value>::value&&
22363         std::is_nothrow_move_assignable<json_value>::value
22364     )
22365     {
22366         std::swap(m_type, other.m_type);
22367         std::swap(m_value, other.m_value);
22368         assert_invariant();
22369     }
22370 
22371     /*!
22372     @brief exchanges the values
22373 
22374     Exchanges the contents of the JSON value from @a left with those of @a right. Does not
22375     invoke any move, copy, or swap operations on individual elements. All
22376     iterators and references remain valid. The past-the-end iterator is
22377     invalidated. implemented as a friend function callable via ADL.
22378 
22379     @param[in,out] left JSON value to exchange the contents with
22380     @param[in,out] right JSON value to exchange the contents with
22381 
22382     @complexity Constant.
22383 
22384     @liveexample{The example below shows how JSON values can be swapped with
22385     `swap()`.,swap__reference}
22386 
22387     @since version 1.0.0
22388     */
swap(reference left,reference right)22389     friend void swap(reference left, reference right) noexcept (
22390         std::is_nothrow_move_constructible<value_t>::value&&
22391         std::is_nothrow_move_assignable<value_t>::value&&
22392         std::is_nothrow_move_constructible<json_value>::value&&
22393         std::is_nothrow_move_assignable<json_value>::value
22394     )
22395     {
22396         left.swap(right);
22397     }
22398 
22399     /*!
22400     @brief exchanges the values
22401 
22402     Exchanges the contents of a JSON array with those of @a other. Does not
22403     invoke any move, copy, or swap operations on individual elements. All
22404     iterators and references remain valid. The past-the-end iterator is
22405     invalidated.
22406 
22407     @param[in,out] other array to exchange the contents with
22408 
22409     @throw type_error.310 when JSON value is not an array; example: `"cannot
22410     use swap() with string"`
22411 
22412     @complexity Constant.
22413 
22414     @liveexample{The example below shows how arrays can be swapped with
22415     `swap()`.,swap__array_t}
22416 
22417     @since version 1.0.0
22418     */
swap(array_t & other)22419     void swap(array_t& other)
22420     {
22421         // swap only works for arrays
22422         if (JSON_HEDLEY_LIKELY(is_array()))
22423         {
22424             std::swap(*(m_value.array), other);
22425         }
22426         else
22427         {
22428             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22429         }
22430     }
22431 
22432     /*!
22433     @brief exchanges the values
22434 
22435     Exchanges the contents of a JSON object with those of @a other. Does not
22436     invoke any move, copy, or swap operations on individual elements. All
22437     iterators and references remain valid. The past-the-end iterator is
22438     invalidated.
22439 
22440     @param[in,out] other object to exchange the contents with
22441 
22442     @throw type_error.310 when JSON value is not an object; example:
22443     `"cannot use swap() with string"`
22444 
22445     @complexity Constant.
22446 
22447     @liveexample{The example below shows how objects can be swapped with
22448     `swap()`.,swap__object_t}
22449 
22450     @since version 1.0.0
22451     */
swap(object_t & other)22452     void swap(object_t& other)
22453     {
22454         // swap only works for objects
22455         if (JSON_HEDLEY_LIKELY(is_object()))
22456         {
22457             std::swap(*(m_value.object), other);
22458         }
22459         else
22460         {
22461             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22462         }
22463     }
22464 
22465     /*!
22466     @brief exchanges the values
22467 
22468     Exchanges the contents of a JSON string with those of @a other. Does not
22469     invoke any move, copy, or swap operations on individual elements. All
22470     iterators and references remain valid. The past-the-end iterator is
22471     invalidated.
22472 
22473     @param[in,out] other string to exchange the contents with
22474 
22475     @throw type_error.310 when JSON value is not a string; example: `"cannot
22476     use swap() with boolean"`
22477 
22478     @complexity Constant.
22479 
22480     @liveexample{The example below shows how strings can be swapped with
22481     `swap()`.,swap__string_t}
22482 
22483     @since version 1.0.0
22484     */
swap(string_t & other)22485     void swap(string_t& other)
22486     {
22487         // swap only works for strings
22488         if (JSON_HEDLEY_LIKELY(is_string()))
22489         {
22490             std::swap(*(m_value.string), other);
22491         }
22492         else
22493         {
22494             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22495         }
22496     }
22497 
22498     /*!
22499     @brief exchanges the values
22500 
22501     Exchanges the contents of a JSON string with those of @a other. Does not
22502     invoke any move, copy, or swap operations on individual elements. All
22503     iterators and references remain valid. The past-the-end iterator is
22504     invalidated.
22505 
22506     @param[in,out] other binary to exchange the contents with
22507 
22508     @throw type_error.310 when JSON value is not a string; example: `"cannot
22509     use swap() with boolean"`
22510 
22511     @complexity Constant.
22512 
22513     @liveexample{The example below shows how strings can be swapped with
22514     `swap()`.,swap__binary_t}
22515 
22516     @since version 3.8.0
22517     */
swap(binary_t & other)22518     void swap(binary_t& other)
22519     {
22520         // swap only works for strings
22521         if (JSON_HEDLEY_LIKELY(is_binary()))
22522         {
22523             std::swap(*(m_value.binary), other);
22524         }
22525         else
22526         {
22527             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22528         }
22529     }
22530 
22531     /// @copydoc swap(binary_t)
swap(typename binary_t::container_type & other)22532     void swap(typename binary_t::container_type& other)
22533     {
22534         // swap only works for strings
22535         if (JSON_HEDLEY_LIKELY(is_binary()))
22536         {
22537             std::swap(*(m_value.binary), other);
22538         }
22539         else
22540         {
22541             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22542         }
22543     }
22544 
22545     /// @}
22546 
22547   public:
22548     //////////////////////////////////////////
22549     // lexicographical comparison operators //
22550     //////////////////////////////////////////
22551 
22552     /// @name lexicographical comparison operators
22553     /// @{
22554 
22555     /*!
22556     @brief comparison: equal
22557 
22558     Compares two JSON values for equality according to the following rules:
22559     - Two JSON values are equal if (1) they are from the same type and (2)
22560       their stored values are the same according to their respective
22561       `operator==`.
22562     - Integer and floating-point numbers are automatically converted before
22563       comparison. Note that two NaN values are always treated as unequal.
22564     - Two JSON null values are equal.
22565 
22566     @note Floating-point inside JSON values numbers are compared with
22567     `json::number_float_t::operator==` which is `double::operator==` by
22568     default. To compare floating-point while respecting an epsilon, an alternative
22569     [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
22570     could be used, for instance
22571     @code {.cpp}
22572     template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
22573     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
22574     {
22575         return std::abs(a - b) <= epsilon;
22576     }
22577     @endcode
22578     Or you can self-defined operator equal function like this:
22579     @code {.cpp}
22580     bool my_equal(const_reference lhs, const_reference rhs) {
22581     const auto lhs_type lhs.type();
22582     const auto rhs_type rhs.type();
22583     if (lhs_type == rhs_type) {
22584         switch(lhs_type)
22585             // self_defined case
22586             case value_t::number_float:
22587                 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
22588             // other cases remain the same with the original
22589             ...
22590     }
22591     ...
22592     }
22593     @endcode
22594 
22595     @note NaN values never compare equal to themselves or to other NaN values.
22596 
22597     @param[in] lhs  first JSON value to consider
22598     @param[in] rhs  second JSON value to consider
22599     @return whether the values @a lhs and @a rhs are equal
22600 
22601     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22602 
22603     @complexity Linear.
22604 
22605     @liveexample{The example demonstrates comparing several JSON
22606     types.,operator__equal}
22607 
22608     @since version 1.0.0
22609     */
operator ==(const_reference lhs,const_reference rhs)22610     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22611     {
22612         const auto lhs_type = lhs.type();
22613         const auto rhs_type = rhs.type();
22614 
22615         if (lhs_type == rhs_type)
22616         {
22617             switch (lhs_type)
22618             {
22619                 case value_t::array:
22620                     return *lhs.m_value.array == *rhs.m_value.array;
22621 
22622                 case value_t::object:
22623                     return *lhs.m_value.object == *rhs.m_value.object;
22624 
22625                 case value_t::null:
22626                     return true;
22627 
22628                 case value_t::string:
22629                     return *lhs.m_value.string == *rhs.m_value.string;
22630 
22631                 case value_t::boolean:
22632                     return lhs.m_value.boolean == rhs.m_value.boolean;
22633 
22634                 case value_t::number_integer:
22635                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
22636 
22637                 case value_t::number_unsigned:
22638                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22639 
22640                 case value_t::number_float:
22641                     return lhs.m_value.number_float == rhs.m_value.number_float;
22642 
22643                 case value_t::binary:
22644                     return *lhs.m_value.binary == *rhs.m_value.binary;
22645 
22646                 default:
22647                     return false;
22648             }
22649         }
22650         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22651         {
22652             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22653         }
22654         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22655         {
22656             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22657         }
22658         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22659         {
22660             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22661         }
22662         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22663         {
22664             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22665         }
22666         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22667         {
22668             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22669         }
22670         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22671         {
22672             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22673         }
22674 
22675         return false;
22676     }
22677 
22678     /*!
22679     @brief comparison: equal
22680     @copydoc operator==(const_reference, const_reference)
22681     */
22682     template<typename ScalarType, typename std::enable_if<
22683                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)22684     friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22685     {
22686         return lhs == basic_json(rhs);
22687     }
22688 
22689     /*!
22690     @brief comparison: equal
22691     @copydoc operator==(const_reference, const_reference)
22692     */
22693     template<typename ScalarType, typename std::enable_if<
22694                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)22695     friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22696     {
22697         return basic_json(lhs) == rhs;
22698     }
22699 
22700     /*!
22701     @brief comparison: not equal
22702 
22703     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
22704 
22705     @param[in] lhs  first JSON value to consider
22706     @param[in] rhs  second JSON value to consider
22707     @return whether the values @a lhs and @a rhs are not equal
22708 
22709     @complexity Linear.
22710 
22711     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22712 
22713     @liveexample{The example demonstrates comparing several JSON
22714     types.,operator__notequal}
22715 
22716     @since version 1.0.0
22717     */
operator !=(const_reference lhs,const_reference rhs)22718     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22719     {
22720         return !(lhs == rhs);
22721     }
22722 
22723     /*!
22724     @brief comparison: not equal
22725     @copydoc operator!=(const_reference, const_reference)
22726     */
22727     template<typename ScalarType, typename std::enable_if<
22728                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)22729     friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22730     {
22731         return lhs != basic_json(rhs);
22732     }
22733 
22734     /*!
22735     @brief comparison: not equal
22736     @copydoc operator!=(const_reference, const_reference)
22737     */
22738     template<typename ScalarType, typename std::enable_if<
22739                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)22740     friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22741     {
22742         return basic_json(lhs) != rhs;
22743     }
22744 
22745     /*!
22746     @brief comparison: less than
22747 
22748     Compares whether one JSON value @a lhs is less than another JSON value @a
22749     rhs according to the following rules:
22750     - If @a lhs and @a rhs have the same type, the values are compared using
22751       the default `<` operator.
22752     - Integer and floating-point numbers are automatically converted before
22753       comparison
22754     - In case @a lhs and @a rhs have different types, the values are ignored
22755       and the order of the types is considered, see
22756       @ref operator<(const value_t, const value_t).
22757 
22758     @param[in] lhs  first JSON value to consider
22759     @param[in] rhs  second JSON value to consider
22760     @return whether @a lhs is less than @a rhs
22761 
22762     @complexity Linear.
22763 
22764     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22765 
22766     @liveexample{The example demonstrates comparing several JSON
22767     types.,operator__less}
22768 
22769     @since version 1.0.0
22770     */
operator <(const_reference lhs,const_reference rhs)22771     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22772     {
22773         const auto lhs_type = lhs.type();
22774         const auto rhs_type = rhs.type();
22775 
22776         if (lhs_type == rhs_type)
22777         {
22778             switch (lhs_type)
22779             {
22780                 case value_t::array:
22781                     // note parentheses are necessary, see
22782                     // https://github.com/nlohmann/json/issues/1530
22783                     return (*lhs.m_value.array) < (*rhs.m_value.array);
22784 
22785                 case value_t::object:
22786                     return (*lhs.m_value.object) < (*rhs.m_value.object);
22787 
22788                 case value_t::null:
22789                     return false;
22790 
22791                 case value_t::string:
22792                     return (*lhs.m_value.string) < (*rhs.m_value.string);
22793 
22794                 case value_t::boolean:
22795                     return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22796 
22797                 case value_t::number_integer:
22798                     return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22799 
22800                 case value_t::number_unsigned:
22801                     return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22802 
22803                 case value_t::number_float:
22804                     return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22805 
22806                 case value_t::binary:
22807                     return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22808 
22809                 default:
22810                     return false;
22811             }
22812         }
22813         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22814         {
22815             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22816         }
22817         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22818         {
22819             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22820         }
22821         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22822         {
22823             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22824         }
22825         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22826         {
22827             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22828         }
22829         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22830         {
22831             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22832         }
22833         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22834         {
22835             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22836         }
22837 
22838         // We only reach this line if we cannot compare values. In that case,
22839         // we compare types. Note we have to call the operator explicitly,
22840         // because MSVC has problems otherwise.
22841         return operator<(lhs_type, rhs_type);
22842     }
22843 
22844     /*!
22845     @brief comparison: less than
22846     @copydoc operator<(const_reference, const_reference)
22847     */
22848     template<typename ScalarType, typename std::enable_if<
22849                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)22850     friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22851     {
22852         return lhs < basic_json(rhs);
22853     }
22854 
22855     /*!
22856     @brief comparison: less than
22857     @copydoc operator<(const_reference, const_reference)
22858     */
22859     template<typename ScalarType, typename std::enable_if<
22860                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)22861     friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22862     {
22863         return basic_json(lhs) < rhs;
22864     }
22865 
22866     /*!
22867     @brief comparison: less than or equal
22868 
22869     Compares whether one JSON value @a lhs is less than or equal to another
22870     JSON value by calculating `not (rhs < lhs)`.
22871 
22872     @param[in] lhs  first JSON value to consider
22873     @param[in] rhs  second JSON value to consider
22874     @return whether @a lhs is less than or equal to @a rhs
22875 
22876     @complexity Linear.
22877 
22878     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22879 
22880     @liveexample{The example demonstrates comparing several JSON
22881     types.,operator__greater}
22882 
22883     @since version 1.0.0
22884     */
operator <=(const_reference lhs,const_reference rhs)22885     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22886     {
22887         return !(rhs < lhs);
22888     }
22889 
22890     /*!
22891     @brief comparison: less than or equal
22892     @copydoc operator<=(const_reference, const_reference)
22893     */
22894     template<typename ScalarType, typename std::enable_if<
22895                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)22896     friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22897     {
22898         return lhs <= basic_json(rhs);
22899     }
22900 
22901     /*!
22902     @brief comparison: less than or equal
22903     @copydoc operator<=(const_reference, const_reference)
22904     */
22905     template<typename ScalarType, typename std::enable_if<
22906                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)22907     friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22908     {
22909         return basic_json(lhs) <= rhs;
22910     }
22911 
22912     /*!
22913     @brief comparison: greater than
22914 
22915     Compares whether one JSON value @a lhs is greater than another
22916     JSON value by calculating `not (lhs <= rhs)`.
22917 
22918     @param[in] lhs  first JSON value to consider
22919     @param[in] rhs  second JSON value to consider
22920     @return whether @a lhs is greater than to @a rhs
22921 
22922     @complexity Linear.
22923 
22924     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22925 
22926     @liveexample{The example demonstrates comparing several JSON
22927     types.,operator__lessequal}
22928 
22929     @since version 1.0.0
22930     */
operator >(const_reference lhs,const_reference rhs)22931     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22932     {
22933         return !(lhs <= rhs);
22934     }
22935 
22936     /*!
22937     @brief comparison: greater than
22938     @copydoc operator>(const_reference, const_reference)
22939     */
22940     template<typename ScalarType, typename std::enable_if<
22941                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)22942     friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
22943     {
22944         return lhs > basic_json(rhs);
22945     }
22946 
22947     /*!
22948     @brief comparison: greater than
22949     @copydoc operator>(const_reference, const_reference)
22950     */
22951     template<typename ScalarType, typename std::enable_if<
22952                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)22953     friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
22954     {
22955         return basic_json(lhs) > rhs;
22956     }
22957 
22958     /*!
22959     @brief comparison: greater than or equal
22960 
22961     Compares whether one JSON value @a lhs is greater than or equal to another
22962     JSON value by calculating `not (lhs < rhs)`.
22963 
22964     @param[in] lhs  first JSON value to consider
22965     @param[in] rhs  second JSON value to consider
22966     @return whether @a lhs is greater than or equal to @a rhs
22967 
22968     @complexity Linear.
22969 
22970     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22971 
22972     @liveexample{The example demonstrates comparing several JSON
22973     types.,operator__greaterequal}
22974 
22975     @since version 1.0.0
22976     */
operator >=(const_reference lhs,const_reference rhs)22977     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22978     {
22979         return !(lhs < rhs);
22980     }
22981 
22982     /*!
22983     @brief comparison: greater than or equal
22984     @copydoc operator>=(const_reference, const_reference)
22985     */
22986     template<typename ScalarType, typename std::enable_if<
22987                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)22988     friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
22989     {
22990         return lhs >= basic_json(rhs);
22991     }
22992 
22993     /*!
22994     @brief comparison: greater than or equal
22995     @copydoc operator>=(const_reference, const_reference)
22996     */
22997     template<typename ScalarType, typename std::enable_if<
22998                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)22999     friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23000     {
23001         return basic_json(lhs) >= rhs;
23002     }
23003 
23004     /// @}
23005 
23006     ///////////////////
23007     // serialization //
23008     ///////////////////
23009 
23010     /// @name serialization
23011     /// @{
23012 
23013     /*!
23014     @brief serialize to stream
23015 
23016     Serialize the given JSON value @a j to the output stream @a o. The JSON
23017     value will be serialized using the @ref dump member function.
23018 
23019     - The indentation of the output can be controlled with the member variable
23020       `width` of the output stream @a o. For instance, using the manipulator
23021       `std::setw(4)` on @a o sets the indentation level to `4` and the
23022       serialization result is the same as calling `dump(4)`.
23023 
23024     - The indentation character can be controlled with the member variable
23025       `fill` of the output stream @a o. For instance, the manipulator
23026       `std::setfill('\\t')` sets indentation to use a tab character rather than
23027       the default space character.
23028 
23029     @param[in,out] o  stream to serialize to
23030     @param[in] j  JSON value to serialize
23031 
23032     @return the stream @a o
23033 
23034     @throw type_error.316 if a string stored inside the JSON value is not
23035                           UTF-8 encoded
23036 
23037     @complexity Linear.
23038 
23039     @liveexample{The example below shows the serialization with different
23040     parameters to `width` to adjust the indentation level.,operator_serialize}
23041 
23042     @since version 1.0.0; indentation character added in version 3.0.0
23043     */
operator <<(std::ostream & o,const basic_json & j)23044     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23045     {
23046         // read width member and use it as indentation parameter if nonzero
23047         const bool pretty_print = o.width() > 0;
23048         const auto indentation = pretty_print ? o.width() : 0;
23049 
23050         // reset width to 0 for subsequent calls to this stream
23051         o.width(0);
23052 
23053         // do the actual serialization
23054         serializer s(detail::output_adapter<char>(o), o.fill());
23055         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23056         return o;
23057     }
23058 
23059     /*!
23060     @brief serialize to stream
23061     @deprecated This stream operator is deprecated and will be removed in
23062                 future 4.0.0 of the library. Please use
23063                 @ref operator<<(std::ostream&, const basic_json&)
23064                 instead; that is, replace calls like `j >> o;` with `o << j;`.
23065     @since version 1.0.0; deprecated since version 3.0.0
23066     */
23067     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
operator >>(const basic_json & j,std::ostream & o)23068     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23069     {
23070         return o << j;
23071     }
23072 
23073     /// @}
23074 
23075 
23076     /////////////////////
23077     // deserialization //
23078     /////////////////////
23079 
23080     /// @name deserialization
23081     /// @{
23082 
23083     /*!
23084     @brief deserialize from a compatible input
23085 
23086     @tparam InputType A compatible input, for instance
23087     - an std::istream object
23088     - a FILE pointer
23089     - a C-style array of characters
23090     - a pointer to a null-terminated string of single byte characters
23091     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23092       iterators.
23093 
23094     @param[in] i  input to read from
23095     @param[in] cb  a parser callback function of type @ref parser_callback_t
23096     which is used to control the deserialization by filtering unwanted values
23097     (optional)
23098     @param[in] allow_exceptions  whether to throw exceptions in case of a
23099     parse error (optional, true by default)
23100     @param[in] ignore_comments  whether comments should be ignored and treated
23101     like whitespace (true) or yield a parse error (true); (optional, false by
23102     default)
23103 
23104     @return deserialized JSON value; in case of a parse error and
23105             @a allow_exceptions set to `false`, the return value will be
23106             value_t::discarded.
23107 
23108     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23109     of input; expected string literal""`
23110     @throw parse_error.102 if to_unicode fails or surrogate error
23111     @throw parse_error.103 if to_unicode fails
23112 
23113     @complexity Linear in the length of the input. The parser is a predictive
23114     LL(1) parser. The complexity can be higher if the parser callback function
23115     @a cb or reading from the input @a i has a super-linear complexity.
23116 
23117     @note A UTF-8 byte order mark is silently ignored.
23118 
23119     @liveexample{The example below demonstrates the `parse()` function reading
23120     from an array.,parse__array__parser_callback_t}
23121 
23122     @liveexample{The example below demonstrates the `parse()` function with
23123     and without callback function.,parse__string__parser_callback_t}
23124 
23125     @liveexample{The example below demonstrates the `parse()` function with
23126     and without callback function.,parse__istream__parser_callback_t}
23127 
23128     @liveexample{The example below demonstrates the `parse()` function reading
23129     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
23130 
23131     @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
23132     ignore comments.
23133     */
23134     template<typename InputType>
23135     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(InputType && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)23136     static basic_json parse(InputType&& i,
23137                             const parser_callback_t cb = nullptr,
23138                             const bool allow_exceptions = true,
23139                             const bool ignore_comments = false)
23140     {
23141         basic_json result;
23142         parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23143         return result;
23144     }
23145 
23146     /*!
23147     @brief deserialize from a pair of character iterators
23148 
23149     The value_type of the iterator must be a integral type with size of 1, 2 or
23150     4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
23151 
23152     @param[in] first iterator to start of character range
23153     @param[in] last  iterator to end of character range
23154     @param[in] cb  a parser callback function of type @ref parser_callback_t
23155     which is used to control the deserialization by filtering unwanted values
23156     (optional)
23157     @param[in] allow_exceptions  whether to throw exceptions in case of a
23158     parse error (optional, true by default)
23159     @param[in] ignore_comments  whether comments should be ignored and treated
23160     like whitespace (true) or yield a parse error (true); (optional, false by
23161     default)
23162 
23163     @return deserialized JSON value; in case of a parse error and
23164             @a allow_exceptions set to `false`, the return value will be
23165             value_t::discarded.
23166 
23167     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23168     of input; expected string literal""`
23169     @throw parse_error.102 if to_unicode fails or surrogate error
23170     @throw parse_error.103 if to_unicode fails
23171     */
23172     template<typename IteratorType>
23173     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)23174     static basic_json parse(IteratorType first,
23175                             IteratorType last,
23176                             const parser_callback_t cb = nullptr,
23177                             const bool allow_exceptions = true,
23178                             const bool ignore_comments = false)
23179     {
23180         basic_json result;
23181         parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23182         return result;
23183     }
23184 
23185     JSON_HEDLEY_WARN_UNUSED_RESULT
23186     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
parse(detail::span_input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)23187     static basic_json parse(detail::span_input_adapter&& i,
23188                             const parser_callback_t cb = nullptr,
23189                             const bool allow_exceptions = true,
23190                             const bool ignore_comments = false)
23191     {
23192         basic_json result;
23193         parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23194         return result;
23195     }
23196 
23197     /*!
23198     @brief check if the input is valid JSON
23199 
23200     Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
23201     function, this function neither throws an exception in case of invalid JSON
23202     input (i.e., a parse error) nor creates diagnostic information.
23203 
23204     @tparam InputType A compatible input, for instance
23205     - an std::istream object
23206     - a FILE pointer
23207     - a C-style array of characters
23208     - a pointer to a null-terminated string of single byte characters
23209     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23210       iterators.
23211 
23212     @param[in] i input to read from
23213     @param[in] ignore_comments  whether comments should be ignored and treated
23214     like whitespace (true) or yield a parse error (true); (optional, false by
23215     default)
23216 
23217     @return Whether the input read from @a i is valid JSON.
23218 
23219     @complexity Linear in the length of the input. The parser is a predictive
23220     LL(1) parser.
23221 
23222     @note A UTF-8 byte order mark is silently ignored.
23223 
23224     @liveexample{The example below demonstrates the `accept()` function reading
23225     from a string.,accept__string}
23226     */
23227     template<typename InputType>
accept(InputType && i,const bool ignore_comments=false)23228     static bool accept(InputType&& i,
23229                        const bool ignore_comments = false)
23230     {
23231         return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23232     }
23233 
23234     template<typename IteratorType>
accept(IteratorType first,IteratorType last,const bool ignore_comments=false)23235     static bool accept(IteratorType first, IteratorType last,
23236                        const bool ignore_comments = false)
23237     {
23238         return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23239     }
23240 
23241     JSON_HEDLEY_WARN_UNUSED_RESULT
23242     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
accept(detail::span_input_adapter && i,const bool ignore_comments=false)23243     static bool accept(detail::span_input_adapter&& i,
23244                        const bool ignore_comments = false)
23245     {
23246         return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23247     }
23248 
23249     /*!
23250     @brief generate SAX events
23251 
23252     The SAX event lister must follow the interface of @ref json_sax.
23253 
23254     This function reads from a compatible input. Examples are:
23255     - an std::istream object
23256     - a FILE pointer
23257     - a C-style array of characters
23258     - a pointer to a null-terminated string of single byte characters
23259     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23260       iterators.
23261 
23262     @param[in] i  input to read from
23263     @param[in,out] sax  SAX event listener
23264     @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
23265     @param[in] strict  whether the input has to be consumed completely
23266     @param[in] ignore_comments  whether comments should be ignored and treated
23267     like whitespace (true) or yield a parse error (true); (optional, false by
23268     default); only applies to the JSON file format.
23269 
23270     @return return value of the last processed SAX event
23271 
23272     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23273     of input; expected string literal""`
23274     @throw parse_error.102 if to_unicode fails or surrogate error
23275     @throw parse_error.103 if to_unicode fails
23276 
23277     @complexity Linear in the length of the input. The parser is a predictive
23278     LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
23279     a super-linear complexity.
23280 
23281     @note A UTF-8 byte order mark is silently ignored.
23282 
23283     @liveexample{The example below demonstrates the `sax_parse()` function
23284     reading from string and processing the events with a user-defined SAX
23285     event consumer.,sax_parse}
23286 
23287     @since version 3.2.0
23288     */
23289     template <typename InputType, typename SAX>
23290     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)23291     static bool sax_parse(InputType&& i, SAX* sax,
23292                           input_format_t format = input_format_t::json,
23293                           const bool strict = true,
23294                           const bool ignore_comments = false)
23295     {
23296         auto ia = detail::input_adapter(std::forward<InputType>(i));
23297         return format == input_format_t::json
23298                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23299                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23300     }
23301 
23302     template<class IteratorType, class SAX>
23303     JSON_HEDLEY_NON_NULL(3)
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)23304     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23305                           input_format_t format = input_format_t::json,
23306                           const bool strict = true,
23307                           const bool ignore_comments = false)
23308     {
23309         auto ia = detail::input_adapter(std::move(first), std::move(last));
23310         return format == input_format_t::json
23311                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23312                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23313     }
23314 
23315     template <typename SAX>
23316     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23317     JSON_HEDLEY_NON_NULL(2)
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)23318     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23319                           input_format_t format = input_format_t::json,
23320                           const bool strict = true,
23321                           const bool ignore_comments = false)
23322     {
23323         auto ia = i.get();
23324         return format == input_format_t::json
23325                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23326                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23327     }
23328 
23329     /*!
23330     @brief deserialize from stream
23331     @deprecated This stream operator is deprecated and will be removed in
23332                 version 4.0.0 of the library. Please use
23333                 @ref operator>>(std::istream&, basic_json&)
23334                 instead; that is, replace calls like `j << i;` with `i >> j;`.
23335     @since version 1.0.0; deprecated since version 3.0.0
23336     */
23337     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
operator <<(basic_json & j,std::istream & i)23338     friend std::istream& operator<<(basic_json& j, std::istream& i)
23339     {
23340         return operator>>(i, j);
23341     }
23342 
23343     /*!
23344     @brief deserialize from stream
23345 
23346     Deserializes an input stream to a JSON value.
23347 
23348     @param[in,out] i  input stream to read a serialized JSON value from
23349     @param[in,out] j  JSON value to write the deserialized input to
23350 
23351     @throw parse_error.101 in case of an unexpected token
23352     @throw parse_error.102 if to_unicode fails or surrogate error
23353     @throw parse_error.103 if to_unicode fails
23354 
23355     @complexity Linear in the length of the input. The parser is a predictive
23356     LL(1) parser.
23357 
23358     @note A UTF-8 byte order mark is silently ignored.
23359 
23360     @liveexample{The example below shows how a JSON value is constructed by
23361     reading a serialization from a stream.,operator_deserialize}
23362 
23363     @sa parse(std::istream&, const parser_callback_t) for a variant with a
23364     parser callback function to filter values while parsing
23365 
23366     @since version 1.0.0
23367     */
operator >>(std::istream & i,basic_json & j)23368     friend std::istream& operator>>(std::istream& i, basic_json& j)
23369     {
23370         parser(detail::input_adapter(i)).parse(false, j);
23371         return i;
23372     }
23373 
23374     /// @}
23375 
23376     ///////////////////////////
23377     // convenience functions //
23378     ///////////////////////////
23379 
23380     /*!
23381     @brief return the type as string
23382 
23383     Returns the type name as string to be used in error messages - usually to
23384     indicate that a function was called on a wrong JSON type.
23385 
23386     @return a string representation of a the @a m_type member:
23387             Value type  | return value
23388             ----------- | -------------
23389             null        | `"null"`
23390             boolean     | `"boolean"`
23391             string      | `"string"`
23392             number      | `"number"` (for all number types)
23393             object      | `"object"`
23394             array       | `"array"`
23395             binary      | `"binary"`
23396             discarded   | `"discarded"`
23397 
23398     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23399 
23400     @complexity Constant.
23401 
23402     @liveexample{The following code exemplifies `type_name()` for all JSON
23403     types.,type_name}
23404 
23405     @sa @ref type() -- return the type of the JSON value
23406     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
23407 
23408     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
23409     since 3.0.0
23410     */
23411     JSON_HEDLEY_RETURNS_NON_NULL
type_name() const23412     const char* type_name() const noexcept
23413     {
23414         {
23415             switch (m_type)
23416             {
23417                 case value_t::null:
23418                     return "null";
23419                 case value_t::object:
23420                     return "object";
23421                 case value_t::array:
23422                     return "array";
23423                 case value_t::string:
23424                     return "string";
23425                 case value_t::boolean:
23426                     return "boolean";
23427                 case value_t::binary:
23428                     return "binary";
23429                 case value_t::discarded:
23430                     return "discarded";
23431                 default:
23432                     return "number";
23433             }
23434         }
23435     }
23436 
23437 
23438   private:
23439     //////////////////////
23440     // member variables //
23441     //////////////////////
23442 
23443     /// the type of the current element
23444     value_t m_type = value_t::null;
23445 
23446     /// the value of the current element
23447     json_value m_value = {};
23448 
23449     //////////////////////////////////////////
23450     // binary serialization/deserialization //
23451     //////////////////////////////////////////
23452 
23453     /// @name binary serialization/deserialization support
23454     /// @{
23455 
23456   public:
23457     /*!
23458     @brief create a CBOR serialization of a given JSON value
23459 
23460     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
23461     Binary Object Representation) serialization format. CBOR is a binary
23462     serialization format which aims to be more compact than JSON itself, yet
23463     more efficient to parse.
23464 
23465     The library uses the following mapping from JSON values types to
23466     CBOR types according to the CBOR specification (RFC 7049):
23467 
23468     JSON value type | value/range                                | CBOR type                          | first byte
23469     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
23470     null            | `null`                                     | Null                               | 0xF6
23471     boolean         | `true`                                     | True                               | 0xF5
23472     boolean         | `false`                                    | False                              | 0xF4
23473     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
23474     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
23475     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
23476     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
23477     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
23478     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
23479     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23480     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23481     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23482     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23483     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
23484     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23485     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23486     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23487     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23488     number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
23489     number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
23490     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
23491     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
23492     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
23493     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
23494     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
23495     array           | *size*: 0..23                              | array                              | 0x80..0x97
23496     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
23497     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
23498     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
23499     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
23500     object          | *size*: 0..23                              | map                                | 0xA0..0xB7
23501     object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
23502     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
23503     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
23504     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
23505     binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
23506     binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
23507     binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
23508     binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
23509     binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
23510 
23511     @note The mapping is **complete** in the sense that any JSON value type
23512           can be converted to a CBOR value.
23513 
23514     @note If NaN or Infinity are stored inside a JSON number, they are
23515           serialized properly. This behavior differs from the @ref dump()
23516           function which serializes NaN or Infinity to `null`.
23517 
23518     @note The following CBOR types are not used in the conversion:
23519           - UTF-8 strings terminated by "break" (0x7F)
23520           - arrays terminated by "break" (0x9F)
23521           - maps terminated by "break" (0xBF)
23522           - byte strings terminated by "break" (0x5F)
23523           - date/time (0xC0..0xC1)
23524           - bignum (0xC2..0xC3)
23525           - decimal fraction (0xC4)
23526           - bigfloat (0xC5)
23527           - expected conversions (0xD5..0xD7)
23528           - simple values (0xE0..0xF3, 0xF8)
23529           - undefined (0xF7)
23530           - half-precision floats (0xF9)
23531           - break (0xFF)
23532 
23533     @param[in] j  JSON value to serialize
23534     @return CBOR serialization as byte vector
23535 
23536     @complexity Linear in the size of the JSON value @a j.
23537 
23538     @liveexample{The example shows the serialization of a JSON value to a byte
23539     vector in CBOR format.,to_cbor}
23540 
23541     @sa http://cbor.io
23542     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
23543         analogous deserialization
23544     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23545     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23546              related UBJSON format
23547 
23548     @since version 2.0.9; compact representation of floating-point numbers
23549            since version 3.8.0
23550     */
to_cbor(const basic_json & j)23551     static std::vector<uint8_t> to_cbor(const basic_json& j)
23552     {
23553         std::vector<uint8_t> result;
23554         to_cbor(j, result);
23555         return result;
23556     }
23557 
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)23558     static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23559     {
23560         binary_writer<uint8_t>(o).write_cbor(j);
23561     }
23562 
to_cbor(const basic_json & j,detail::output_adapter<char> o)23563     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23564     {
23565         binary_writer<char>(o).write_cbor(j);
23566     }
23567 
23568     /*!
23569     @brief create a MessagePack serialization of a given JSON value
23570 
23571     Serializes a given JSON value @a j to a byte vector using the MessagePack
23572     serialization format. MessagePack is a binary serialization format which
23573     aims to be more compact than JSON itself, yet more efficient to parse.
23574 
23575     The library uses the following mapping from JSON values types to
23576     MessagePack types according to the MessagePack specification:
23577 
23578     JSON value type | value/range                       | MessagePack type | first byte
23579     --------------- | --------------------------------- | ---------------- | ----------
23580     null            | `null`                            | nil              | 0xC0
23581     boolean         | `true`                            | true             | 0xC3
23582     boolean         | `false`                           | false            | 0xC2
23583     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
23584     number_integer  | -2147483648..-32769               | int32            | 0xD2
23585     number_integer  | -32768..-129                      | int16            | 0xD1
23586     number_integer  | -128..-33                         | int8             | 0xD0
23587     number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
23588     number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
23589     number_integer  | 128..255                          | uint 8           | 0xCC
23590     number_integer  | 256..65535                        | uint 16          | 0xCD
23591     number_integer  | 65536..4294967295                 | uint 32          | 0xCE
23592     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
23593     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
23594     number_unsigned | 128..255                          | uint 8           | 0xCC
23595     number_unsigned | 256..65535                        | uint 16          | 0xCD
23596     number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
23597     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
23598     number_float    | *any value representable by a float*     | float 32 | 0xCA
23599     number_float    | *any value NOT representable by a float* | float 64 | 0xCB
23600     string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
23601     string          | *length*: 32..255                 | str 8            | 0xD9
23602     string          | *length*: 256..65535              | str 16           | 0xDA
23603     string          | *length*: 65536..4294967295       | str 32           | 0xDB
23604     array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
23605     array           | *size*: 16..65535                 | array 16         | 0xDC
23606     array           | *size*: 65536..4294967295         | array 32         | 0xDD
23607     object          | *size*: 0..15                     | fix map          | 0x80..0x8F
23608     object          | *size*: 16..65535                 | map 16           | 0xDE
23609     object          | *size*: 65536..4294967295         | map 32           | 0xDF
23610     binary          | *size*: 0..255                    | bin 8            | 0xC4
23611     binary          | *size*: 256..65535                | bin 16           | 0xC5
23612     binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
23613 
23614     @note The mapping is **complete** in the sense that any JSON value type
23615           can be converted to a MessagePack value.
23616 
23617     @note The following values can **not** be converted to a MessagePack value:
23618           - strings with more than 4294967295 bytes
23619           - byte strings with more than 4294967295 bytes
23620           - arrays with more than 4294967295 elements
23621           - objects with more than 4294967295 elements
23622 
23623     @note Any MessagePack output created @ref to_msgpack can be successfully
23624           parsed by @ref from_msgpack.
23625 
23626     @note If NaN or Infinity are stored inside a JSON number, they are
23627           serialized properly. This behavior differs from the @ref dump()
23628           function which serializes NaN or Infinity to `null`.
23629 
23630     @param[in] j  JSON value to serialize
23631     @return MessagePack serialization as byte vector
23632 
23633     @complexity Linear in the size of the JSON value @a j.
23634 
23635     @liveexample{The example shows the serialization of a JSON value to a byte
23636     vector in MessagePack format.,to_msgpack}
23637 
23638     @sa http://msgpack.org
23639     @sa @ref from_msgpack for the analogous deserialization
23640     @sa @ref to_cbor(const basic_json& for the related CBOR format
23641     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23642              related UBJSON format
23643 
23644     @since version 2.0.9
23645     */
to_msgpack(const basic_json & j)23646     static std::vector<uint8_t> to_msgpack(const basic_json& j)
23647     {
23648         std::vector<uint8_t> result;
23649         to_msgpack(j, result);
23650         return result;
23651     }
23652 
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)23653     static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23654     {
23655         binary_writer<uint8_t>(o).write_msgpack(j);
23656     }
23657 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)23658     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23659     {
23660         binary_writer<char>(o).write_msgpack(j);
23661     }
23662 
23663     /*!
23664     @brief create a UBJSON serialization of a given JSON value
23665 
23666     Serializes a given JSON value @a j to a byte vector using the UBJSON
23667     (Universal Binary JSON) serialization format. UBJSON aims to be more compact
23668     than JSON itself, yet more efficient to parse.
23669 
23670     The library uses the following mapping from JSON values types to
23671     UBJSON types according to the UBJSON specification:
23672 
23673     JSON value type | value/range                       | UBJSON type | marker
23674     --------------- | --------------------------------- | ----------- | ------
23675     null            | `null`                            | null        | `Z`
23676     boolean         | `true`                            | true        | `T`
23677     boolean         | `false`                           | false       | `F`
23678     number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
23679     number_integer  | -2147483648..-32769               | int32       | `l`
23680     number_integer  | -32768..-129                      | int16       | `I`
23681     number_integer  | -128..127                         | int8        | `i`
23682     number_integer  | 128..255                          | uint8       | `U`
23683     number_integer  | 256..32767                        | int16       | `I`
23684     number_integer  | 32768..2147483647                 | int32       | `l`
23685     number_integer  | 2147483648..9223372036854775807   | int64       | `L`
23686     number_unsigned | 0..127                            | int8        | `i`
23687     number_unsigned | 128..255                          | uint8       | `U`
23688     number_unsigned | 256..32767                        | int16       | `I`
23689     number_unsigned | 32768..2147483647                 | int32       | `l`
23690     number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
23691     number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
23692     number_float    | *any value*                       | float64     | `D`
23693     string          | *with shortest length indicator*  | string      | `S`
23694     array           | *see notes on optimized format*   | array       | `[`
23695     object          | *see notes on optimized format*   | map         | `{`
23696 
23697     @note The mapping is **complete** in the sense that any JSON value type
23698           can be converted to a UBJSON value.
23699 
23700     @note The following values can **not** be converted to a UBJSON value:
23701           - strings with more than 9223372036854775807 bytes (theoretical)
23702 
23703     @note The following markers are not used in the conversion:
23704           - `Z`: no-op values are not created.
23705           - `C`: single-byte strings are serialized with `S` markers.
23706 
23707     @note Any UBJSON output created @ref to_ubjson can be successfully parsed
23708           by @ref from_ubjson.
23709 
23710     @note If NaN or Infinity are stored inside a JSON number, they are
23711           serialized properly. This behavior differs from the @ref dump()
23712           function which serializes NaN or Infinity to `null`.
23713 
23714     @note The optimized formats for containers are supported: Parameter
23715           @a use_size adds size information to the beginning of a container and
23716           removes the closing marker. Parameter @a use_type further checks
23717           whether all elements of a container have the same type and adds the
23718           type marker to the beginning of the container. The @a use_type
23719           parameter must only be used together with @a use_size = true. Note
23720           that @a use_size = true alone may result in larger representations -
23721           the benefit of this parameter is that the receiving side is
23722           immediately informed on the number of elements of the container.
23723 
23724     @note If the JSON data contains the binary type, the value stored is a list
23725           of integers, as suggested by the UBJSON documentation.  In particular,
23726           this means that serialization and the deserialization of a JSON
23727           containing binary values into UBJSON and back will result in a
23728           different JSON object.
23729 
23730     @param[in] j  JSON value to serialize
23731     @param[in] use_size  whether to add size annotations to container types
23732     @param[in] use_type  whether to add type annotations to container types
23733                          (must be combined with @a use_size = true)
23734     @return UBJSON serialization as byte vector
23735 
23736     @complexity Linear in the size of the JSON value @a j.
23737 
23738     @liveexample{The example shows the serialization of a JSON value to a byte
23739     vector in UBJSON format.,to_ubjson}
23740 
23741     @sa http://ubjson.org
23742     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
23743         analogous deserialization
23744     @sa @ref to_cbor(const basic_json& for the related CBOR format
23745     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23746 
23747     @since version 3.1.0
23748     */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)23749     static std::vector<uint8_t> to_ubjson(const basic_json& j,
23750                                           const bool use_size = false,
23751                                           const bool use_type = false)
23752     {
23753         std::vector<uint8_t> result;
23754         to_ubjson(j, result, use_size, use_type);
23755         return result;
23756     }
23757 
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)23758     static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23759                           const bool use_size = false, const bool use_type = false)
23760     {
23761         binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23762     }
23763 
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)23764     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23765                           const bool use_size = false, const bool use_type = false)
23766     {
23767         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23768     }
23769 
23770 
23771     /*!
23772     @brief Serializes the given JSON object `j` to BSON and returns a vector
23773            containing the corresponding BSON-representation.
23774 
23775     BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
23776     stored as a single entity (a so-called document).
23777 
23778     The library uses the following mapping from JSON values types to BSON types:
23779 
23780     JSON value type | value/range                       | BSON type   | marker
23781     --------------- | --------------------------------- | ----------- | ------
23782     null            | `null`                            | null        | 0x0A
23783     boolean         | `true`, `false`                   | boolean     | 0x08
23784     number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
23785     number_integer  | -2147483648..2147483647           | int32       | 0x10
23786     number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
23787     number_unsigned | 0..2147483647                     | int32       | 0x10
23788     number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
23789     number_unsigned | 9223372036854775808..18446744073709551615| --   | --
23790     number_float    | *any value*                       | double      | 0x01
23791     string          | *any value*                       | string      | 0x02
23792     array           | *any value*                       | document    | 0x04
23793     object          | *any value*                       | document    | 0x03
23794     binary          | *any value*                       | binary      | 0x05
23795 
23796     @warning The mapping is **incomplete**, since only JSON-objects (and things
23797     contained therein) can be serialized to BSON.
23798     Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
23799     and the keys may not contain U+0000, since they are serialized a
23800     zero-terminated c-strings.
23801 
23802     @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
23803     @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
23804     @throw type_error.317    if `!j.is_object()`
23805 
23806     @pre The input `j` is required to be an object: `j.is_object() == true`.
23807 
23808     @note Any BSON output created via @ref to_bson can be successfully parsed
23809           by @ref from_bson.
23810 
23811     @param[in] j  JSON value to serialize
23812     @return BSON serialization as byte vector
23813 
23814     @complexity Linear in the size of the JSON value @a j.
23815 
23816     @liveexample{The example shows the serialization of a JSON value to a byte
23817     vector in BSON format.,to_bson}
23818 
23819     @sa http://bsonspec.org/spec.html
23820     @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
23821         analogous deserialization
23822     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23823              related UBJSON format
23824     @sa @ref to_cbor(const basic_json&) for the related CBOR format
23825     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23826     */
to_bson(const basic_json & j)23827     static std::vector<uint8_t> to_bson(const basic_json& j)
23828     {
23829         std::vector<uint8_t> result;
23830         to_bson(j, result);
23831         return result;
23832     }
23833 
23834     /*!
23835     @brief Serializes the given JSON object `j` to BSON and forwards the
23836            corresponding BSON-representation to the given output_adapter `o`.
23837     @param j The JSON object to convert to BSON.
23838     @param o The output adapter that receives the binary BSON representation.
23839     @pre The input `j` shall be an object: `j.is_object() == true`
23840     @sa @ref to_bson(const basic_json&)
23841     */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)23842     static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23843     {
23844         binary_writer<uint8_t>(o).write_bson(j);
23845     }
23846 
23847     /*!
23848     @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
23849     */
to_bson(const basic_json & j,detail::output_adapter<char> o)23850     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23851     {
23852         binary_writer<char>(o).write_bson(j);
23853     }
23854 
23855 
23856     /*!
23857     @brief create a JSON value from an input in CBOR format
23858 
23859     Deserializes a given input @a i to a JSON value using the CBOR (Concise
23860     Binary Object Representation) serialization format.
23861 
23862     The library maps CBOR types to JSON value types as follows:
23863 
23864     CBOR type              | JSON value type | first byte
23865     ---------------------- | --------------- | ----------
23866     Integer                | number_unsigned | 0x00..0x17
23867     Unsigned integer       | number_unsigned | 0x18
23868     Unsigned integer       | number_unsigned | 0x19
23869     Unsigned integer       | number_unsigned | 0x1A
23870     Unsigned integer       | number_unsigned | 0x1B
23871     Negative integer       | number_integer  | 0x20..0x37
23872     Negative integer       | number_integer  | 0x38
23873     Negative integer       | number_integer  | 0x39
23874     Negative integer       | number_integer  | 0x3A
23875     Negative integer       | number_integer  | 0x3B
23876     Byte string            | binary          | 0x40..0x57
23877     Byte string            | binary          | 0x58
23878     Byte string            | binary          | 0x59
23879     Byte string            | binary          | 0x5A
23880     Byte string            | binary          | 0x5B
23881     UTF-8 string           | string          | 0x60..0x77
23882     UTF-8 string           | string          | 0x78
23883     UTF-8 string           | string          | 0x79
23884     UTF-8 string           | string          | 0x7A
23885     UTF-8 string           | string          | 0x7B
23886     UTF-8 string           | string          | 0x7F
23887     array                  | array           | 0x80..0x97
23888     array                  | array           | 0x98
23889     array                  | array           | 0x99
23890     array                  | array           | 0x9A
23891     array                  | array           | 0x9B
23892     array                  | array           | 0x9F
23893     map                    | object          | 0xA0..0xB7
23894     map                    | object          | 0xB8
23895     map                    | object          | 0xB9
23896     map                    | object          | 0xBA
23897     map                    | object          | 0xBB
23898     map                    | object          | 0xBF
23899     False                  | `false`         | 0xF4
23900     True                   | `true`          | 0xF5
23901     Null                   | `null`          | 0xF6
23902     Half-Precision Float   | number_float    | 0xF9
23903     Single-Precision Float | number_float    | 0xFA
23904     Double-Precision Float | number_float    | 0xFB
23905 
23906     @warning The mapping is **incomplete** in the sense that not all CBOR
23907              types can be converted to a JSON value. The following CBOR types
23908              are not supported and will yield parse errors (parse_error.112):
23909              - date/time (0xC0..0xC1)
23910              - bignum (0xC2..0xC3)
23911              - decimal fraction (0xC4)
23912              - bigfloat (0xC5)
23913              - expected conversions (0xD5..0xD7)
23914              - simple values (0xE0..0xF3, 0xF8)
23915              - undefined (0xF7)
23916 
23917     @warning CBOR allows map keys of any type, whereas JSON only allows
23918              strings as keys in object values. Therefore, CBOR maps with keys
23919              other than UTF-8 strings are rejected (parse_error.113).
23920 
23921     @note Any CBOR output created @ref to_cbor can be successfully parsed by
23922           @ref from_cbor.
23923 
23924     @param[in] i  an input in CBOR format convertible to an input adapter
23925     @param[in] strict  whether to expect the input to be consumed until EOF
23926                        (true by default)
23927     @param[in] allow_exceptions  whether to throw exceptions in case of a
23928     parse error (optional, true by default)
23929     @param[in] tag_handler how to treat CBOR tags (optional, error by default)
23930 
23931     @return deserialized JSON value; in case of a parse error and
23932             @a allow_exceptions set to `false`, the return value will be
23933             value_t::discarded.
23934 
23935     @throw parse_error.110 if the given input ends prematurely or the end of
23936     file was not reached when @a strict was set to true
23937     @throw parse_error.112 if unsupported features from CBOR were
23938     used in the given input @a v or if the input is not valid CBOR
23939     @throw parse_error.113 if a string was expected as map key, but not found
23940 
23941     @complexity Linear in the size of the input @a i.
23942 
23943     @liveexample{The example shows the deserialization of a byte vector in CBOR
23944     format to a JSON value.,from_cbor}
23945 
23946     @sa http://cbor.io
23947     @sa @ref to_cbor(const basic_json&) for the analogous serialization
23948     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
23949         related MessagePack format
23950     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
23951         related UBJSON format
23952 
23953     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
23954            consume input adapters, removed start_index parameter, and added
23955            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
23956            since 3.2.0; added @a tag_handler parameter since 3.9.0.
23957     */
23958     template<typename InputType>
23959     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)23960     static basic_json from_cbor(InputType&& i,
23961                                 const bool strict = true,
23962                                 const bool allow_exceptions = true,
23963                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23964     {
23965         basic_json result;
23966         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23967         auto ia = detail::input_adapter(std::forward<InputType>(i));
23968         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23969         return res ? result : basic_json(value_t::discarded);
23970     }
23971 
23972     /*!
23973     @copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t)
23974     */
23975     template<typename IteratorType>
23976     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)23977     static basic_json from_cbor(IteratorType first, IteratorType last,
23978                                 const bool strict = true,
23979                                 const bool allow_exceptions = true,
23980                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23981     {
23982         basic_json result;
23983         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23984         auto ia = detail::input_adapter(std::move(first), std::move(last));
23985         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
23986         return res ? result : basic_json(value_t::discarded);
23987     }
23988 
23989     template<typename T>
23990     JSON_HEDLEY_WARN_UNUSED_RESULT
23991     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
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)23992     static basic_json from_cbor(const T* ptr, std::size_t len,
23993                                 const bool strict = true,
23994                                 const bool allow_exceptions = true,
23995                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
23996     {
23997         return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
23998     }
23999 
24000 
24001     JSON_HEDLEY_WARN_UNUSED_RESULT
24002     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
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)24003     static basic_json from_cbor(detail::span_input_adapter&& i,
24004                                 const bool strict = true,
24005                                 const bool allow_exceptions = true,
24006                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24007     {
24008         basic_json result;
24009         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24010         auto ia = i.get();
24011         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24012         return res ? result : basic_json(value_t::discarded);
24013     }
24014 
24015     /*!
24016     @brief create a JSON value from an input in MessagePack format
24017 
24018     Deserializes a given input @a i to a JSON value using the MessagePack
24019     serialization format.
24020 
24021     The library maps MessagePack types to JSON value types as follows:
24022 
24023     MessagePack type | JSON value type | first byte
24024     ---------------- | --------------- | ----------
24025     positive fixint  | number_unsigned | 0x00..0x7F
24026     fixmap           | object          | 0x80..0x8F
24027     fixarray         | array           | 0x90..0x9F
24028     fixstr           | string          | 0xA0..0xBF
24029     nil              | `null`          | 0xC0
24030     false            | `false`         | 0xC2
24031     true             | `true`          | 0xC3
24032     float 32         | number_float    | 0xCA
24033     float 64         | number_float    | 0xCB
24034     uint 8           | number_unsigned | 0xCC
24035     uint 16          | number_unsigned | 0xCD
24036     uint 32          | number_unsigned | 0xCE
24037     uint 64          | number_unsigned | 0xCF
24038     int 8            | number_integer  | 0xD0
24039     int 16           | number_integer  | 0xD1
24040     int 32           | number_integer  | 0xD2
24041     int 64           | number_integer  | 0xD3
24042     str 8            | string          | 0xD9
24043     str 16           | string          | 0xDA
24044     str 32           | string          | 0xDB
24045     array 16         | array           | 0xDC
24046     array 32         | array           | 0xDD
24047     map 16           | object          | 0xDE
24048     map 32           | object          | 0xDF
24049     bin 8            | binary          | 0xC4
24050     bin 16           | binary          | 0xC5
24051     bin 32           | binary          | 0xC6
24052     ext 8            | binary          | 0xC7
24053     ext 16           | binary          | 0xC8
24054     ext 32           | binary          | 0xC9
24055     fixext 1         | binary          | 0xD4
24056     fixext 2         | binary          | 0xD5
24057     fixext 4         | binary          | 0xD6
24058     fixext 8         | binary          | 0xD7
24059     fixext 16        | binary          | 0xD8
24060     negative fixint  | number_integer  | 0xE0-0xFF
24061 
24062     @note Any MessagePack output created @ref to_msgpack can be successfully
24063           parsed by @ref from_msgpack.
24064 
24065     @param[in] i  an input in MessagePack format convertible to an input
24066                   adapter
24067     @param[in] strict  whether to expect the input to be consumed until EOF
24068                        (true by default)
24069     @param[in] allow_exceptions  whether to throw exceptions in case of a
24070     parse error (optional, true by default)
24071 
24072     @return deserialized JSON value; in case of a parse error and
24073             @a allow_exceptions set to `false`, the return value will be
24074             value_t::discarded.
24075 
24076     @throw parse_error.110 if the given input ends prematurely or the end of
24077     file was not reached when @a strict was set to true
24078     @throw parse_error.112 if unsupported features from MessagePack were
24079     used in the given input @a i or if the input is not valid MessagePack
24080     @throw parse_error.113 if a string was expected as map key, but not found
24081 
24082     @complexity Linear in the size of the input @a i.
24083 
24084     @liveexample{The example shows the deserialization of a byte vector in
24085     MessagePack format to a JSON value.,from_msgpack}
24086 
24087     @sa http://msgpack.org
24088     @sa @ref to_msgpack(const basic_json&) for the analogous serialization
24089     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24090         related CBOR format
24091     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
24092         the related UBJSON format
24093     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24094         the related BSON format
24095 
24096     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
24097            consume input adapters, removed start_index parameter, and added
24098            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
24099            since 3.2.0
24100     */
24101     template<typename InputType>
24102     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(InputType && i,const bool strict=true,const bool allow_exceptions=true)24103     static basic_json from_msgpack(InputType&& i,
24104                                    const bool strict = true,
24105                                    const bool allow_exceptions = true)
24106     {
24107         basic_json result;
24108         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24109         auto ia = detail::input_adapter(std::forward<InputType>(i));
24110         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24111         return res ? result : basic_json(value_t::discarded);
24112     }
24113 
24114     /*!
24115     @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
24116     */
24117     template<typename IteratorType>
24118     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24119     static basic_json from_msgpack(IteratorType first, IteratorType last,
24120                                    const bool strict = true,
24121                                    const bool allow_exceptions = true)
24122     {
24123         basic_json result;
24124         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24125         auto ia = detail::input_adapter(std::move(first), std::move(last));
24126         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24127         return res ? result : basic_json(value_t::discarded);
24128     }
24129 
24130 
24131     template<typename T>
24132     JSON_HEDLEY_WARN_UNUSED_RESULT
24133     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)24134     static basic_json from_msgpack(const T* ptr, std::size_t len,
24135                                    const bool strict = true,
24136                                    const bool allow_exceptions = true)
24137     {
24138         return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24139     }
24140 
24141     JSON_HEDLEY_WARN_UNUSED_RESULT
24142     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)24143     static basic_json from_msgpack(detail::span_input_adapter&& i,
24144                                    const bool strict = true,
24145                                    const bool allow_exceptions = true)
24146     {
24147         basic_json result;
24148         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24149         auto ia = i.get();
24150         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24151         return res ? result : basic_json(value_t::discarded);
24152     }
24153 
24154 
24155     /*!
24156     @brief create a JSON value from an input in UBJSON format
24157 
24158     Deserializes a given input @a i to a JSON value using the UBJSON (Universal
24159     Binary JSON) serialization format.
24160 
24161     The library maps UBJSON types to JSON value types as follows:
24162 
24163     UBJSON type | JSON value type                         | marker
24164     ----------- | --------------------------------------- | ------
24165     no-op       | *no value, next value is read*          | `N`
24166     null        | `null`                                  | `Z`
24167     false       | `false`                                 | `F`
24168     true        | `true`                                  | `T`
24169     float32     | number_float                            | `d`
24170     float64     | number_float                            | `D`
24171     uint8       | number_unsigned                         | `U`
24172     int8        | number_integer                          | `i`
24173     int16       | number_integer                          | `I`
24174     int32       | number_integer                          | `l`
24175     int64       | number_integer                          | `L`
24176     high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
24177     string      | string                                  | `S`
24178     char        | string                                  | `C`
24179     array       | array (optimized values are supported)  | `[`
24180     object      | object (optimized values are supported) | `{`
24181 
24182     @note The mapping is **complete** in the sense that any UBJSON value can
24183           be converted to a JSON value.
24184 
24185     @param[in] i  an input in UBJSON format convertible to an input adapter
24186     @param[in] strict  whether to expect the input to be consumed until EOF
24187                        (true by default)
24188     @param[in] allow_exceptions  whether to throw exceptions in case of a
24189     parse error (optional, true by default)
24190 
24191     @return deserialized JSON value; in case of a parse error and
24192             @a allow_exceptions set to `false`, the return value will be
24193             value_t::discarded.
24194 
24195     @throw parse_error.110 if the given input ends prematurely or the end of
24196     file was not reached when @a strict was set to true
24197     @throw parse_error.112 if a parse error occurs
24198     @throw parse_error.113 if a string could not be parsed successfully
24199 
24200     @complexity Linear in the size of the input @a i.
24201 
24202     @liveexample{The example shows the deserialization of a byte vector in
24203     UBJSON format to a JSON value.,from_ubjson}
24204 
24205     @sa http://ubjson.org
24206     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
24207              analogous serialization
24208     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24209         related CBOR format
24210     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24211         the related MessagePack format
24212     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24213         the related BSON format
24214 
24215     @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
24216     */
24217     template<typename InputType>
24218     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(InputType && i,const bool strict=true,const bool allow_exceptions=true)24219     static basic_json from_ubjson(InputType&& i,
24220                                   const bool strict = true,
24221                                   const bool allow_exceptions = true)
24222     {
24223         basic_json result;
24224         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24225         auto ia = detail::input_adapter(std::forward<InputType>(i));
24226         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24227         return res ? result : basic_json(value_t::discarded);
24228     }
24229 
24230     /*!
24231     @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
24232     */
24233     template<typename IteratorType>
24234     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24235     static basic_json from_ubjson(IteratorType first, IteratorType last,
24236                                   const bool strict = true,
24237                                   const bool allow_exceptions = true)
24238     {
24239         basic_json result;
24240         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24241         auto ia = detail::input_adapter(std::move(first), std::move(last));
24242         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24243         return res ? result : basic_json(value_t::discarded);
24244     }
24245 
24246     template<typename T>
24247     JSON_HEDLEY_WARN_UNUSED_RESULT
24248     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)24249     static basic_json from_ubjson(const T* ptr, std::size_t len,
24250                                   const bool strict = true,
24251                                   const bool allow_exceptions = true)
24252     {
24253         return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24254     }
24255 
24256     JSON_HEDLEY_WARN_UNUSED_RESULT
24257     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)24258     static basic_json from_ubjson(detail::span_input_adapter&& i,
24259                                   const bool strict = true,
24260                                   const bool allow_exceptions = true)
24261     {
24262         basic_json result;
24263         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24264         auto ia = i.get();
24265         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24266         return res ? result : basic_json(value_t::discarded);
24267     }
24268 
24269 
24270     /*!
24271     @brief Create a JSON value from an input in BSON format
24272 
24273     Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
24274     serialization format.
24275 
24276     The library maps BSON record types to JSON value types as follows:
24277 
24278     BSON type       | BSON marker byte | JSON value type
24279     --------------- | ---------------- | ---------------------------
24280     double          | 0x01             | number_float
24281     string          | 0x02             | string
24282     document        | 0x03             | object
24283     array           | 0x04             | array
24284     binary          | 0x05             | still unsupported
24285     undefined       | 0x06             | still unsupported
24286     ObjectId        | 0x07             | still unsupported
24287     boolean         | 0x08             | boolean
24288     UTC Date-Time   | 0x09             | still unsupported
24289     null            | 0x0A             | null
24290     Regular Expr.   | 0x0B             | still unsupported
24291     DB Pointer      | 0x0C             | still unsupported
24292     JavaScript Code | 0x0D             | still unsupported
24293     Symbol          | 0x0E             | still unsupported
24294     JavaScript Code | 0x0F             | still unsupported
24295     int32           | 0x10             | number_integer
24296     Timestamp       | 0x11             | still unsupported
24297     128-bit decimal float | 0x13       | still unsupported
24298     Max Key         | 0x7F             | still unsupported
24299     Min Key         | 0xFF             | still unsupported
24300 
24301     @warning The mapping is **incomplete**. The unsupported mappings
24302              are indicated in the table above.
24303 
24304     @param[in] i  an input in BSON format convertible to an input adapter
24305     @param[in] strict  whether to expect the input to be consumed until EOF
24306                        (true by default)
24307     @param[in] allow_exceptions  whether to throw exceptions in case of a
24308     parse error (optional, true by default)
24309 
24310     @return deserialized JSON value; in case of a parse error and
24311             @a allow_exceptions set to `false`, the return value will be
24312             value_t::discarded.
24313 
24314     @throw parse_error.114 if an unsupported BSON record type is encountered
24315 
24316     @complexity Linear in the size of the input @a i.
24317 
24318     @liveexample{The example shows the deserialization of a byte vector in
24319     BSON format to a JSON value.,from_bson}
24320 
24321     @sa http://bsonspec.org/spec.html
24322     @sa @ref to_bson(const basic_json&) for the analogous serialization
24323     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24324         related CBOR format
24325     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24326         the related MessagePack format
24327     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
24328         related UBJSON format
24329     */
24330     template<typename InputType>
24331     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(InputType && i,const bool strict=true,const bool allow_exceptions=true)24332     static basic_json from_bson(InputType&& i,
24333                                 const bool strict = true,
24334                                 const bool allow_exceptions = true)
24335     {
24336         basic_json result;
24337         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24338         auto ia = detail::input_adapter(std::forward<InputType>(i));
24339         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24340         return res ? result : basic_json(value_t::discarded);
24341     }
24342 
24343     /*!
24344     @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
24345     */
24346     template<typename IteratorType>
24347     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24348     static basic_json from_bson(IteratorType first, IteratorType last,
24349                                 const bool strict = true,
24350                                 const bool allow_exceptions = true)
24351     {
24352         basic_json result;
24353         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24354         auto ia = detail::input_adapter(std::move(first), std::move(last));
24355         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24356         return res ? result : basic_json(value_t::discarded);
24357     }
24358 
24359     template<typename T>
24360     JSON_HEDLEY_WARN_UNUSED_RESULT
24361     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)24362     static basic_json from_bson(const T* ptr, std::size_t len,
24363                                 const bool strict = true,
24364                                 const bool allow_exceptions = true)
24365     {
24366         return from_bson(ptr, ptr + len, strict, allow_exceptions);
24367     }
24368 
24369     JSON_HEDLEY_WARN_UNUSED_RESULT
24370     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)24371     static basic_json from_bson(detail::span_input_adapter&& i,
24372                                 const bool strict = true,
24373                                 const bool allow_exceptions = true)
24374     {
24375         basic_json result;
24376         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24377         auto ia = i.get();
24378         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24379         return res ? result : basic_json(value_t::discarded);
24380     }
24381     /// @}
24382 
24383     //////////////////////////
24384     // JSON Pointer support //
24385     //////////////////////////
24386 
24387     /// @name JSON Pointer functions
24388     /// @{
24389 
24390     /*!
24391     @brief access specified element via JSON Pointer
24392 
24393     Uses a JSON pointer to retrieve a reference to the respective JSON value.
24394     No bound checking is performed. Similar to @ref operator[](const typename
24395     object_t::key_type&), `null` values are created in arrays and objects if
24396     necessary.
24397 
24398     In particular:
24399     - If the JSON pointer points to an object key that does not exist, it
24400       is created an filled with a `null` value before a reference to it
24401       is returned.
24402     - If the JSON pointer points to an array index that does not exist, it
24403       is created an filled with a `null` value before a reference to it
24404       is returned. All indices between the current maximum and the given
24405       index are also filled with `null`.
24406     - The special value `-` is treated as a synonym for the index past the
24407       end.
24408 
24409     @param[in] ptr  a JSON pointer
24410 
24411     @return reference to the element pointed to by @a ptr
24412 
24413     @complexity Constant.
24414 
24415     @throw parse_error.106   if an array index begins with '0'
24416     @throw parse_error.109   if an array index was not a number
24417     @throw out_of_range.404  if the JSON pointer can not be resolved
24418 
24419     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
24420 
24421     @since version 2.0.0
24422     */
operator [](const json_pointer & ptr)24423     reference operator[](const json_pointer& ptr)
24424     {
24425         return ptr.get_unchecked(this);
24426     }
24427 
24428     /*!
24429     @brief access specified element via JSON Pointer
24430 
24431     Uses a JSON pointer to retrieve a reference to the respective JSON value.
24432     No bound checking is performed. The function does not change the JSON
24433     value; no `null` values are created. In particular, the special value
24434     `-` yields an exception.
24435 
24436     @param[in] ptr  JSON pointer to the desired element
24437 
24438     @return const reference to the element pointed to by @a ptr
24439 
24440     @complexity Constant.
24441 
24442     @throw parse_error.106   if an array index begins with '0'
24443     @throw parse_error.109   if an array index was not a number
24444     @throw out_of_range.402  if the array index '-' is used
24445     @throw out_of_range.404  if the JSON pointer can not be resolved
24446 
24447     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
24448 
24449     @since version 2.0.0
24450     */
operator [](const json_pointer & ptr) const24451     const_reference operator[](const json_pointer& ptr) const
24452     {
24453         return ptr.get_unchecked(this);
24454     }
24455 
24456     /*!
24457     @brief access specified element via JSON Pointer
24458 
24459     Returns a reference to the element at with specified JSON pointer @a ptr,
24460     with bounds checking.
24461 
24462     @param[in] ptr  JSON pointer to the desired element
24463 
24464     @return reference to the element pointed to by @a ptr
24465 
24466     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24467     begins with '0'. See example below.
24468 
24469     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24470     is not a number. See example below.
24471 
24472     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24473     is out of range. See example below.
24474 
24475     @throw out_of_range.402 if the array index '-' is used in the passed JSON
24476     pointer @a ptr. As `at` provides checked access (and no elements are
24477     implicitly inserted), the index '-' is always invalid. See example below.
24478 
24479     @throw out_of_range.403 if the JSON pointer describes a key of an object
24480     which cannot be found. See example below.
24481 
24482     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24483     See example below.
24484 
24485     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24486     changes in the JSON value.
24487 
24488     @complexity Constant.
24489 
24490     @since version 2.0.0
24491 
24492     @liveexample{The behavior is shown in the example.,at_json_pointer}
24493     */
at(const json_pointer & ptr)24494     reference at(const json_pointer& ptr)
24495     {
24496         return ptr.get_checked(this);
24497     }
24498 
24499     /*!
24500     @brief access specified element via JSON Pointer
24501 
24502     Returns a const reference to the element at with specified JSON pointer @a
24503     ptr, with bounds checking.
24504 
24505     @param[in] ptr  JSON pointer to the desired element
24506 
24507     @return reference to the element pointed to by @a ptr
24508 
24509     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24510     begins with '0'. See example below.
24511 
24512     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24513     is not a number. See example below.
24514 
24515     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24516     is out of range. See example below.
24517 
24518     @throw out_of_range.402 if the array index '-' is used in the passed JSON
24519     pointer @a ptr. As `at` provides checked access (and no elements are
24520     implicitly inserted), the index '-' is always invalid. See example below.
24521 
24522     @throw out_of_range.403 if the JSON pointer describes a key of an object
24523     which cannot be found. See example below.
24524 
24525     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24526     See example below.
24527 
24528     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24529     changes in the JSON value.
24530 
24531     @complexity Constant.
24532 
24533     @since version 2.0.0
24534 
24535     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
24536     */
at(const json_pointer & ptr) const24537     const_reference at(const json_pointer& ptr) const
24538     {
24539         return ptr.get_checked(this);
24540     }
24541 
24542     /*!
24543     @brief return flattened JSON value
24544 
24545     The function creates a JSON object whose keys are JSON pointers (see [RFC
24546     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
24547     primitive. The original JSON value can be restored using the @ref
24548     unflatten() function.
24549 
24550     @return an object that maps JSON pointers to primitive values
24551 
24552     @note Empty objects and arrays are flattened to `null` and will not be
24553           reconstructed correctly by the @ref unflatten() function.
24554 
24555     @complexity Linear in the size the JSON value.
24556 
24557     @liveexample{The following code shows how a JSON object is flattened to an
24558     object whose keys consist of JSON pointers.,flatten}
24559 
24560     @sa @ref unflatten() for the reverse function
24561 
24562     @since version 2.0.0
24563     */
flatten() const24564     basic_json flatten() const
24565     {
24566         basic_json result(value_t::object);
24567         json_pointer::flatten("", *this, result);
24568         return result;
24569     }
24570 
24571     /*!
24572     @brief unflatten a previously flattened JSON value
24573 
24574     The function restores the arbitrary nesting of a JSON value that has been
24575     flattened before using the @ref flatten() function. The JSON value must
24576     meet certain constraints:
24577     1. The value must be an object.
24578     2. The keys must be JSON pointers (see
24579        [RFC 6901](https://tools.ietf.org/html/rfc6901))
24580     3. The mapped values must be primitive JSON types.
24581 
24582     @return the original JSON from a flattened version
24583 
24584     @note Empty objects and arrays are flattened by @ref flatten() to `null`
24585           values and can not unflattened to their original type. Apart from
24586           this example, for a JSON value `j`, the following is always true:
24587           `j == j.flatten().unflatten()`.
24588 
24589     @complexity Linear in the size the JSON value.
24590 
24591     @throw type_error.314  if value is not an object
24592     @throw type_error.315  if object values are not primitive
24593 
24594     @liveexample{The following code shows how a flattened JSON object is
24595     unflattened into the original nested JSON object.,unflatten}
24596 
24597     @sa @ref flatten() for the reverse function
24598 
24599     @since version 2.0.0
24600     */
unflatten() const24601     basic_json unflatten() const
24602     {
24603         return json_pointer::unflatten(*this);
24604     }
24605 
24606     /// @}
24607 
24608     //////////////////////////
24609     // JSON Patch functions //
24610     //////////////////////////
24611 
24612     /// @name JSON Patch functions
24613     /// @{
24614 
24615     /*!
24616     @brief applies a JSON patch
24617 
24618     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
24619     expressing a sequence of operations to apply to a JSON) document. With
24620     this function, a JSON Patch is applied to the current JSON value by
24621     executing all operations from the patch.
24622 
24623     @param[in] json_patch  JSON patch document
24624     @return patched document
24625 
24626     @note The application of a patch is atomic: Either all operations succeed
24627           and the patched document is returned or an exception is thrown. In
24628           any case, the original value is not changed: the patch is applied
24629           to a copy of the value.
24630 
24631     @throw parse_error.104 if the JSON patch does not consist of an array of
24632     objects
24633 
24634     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
24635     attributes are missing); example: `"operation add must have member path"`
24636 
24637     @throw out_of_range.401 if an array index is out of range.
24638 
24639     @throw out_of_range.403 if a JSON pointer inside the patch could not be
24640     resolved successfully in the current JSON value; example: `"key baz not
24641     found"`
24642 
24643     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
24644     "move")
24645 
24646     @throw other_error.501 if "test" operation was unsuccessful
24647 
24648     @complexity Linear in the size of the JSON value and the length of the
24649     JSON patch. As usually only a fraction of the JSON value is affected by
24650     the patch, the complexity can usually be neglected.
24651 
24652     @liveexample{The following code shows how a JSON patch is applied to a
24653     value.,patch}
24654 
24655     @sa @ref diff -- create a JSON patch by comparing two JSON values
24656 
24657     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
24658     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
24659 
24660     @since version 2.0.0
24661     */
patch(const basic_json & json_patch) const24662     basic_json patch(const basic_json& json_patch) const
24663     {
24664         // make a working copy to apply the patch to
24665         basic_json result = *this;
24666 
24667         // the valid JSON Patch operations
24668         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24669 
24670         const auto get_op = [](const std::string & op)
24671         {
24672             if (op == "add")
24673             {
24674                 return patch_operations::add;
24675             }
24676             if (op == "remove")
24677             {
24678                 return patch_operations::remove;
24679             }
24680             if (op == "replace")
24681             {
24682                 return patch_operations::replace;
24683             }
24684             if (op == "move")
24685             {
24686                 return patch_operations::move;
24687             }
24688             if (op == "copy")
24689             {
24690                 return patch_operations::copy;
24691             }
24692             if (op == "test")
24693             {
24694                 return patch_operations::test;
24695             }
24696 
24697             return patch_operations::invalid;
24698         };
24699 
24700         // wrapper for "add" operation; add value at ptr
24701         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24702         {
24703             // adding to the root of the target document means replacing it
24704             if (ptr.empty())
24705             {
24706                 result = val;
24707                 return;
24708             }
24709 
24710             // make sure the top element of the pointer exists
24711             json_pointer top_pointer = ptr.top();
24712             if (top_pointer != ptr)
24713             {
24714                 result.at(top_pointer);
24715             }
24716 
24717             // get reference to parent of JSON pointer ptr
24718             const auto last_path = ptr.back();
24719             ptr.pop_back();
24720             basic_json& parent = result[ptr];
24721 
24722             switch (parent.m_type)
24723             {
24724                 case value_t::null:
24725                 case value_t::object:
24726                 {
24727                     // use operator[] to add value
24728                     parent[last_path] = val;
24729                     break;
24730                 }
24731 
24732                 case value_t::array:
24733                 {
24734                     if (last_path == "-")
24735                     {
24736                         // special case: append to back
24737                         parent.push_back(val);
24738                     }
24739                     else
24740                     {
24741                         const auto idx = json_pointer::array_index(last_path);
24742                         if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24743                         {
24744                             // avoid undefined behavior
24745                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24746                         }
24747 
24748                         // default case: insert add offset
24749                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24750                     }
24751                     break;
24752                 }
24753 
24754                 // if there exists a parent it cannot be primitive
24755                 default:            // LCOV_EXCL_LINE
24756                     JSON_ASSERT(false);  // LCOV_EXCL_LINE
24757             }
24758         };
24759 
24760         // wrapper for "remove" operation; remove value at ptr
24761         const auto operation_remove = [&result](json_pointer & ptr)
24762         {
24763             // get reference to parent of JSON pointer ptr
24764             const auto last_path = ptr.back();
24765             ptr.pop_back();
24766             basic_json& parent = result.at(ptr);
24767 
24768             // remove child
24769             if (parent.is_object())
24770             {
24771                 // perform range check
24772                 auto it = parent.find(last_path);
24773                 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24774                 {
24775                     parent.erase(it);
24776                 }
24777                 else
24778                 {
24779                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24780                 }
24781             }
24782             else if (parent.is_array())
24783             {
24784                 // note erase performs range check
24785                 parent.erase(json_pointer::array_index(last_path));
24786             }
24787         };
24788 
24789         // type check: top level value must be an array
24790         if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24791         {
24792             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24793         }
24794 
24795         // iterate and apply the operations
24796         for (const auto& val : json_patch)
24797         {
24798             // wrapper to get a value for an operation
24799             const auto get_value = [&val](const std::string & op,
24800                                           const std::string & member,
24801                                           bool string_type) -> basic_json &
24802             {
24803                 // find value
24804                 auto it = val.m_value.object->find(member);
24805 
24806                 // context-sensitive error message
24807                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24808 
24809                 // check if desired value is present
24810                 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24811                 {
24812                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24813                 }
24814 
24815                 // check if result is of type string
24816                 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24817                 {
24818                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24819                 }
24820 
24821                 // no error: return value
24822                 return it->second;
24823             };
24824 
24825             // type check: every element of the array must be an object
24826             if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24827             {
24828                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24829             }
24830 
24831             // collect mandatory members
24832             const auto op = get_value("op", "op", true).template get<std::string>();
24833             const auto path = get_value(op, "path", true).template get<std::string>();
24834             json_pointer ptr(path);
24835 
24836             switch (get_op(op))
24837             {
24838                 case patch_operations::add:
24839                 {
24840                     operation_add(ptr, get_value("add", "value", false));
24841                     break;
24842                 }
24843 
24844                 case patch_operations::remove:
24845                 {
24846                     operation_remove(ptr);
24847                     break;
24848                 }
24849 
24850                 case patch_operations::replace:
24851                 {
24852                     // the "path" location must exist - use at()
24853                     result.at(ptr) = get_value("replace", "value", false);
24854                     break;
24855                 }
24856 
24857                 case patch_operations::move:
24858                 {
24859                     const auto from_path = get_value("move", "from", true).template get<std::string>();
24860                     json_pointer from_ptr(from_path);
24861 
24862                     // the "from" location must exist - use at()
24863                     basic_json v = result.at(from_ptr);
24864 
24865                     // The move operation is functionally identical to a
24866                     // "remove" operation on the "from" location, followed
24867                     // immediately by an "add" operation at the target
24868                     // location with the value that was just removed.
24869                     operation_remove(from_ptr);
24870                     operation_add(ptr, v);
24871                     break;
24872                 }
24873 
24874                 case patch_operations::copy:
24875                 {
24876                     const auto from_path = get_value("copy", "from", true).template get<std::string>();
24877                     const json_pointer from_ptr(from_path);
24878 
24879                     // the "from" location must exist - use at()
24880                     basic_json v = result.at(from_ptr);
24881 
24882                     // The copy is functionally identical to an "add"
24883                     // operation at the target location using the value
24884                     // specified in the "from" member.
24885                     operation_add(ptr, v);
24886                     break;
24887                 }
24888 
24889                 case patch_operations::test:
24890                 {
24891                     bool success = false;
24892                     JSON_TRY
24893                     {
24894                         // check if "value" matches the one at "path"
24895                         // the "path" location must exist - use at()
24896                         success = (result.at(ptr) == get_value("test", "value", false));
24897                     }
24898                     JSON_INTERNAL_CATCH (out_of_range&)
24899                     {
24900                         // ignore out of range errors: success remains false
24901                     }
24902 
24903                     // throw an exception if test fails
24904                     if (JSON_HEDLEY_UNLIKELY(!success))
24905                     {
24906                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24907                     }
24908 
24909                     break;
24910                 }
24911 
24912                 default:
24913                 {
24914                     // op must be "add", "remove", "replace", "move", "copy", or
24915                     // "test"
24916                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
24917                 }
24918             }
24919         }
24920 
24921         return result;
24922     }
24923 
24924     /*!
24925     @brief creates a diff as a JSON patch
24926 
24927     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
24928     be changed into the value @a target by calling @ref patch function.
24929 
24930     @invariant For two JSON values @a source and @a target, the following code
24931     yields always `true`:
24932     @code {.cpp}
24933     source.patch(diff(source, target)) == target;
24934     @endcode
24935 
24936     @note Currently, only `remove`, `add`, and `replace` operations are
24937           generated.
24938 
24939     @param[in] source  JSON value to compare from
24940     @param[in] target  JSON value to compare against
24941     @param[in] path    helper value to create JSON pointers
24942 
24943     @return a JSON patch to convert the @a source to @a target
24944 
24945     @complexity Linear in the lengths of @a source and @a target.
24946 
24947     @liveexample{The following code shows how a JSON patch is created as a
24948     diff for two JSON values.,diff}
24949 
24950     @sa @ref patch -- apply a JSON patch
24951     @sa @ref merge_patch -- apply a JSON Merge Patch
24952 
24953     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
24954 
24955     @since version 2.0.0
24956     */
24957     JSON_HEDLEY_WARN_UNUSED_RESULT
diff(const basic_json & source,const basic_json & target,const std::string & path="")24958     static basic_json diff(const basic_json& source, const basic_json& target,
24959                            const std::string& path = "")
24960     {
24961         // the patch
24962         basic_json result(value_t::array);
24963 
24964         // if the values are the same, return empty patch
24965         if (source == target)
24966         {
24967             return result;
24968         }
24969 
24970         if (source.type() != target.type())
24971         {
24972             // different types: replace value
24973             result.push_back(
24974             {
24975                 {"op", "replace"}, {"path", path}, {"value", target}
24976             });
24977             return result;
24978         }
24979 
24980         switch (source.type())
24981         {
24982             case value_t::array:
24983             {
24984                 // first pass: traverse common elements
24985                 std::size_t i = 0;
24986                 while (i < source.size() && i < target.size())
24987                 {
24988                     // recursive call to compare array values at index i
24989                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
24990                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
24991                     ++i;
24992                 }
24993 
24994                 // i now reached the end of at least one array
24995                 // in a second pass, traverse the remaining elements
24996 
24997                 // remove my remaining elements
24998                 const auto end_index = static_cast<difference_type>(result.size());
24999                 while (i < source.size())
25000                 {
25001                     // add operations in reverse order to avoid invalid
25002                     // indices
25003                     result.insert(result.begin() + end_index, object(
25004                     {
25005                         {"op", "remove"},
25006                         {"path", path + "/" + std::to_string(i)}
25007                     }));
25008                     ++i;
25009                 }
25010 
25011                 // add other remaining elements
25012                 while (i < target.size())
25013                 {
25014                     result.push_back(
25015                     {
25016                         {"op", "add"},
25017                         {"path", path + "/-"},
25018                         {"value", target[i]}
25019                     });
25020                     ++i;
25021                 }
25022 
25023                 break;
25024             }
25025 
25026             case value_t::object:
25027             {
25028                 // first pass: traverse this object's elements
25029                 for (auto it = source.cbegin(); it != source.cend(); ++it)
25030                 {
25031                     // escape the key name to be used in a JSON patch
25032                     const auto key = json_pointer::escape(it.key());
25033 
25034                     if (target.find(it.key()) != target.end())
25035                     {
25036                         // recursive call to compare object values at key it
25037                         auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25038                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25039                     }
25040                     else
25041                     {
25042                         // found a key that is not in o -> remove it
25043                         result.push_back(object(
25044                         {
25045                             {"op", "remove"}, {"path", path + "/" + key}
25046                         }));
25047                     }
25048                 }
25049 
25050                 // second pass: traverse other object's elements
25051                 for (auto it = target.cbegin(); it != target.cend(); ++it)
25052                 {
25053                     if (source.find(it.key()) == source.end())
25054                     {
25055                         // found a key that is not in this -> add it
25056                         const auto key = json_pointer::escape(it.key());
25057                         result.push_back(
25058                         {
25059                             {"op", "add"}, {"path", path + "/" + key},
25060                             {"value", it.value()}
25061                         });
25062                     }
25063                 }
25064 
25065                 break;
25066             }
25067 
25068             default:
25069             {
25070                 // both primitive type: replace value
25071                 result.push_back(
25072                 {
25073                     {"op", "replace"}, {"path", path}, {"value", target}
25074                 });
25075                 break;
25076             }
25077         }
25078 
25079         return result;
25080     }
25081 
25082     /// @}
25083 
25084     ////////////////////////////////
25085     // JSON Merge Patch functions //
25086     ////////////////////////////////
25087 
25088     /// @name JSON Merge Patch functions
25089     /// @{
25090 
25091     /*!
25092     @brief applies a JSON Merge Patch
25093 
25094     The merge patch format is primarily intended for use with the HTTP PATCH
25095     method as a means of describing a set of modifications to a target
25096     resource's content. This function applies a merge patch to the current
25097     JSON value.
25098 
25099     The function implements the following algorithm from Section 2 of
25100     [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
25101 
25102     ```
25103     define MergePatch(Target, Patch):
25104       if Patch is an Object:
25105         if Target is not an Object:
25106           Target = {} // Ignore the contents and set it to an empty Object
25107         for each Name/Value pair in Patch:
25108           if Value is null:
25109             if Name exists in Target:
25110               remove the Name/Value pair from Target
25111           else:
25112             Target[Name] = MergePatch(Target[Name], Value)
25113         return Target
25114       else:
25115         return Patch
25116     ```
25117 
25118     Thereby, `Target` is the current object; that is, the patch is applied to
25119     the current value.
25120 
25121     @param[in] apply_patch  the patch to apply
25122 
25123     @complexity Linear in the lengths of @a patch.
25124 
25125     @liveexample{The following code shows how a JSON Merge Patch is applied to
25126     a JSON document.,merge_patch}
25127 
25128     @sa @ref patch -- apply a JSON patch
25129     @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
25130 
25131     @since version 3.0.0
25132     */
merge_patch(const basic_json & apply_patch)25133     void merge_patch(const basic_json& apply_patch)
25134     {
25135         if (apply_patch.is_object())
25136         {
25137             if (!is_object())
25138             {
25139                 *this = object();
25140             }
25141             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25142             {
25143                 if (it.value().is_null())
25144                 {
25145                     erase(it.key());
25146                 }
25147                 else
25148                 {
25149                     operator[](it.key()).merge_patch(it.value());
25150                 }
25151             }
25152         }
25153         else
25154         {
25155             *this = apply_patch;
25156         }
25157     }
25158 
25159     /// @}
25160 };
25161 
25162 /*!
25163 @brief user-defined to_string function for JSON values
25164 
25165 This function implements a user-defined to_string  for JSON objects.
25166 
25167 @param[in] j  a JSON object
25168 @return a std::string object
25169 */
25170 
25171 NLOHMANN_BASIC_JSON_TPL_DECLARATION
to_string(const NLOHMANN_BASIC_JSON_TPL & j)25172 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25173 {
25174     return j.dump();
25175 }
25176 } // namespace nlohmann
25177 
25178 ///////////////////////
25179 // nonmember support //
25180 ///////////////////////
25181 
25182 // specialization of std::swap, and std::hash
25183 namespace std
25184 {
25185 
25186 /// hash value for JSON objects
25187 template<>
25188 struct hash<nlohmann::json>
25189 {
25190     /*!
25191     @brief return a hash value for a JSON object
25192 
25193     @since version 1.0.0
25194     */
operator ()std::hash25195     std::size_t operator()(const nlohmann::json& j) const
25196     {
25197         return nlohmann::detail::hash(j);
25198     }
25199 };
25200 
25201 /// specialization for std::less<value_t>
25202 /// @note: do not remove the space after '<',
25203 ///        see https://github.com/nlohmann/json/pull/679
25204 template<>
25205 struct less<::nlohmann::detail::value_t>
25206 {
25207     /*!
25208     @brief compare two value_t enum values
25209     @since version 3.0.0
25210     */
operator ()std::less25211     bool operator()(nlohmann::detail::value_t lhs,
25212                     nlohmann::detail::value_t rhs) const noexcept
25213     {
25214         return nlohmann::detail::operator<(lhs, rhs);
25215     }
25216 };
25217 
25218 // C++20 prohibit function specialization in the std namespace.
25219 #ifndef JSON_HAS_CPP_20
25220 
25221 /*!
25222 @brief exchanges the values of two JSON objects
25223 
25224 @since version 1.0.0
25225 */
25226 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)25227 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25228     is_nothrow_move_constructible<nlohmann::json>::value&&
25229     is_nothrow_move_assignable<nlohmann::json>::value
25230                               )
25231 {
25232     j1.swap(j2);
25233 }
25234 
25235 #endif
25236 
25237 } // namespace std
25238 
25239 /*!
25240 @brief user-defined string literal for JSON values
25241 
25242 This operator implements a user-defined string literal for JSON objects. It
25243 can be used by adding `"_json"` to a string literal and returns a JSON object
25244 if no parse error occurred.
25245 
25246 @param[in] s  a string representation of a JSON object
25247 @param[in] n  the length of string @a s
25248 @return a JSON object
25249 
25250 @since version 1.0.0
25251 */
25252 JSON_HEDLEY_NON_NULL(1)
operator ""_json(const char * s,std::size_t n)25253 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25254 {
25255     return nlohmann::json::parse(s, s + n);
25256 }
25257 
25258 /*!
25259 @brief user-defined string literal for JSON pointer
25260 
25261 This operator implements a user-defined string literal for JSON Pointers. It
25262 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
25263 object if no parse error occurred.
25264 
25265 @param[in] s  a string representation of a JSON Pointer
25266 @param[in] n  the length of string @a s
25267 @return a JSON pointer object
25268 
25269 @since version 2.0.0
25270 */
25271 JSON_HEDLEY_NON_NULL(1)
operator ""_json_pointer(const char * s,std::size_t n)25272 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25273 {
25274     return nlohmann::json::json_pointer(std::string(s, n));
25275 }
25276 
25277 // #include <nlohmann/detail/macro_unscope.hpp>
25278 
25279 
25280 // restore GCC/clang diagnostic settings
25281 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25282     #pragma GCC diagnostic pop
25283 #endif
25284 #if defined(__clang__)
25285     #pragma GCC diagnostic pop
25286 #endif
25287 
25288 // clean up
25289 #undef JSON_ASSERT
25290 #undef JSON_INTERNAL_CATCH
25291 #undef JSON_CATCH
25292 #undef JSON_THROW
25293 #undef JSON_TRY
25294 #undef JSON_HAS_CPP_14
25295 #undef JSON_HAS_CPP_17
25296 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25297 #undef NLOHMANN_BASIC_JSON_TPL
25298 #undef JSON_EXPLICIT
25299 
25300 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25301 #undef JSON_HEDLEY_ALWAYS_INLINE
25302 #undef JSON_HEDLEY_ARM_VERSION
25303 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25304 #undef JSON_HEDLEY_ARRAY_PARAM
25305 #undef JSON_HEDLEY_ASSUME
25306 #undef JSON_HEDLEY_BEGIN_C_DECLS
25307 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25308 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25309 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25310 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25311 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25312 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25313 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25314 #undef JSON_HEDLEY_COMPCERT_VERSION
25315 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25316 #undef JSON_HEDLEY_CONCAT
25317 #undef JSON_HEDLEY_CONCAT3
25318 #undef JSON_HEDLEY_CONCAT3_EX
25319 #undef JSON_HEDLEY_CONCAT_EX
25320 #undef JSON_HEDLEY_CONST
25321 #undef JSON_HEDLEY_CONSTEXPR
25322 #undef JSON_HEDLEY_CONST_CAST
25323 #undef JSON_HEDLEY_CPP_CAST
25324 #undef JSON_HEDLEY_CRAY_VERSION
25325 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25326 #undef JSON_HEDLEY_C_DECL
25327 #undef JSON_HEDLEY_DEPRECATED
25328 #undef JSON_HEDLEY_DEPRECATED_FOR
25329 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25330 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25331 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25332 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25333 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25334 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25335 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25336 #undef JSON_HEDLEY_DMC_VERSION
25337 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25338 #undef JSON_HEDLEY_EMPTY_BASES
25339 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25340 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25341 #undef JSON_HEDLEY_END_C_DECLS
25342 #undef JSON_HEDLEY_FLAGS
25343 #undef JSON_HEDLEY_FLAGS_CAST
25344 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25345 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25346 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25347 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25348 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25349 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25350 #undef JSON_HEDLEY_GCC_HAS_WARNING
25351 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25352 #undef JSON_HEDLEY_GCC_VERSION
25353 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25354 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25355 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25356 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25357 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25358 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25359 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25360 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25361 #undef JSON_HEDLEY_GNUC_VERSION
25362 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25363 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25364 #undef JSON_HEDLEY_HAS_BUILTIN
25365 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25366 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25367 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25368 #undef JSON_HEDLEY_HAS_EXTENSION
25369 #undef JSON_HEDLEY_HAS_FEATURE
25370 #undef JSON_HEDLEY_HAS_WARNING
25371 #undef JSON_HEDLEY_IAR_VERSION
25372 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25373 #undef JSON_HEDLEY_IBM_VERSION
25374 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25375 #undef JSON_HEDLEY_IMPORT
25376 #undef JSON_HEDLEY_INLINE
25377 #undef JSON_HEDLEY_INTEL_VERSION
25378 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25379 #undef JSON_HEDLEY_IS_CONSTANT
25380 #undef JSON_HEDLEY_IS_CONSTEXPR_
25381 #undef JSON_HEDLEY_LIKELY
25382 #undef JSON_HEDLEY_MALLOC
25383 #undef JSON_HEDLEY_MESSAGE
25384 #undef JSON_HEDLEY_MSVC_VERSION
25385 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25386 #undef JSON_HEDLEY_NEVER_INLINE
25387 #undef JSON_HEDLEY_NON_NULL
25388 #undef JSON_HEDLEY_NO_ESCAPE
25389 #undef JSON_HEDLEY_NO_RETURN
25390 #undef JSON_HEDLEY_NO_THROW
25391 #undef JSON_HEDLEY_NULL
25392 #undef JSON_HEDLEY_PELLES_VERSION
25393 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25394 #undef JSON_HEDLEY_PGI_VERSION
25395 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25396 #undef JSON_HEDLEY_PREDICT
25397 #undef JSON_HEDLEY_PRINTF_FORMAT
25398 #undef JSON_HEDLEY_PRIVATE
25399 #undef JSON_HEDLEY_PUBLIC
25400 #undef JSON_HEDLEY_PURE
25401 #undef JSON_HEDLEY_REINTERPRET_CAST
25402 #undef JSON_HEDLEY_REQUIRE
25403 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25404 #undef JSON_HEDLEY_REQUIRE_MSG
25405 #undef JSON_HEDLEY_RESTRICT
25406 #undef JSON_HEDLEY_RETURNS_NON_NULL
25407 #undef JSON_HEDLEY_SENTINEL
25408 #undef JSON_HEDLEY_STATIC_ASSERT
25409 #undef JSON_HEDLEY_STATIC_CAST
25410 #undef JSON_HEDLEY_STRINGIFY
25411 #undef JSON_HEDLEY_STRINGIFY_EX
25412 #undef JSON_HEDLEY_SUNPRO_VERSION
25413 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25414 #undef JSON_HEDLEY_TINYC_VERSION
25415 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25416 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25417 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25418 #undef JSON_HEDLEY_TI_CL2000_VERSION
25419 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25420 #undef JSON_HEDLEY_TI_CL430_VERSION
25421 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25422 #undef JSON_HEDLEY_TI_CL6X_VERSION
25423 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25424 #undef JSON_HEDLEY_TI_CL7X_VERSION
25425 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25426 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25427 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25428 #undef JSON_HEDLEY_TI_VERSION
25429 #undef JSON_HEDLEY_TI_VERSION_CHECK
25430 #undef JSON_HEDLEY_UNAVAILABLE
25431 #undef JSON_HEDLEY_UNLIKELY
25432 #undef JSON_HEDLEY_UNPREDICTABLE
25433 #undef JSON_HEDLEY_UNREACHABLE
25434 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25435 #undef JSON_HEDLEY_VERSION
25436 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25437 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25438 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25439 #undef JSON_HEDLEY_VERSION_ENCODE
25440 #undef JSON_HEDLEY_WARNING
25441 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
25442 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25443 #undef JSON_HEDLEY_FALL_THROUGH
25444 
25445 
25446 
25447 #endif  // INCLUDE_NLOHMANN_JSON_HPP_
25448