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 < 14)
123 #if defined(JSON_HEDLEY_VERSION)
124     #undef JSON_HEDLEY_VERSION
125 #endif
126 #define JSON_HEDLEY_VERSION 14
127 
128 #if defined(JSON_HEDLEY_STRINGIFY_EX)
129     #undef JSON_HEDLEY_STRINGIFY_EX
130 #endif
131 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
132 
133 #if defined(JSON_HEDLEY_STRINGIFY)
134     #undef JSON_HEDLEY_STRINGIFY
135 #endif
136 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
137 
138 #if defined(JSON_HEDLEY_CONCAT_EX)
139     #undef JSON_HEDLEY_CONCAT_EX
140 #endif
141 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
142 
143 #if defined(JSON_HEDLEY_CONCAT)
144     #undef JSON_HEDLEY_CONCAT
145 #endif
146 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
147 
148 #if defined(JSON_HEDLEY_CONCAT3_EX)
149     #undef JSON_HEDLEY_CONCAT3_EX
150 #endif
151 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
152 
153 #if defined(JSON_HEDLEY_CONCAT3)
154     #undef JSON_HEDLEY_CONCAT3
155 #endif
156 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
157 
158 #if defined(JSON_HEDLEY_VERSION_ENCODE)
159     #undef JSON_HEDLEY_VERSION_ENCODE
160 #endif
161 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
162 
163 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
164     #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
165 #endif
166 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
167 
168 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
169     #undef JSON_HEDLEY_VERSION_DECODE_MINOR
170 #endif
171 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
172 
173 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
174     #undef JSON_HEDLEY_VERSION_DECODE_REVISION
175 #endif
176 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
177 
178 #if defined(JSON_HEDLEY_GNUC_VERSION)
179     #undef JSON_HEDLEY_GNUC_VERSION
180 #endif
181 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
182     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
183 #elif defined(__GNUC__)
184     #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
185 #endif
186 
187 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
188     #undef JSON_HEDLEY_GNUC_VERSION_CHECK
189 #endif
190 #if defined(JSON_HEDLEY_GNUC_VERSION)
191     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
192 #else
193     #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
194 #endif
195 
196 #if defined(JSON_HEDLEY_MSVC_VERSION)
197     #undef JSON_HEDLEY_MSVC_VERSION
198 #endif
199 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
200     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
201 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
202     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
203 #elif defined(_MSC_VER) && !defined(__ICL)
204     #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
205 #endif
206 
207 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
208     #undef JSON_HEDLEY_MSVC_VERSION_CHECK
209 #endif
210 #if !defined(JSON_HEDLEY_MSVC_VERSION)
211     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
212 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
213     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
214 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
215     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
216 #else
217     #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
218 #endif
219 
220 #if defined(JSON_HEDLEY_INTEL_VERSION)
221     #undef JSON_HEDLEY_INTEL_VERSION
222 #endif
223 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
224     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
225 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
226     #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
227 #endif
228 
229 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
230     #undef JSON_HEDLEY_INTEL_VERSION_CHECK
231 #endif
232 #if defined(JSON_HEDLEY_INTEL_VERSION)
233     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
234 #else
235     #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
236 #endif
237 
238 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
239     #undef JSON_HEDLEY_INTEL_CL_VERSION
240 #endif
241 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
242     #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
243 #endif
244 
245 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
246     #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
247 #endif
248 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
249     #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
250 #else
251     #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
252 #endif
253 
254 #if defined(JSON_HEDLEY_PGI_VERSION)
255     #undef JSON_HEDLEY_PGI_VERSION
256 #endif
257 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
258     #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
259 #endif
260 
261 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
262     #undef JSON_HEDLEY_PGI_VERSION_CHECK
263 #endif
264 #if defined(JSON_HEDLEY_PGI_VERSION)
265     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
266 #else
267     #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
268 #endif
269 
270 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
271     #undef JSON_HEDLEY_SUNPRO_VERSION
272 #endif
273 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
274     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
275 #elif defined(__SUNPRO_C)
276     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
277 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
278     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
279 #elif defined(__SUNPRO_CC)
280     #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
281 #endif
282 
283 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
284     #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
285 #endif
286 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
287     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
288 #else
289     #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
290 #endif
291 
292 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
293     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
294 #endif
295 #if defined(__EMSCRIPTEN__)
296     #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
297 #endif
298 
299 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
300     #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
301 #endif
302 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
303     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
304 #else
305     #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
306 #endif
307 
308 #if defined(JSON_HEDLEY_ARM_VERSION)
309     #undef JSON_HEDLEY_ARM_VERSION
310 #endif
311 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
312     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
313 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
314     #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
315 #endif
316 
317 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
318     #undef JSON_HEDLEY_ARM_VERSION_CHECK
319 #endif
320 #if defined(JSON_HEDLEY_ARM_VERSION)
321     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
322 #else
323     #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
324 #endif
325 
326 #if defined(JSON_HEDLEY_IBM_VERSION)
327     #undef JSON_HEDLEY_IBM_VERSION
328 #endif
329 #if defined(__ibmxl__)
330     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
331 #elif defined(__xlC__) && defined(__xlC_ver__)
332     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
333 #elif defined(__xlC__)
334     #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
335 #endif
336 
337 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
338     #undef JSON_HEDLEY_IBM_VERSION_CHECK
339 #endif
340 #if defined(JSON_HEDLEY_IBM_VERSION)
341     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
342 #else
343     #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
344 #endif
345 
346 #if defined(JSON_HEDLEY_TI_VERSION)
347     #undef JSON_HEDLEY_TI_VERSION
348 #endif
349 #if \
350     defined(__TI_COMPILER_VERSION__) && \
351     ( \
352       defined(__TMS470__) || defined(__TI_ARM__) || \
353       defined(__MSP430__) || \
354       defined(__TMS320C2000__) \
355     )
356 #if (__TI_COMPILER_VERSION__ >= 16000000)
357     #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
358 #endif
359 #endif
360 
361 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
362     #undef JSON_HEDLEY_TI_VERSION_CHECK
363 #endif
364 #if defined(JSON_HEDLEY_TI_VERSION)
365     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
366 #else
367     #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
368 #endif
369 
370 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
371     #undef JSON_HEDLEY_TI_CL2000_VERSION
372 #endif
373 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
374     #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
375 #endif
376 
377 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
378     #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
379 #endif
380 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
381     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
382 #else
383     #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
384 #endif
385 
386 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
387     #undef JSON_HEDLEY_TI_CL430_VERSION
388 #endif
389 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
390     #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
391 #endif
392 
393 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
394     #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
395 #endif
396 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
397     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
398 #else
399     #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
400 #endif
401 
402 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
403     #undef JSON_HEDLEY_TI_ARMCL_VERSION
404 #endif
405 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
406     #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
407 #endif
408 
409 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
410     #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
411 #endif
412 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
413     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
414 #else
415     #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
416 #endif
417 
418 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
419     #undef JSON_HEDLEY_TI_CL6X_VERSION
420 #endif
421 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
422     #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
423 #endif
424 
425 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
426     #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
427 #endif
428 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
429     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430 #else
431     #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
432 #endif
433 
434 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
435     #undef JSON_HEDLEY_TI_CL7X_VERSION
436 #endif
437 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
438     #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439 #endif
440 
441 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
442     #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
443 #endif
444 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
445     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446 #else
447     #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
448 #endif
449 
450 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
451     #undef JSON_HEDLEY_TI_CLPRU_VERSION
452 #endif
453 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
454     #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455 #endif
456 
457 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
458     #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
459 #endif
460 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
461     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462 #else
463     #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
464 #endif
465 
466 #if defined(JSON_HEDLEY_CRAY_VERSION)
467     #undef JSON_HEDLEY_CRAY_VERSION
468 #endif
469 #if defined(_CRAYC)
470     #if defined(_RELEASE_PATCHLEVEL)
471         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
472     #else
473         #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
474     #endif
475 #endif
476 
477 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
478     #undef JSON_HEDLEY_CRAY_VERSION_CHECK
479 #endif
480 #if defined(JSON_HEDLEY_CRAY_VERSION)
481     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
482 #else
483     #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
484 #endif
485 
486 #if defined(JSON_HEDLEY_IAR_VERSION)
487     #undef JSON_HEDLEY_IAR_VERSION
488 #endif
489 #if defined(__IAR_SYSTEMS_ICC__)
490     #if __VER__ > 1000
491         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
492     #else
493         #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0)
494     #endif
495 #endif
496 
497 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
498     #undef JSON_HEDLEY_IAR_VERSION_CHECK
499 #endif
500 #if defined(JSON_HEDLEY_IAR_VERSION)
501     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
502 #else
503     #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
504 #endif
505 
506 #if defined(JSON_HEDLEY_TINYC_VERSION)
507     #undef JSON_HEDLEY_TINYC_VERSION
508 #endif
509 #if defined(__TINYC__)
510     #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
511 #endif
512 
513 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
514     #undef JSON_HEDLEY_TINYC_VERSION_CHECK
515 #endif
516 #if defined(JSON_HEDLEY_TINYC_VERSION)
517     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
518 #else
519     #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
520 #endif
521 
522 #if defined(JSON_HEDLEY_DMC_VERSION)
523     #undef JSON_HEDLEY_DMC_VERSION
524 #endif
525 #if defined(__DMC__)
526     #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
527 #endif
528 
529 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
530     #undef JSON_HEDLEY_DMC_VERSION_CHECK
531 #endif
532 #if defined(JSON_HEDLEY_DMC_VERSION)
533     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
534 #else
535     #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
536 #endif
537 
538 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
539     #undef JSON_HEDLEY_COMPCERT_VERSION
540 #endif
541 #if defined(__COMPCERT_VERSION__)
542     #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
543 #endif
544 
545 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
546     #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
547 #endif
548 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
549     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
550 #else
551     #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
552 #endif
553 
554 #if defined(JSON_HEDLEY_PELLES_VERSION)
555     #undef JSON_HEDLEY_PELLES_VERSION
556 #endif
557 #if defined(__POCC__)
558     #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
559 #endif
560 
561 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
562     #undef JSON_HEDLEY_PELLES_VERSION_CHECK
563 #endif
564 #if defined(JSON_HEDLEY_PELLES_VERSION)
565     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566 #else
567     #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
568 #endif
569 
570 #if defined(JSON_HEDLEY_GCC_VERSION)
571     #undef JSON_HEDLEY_GCC_VERSION
572 #endif
573 #if \
574     defined(JSON_HEDLEY_GNUC_VERSION) && \
575     !defined(__clang__) && \
576     !defined(JSON_HEDLEY_INTEL_VERSION) && \
577     !defined(JSON_HEDLEY_PGI_VERSION) && \
578     !defined(JSON_HEDLEY_ARM_VERSION) && \
579     !defined(JSON_HEDLEY_TI_VERSION) && \
580     !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
581     !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
582     !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
583     !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
584     !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
585     !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
586     !defined(__COMPCERT__)
587     #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
588 #endif
589 
590 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
591     #undef JSON_HEDLEY_GCC_VERSION_CHECK
592 #endif
593 #if defined(JSON_HEDLEY_GCC_VERSION)
594     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
595 #else
596     #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
597 #endif
598 
599 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
600     #undef JSON_HEDLEY_HAS_ATTRIBUTE
601 #endif
602 #if defined(__has_attribute)
603     #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
604 #else
605     #define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
606 #endif
607 
608 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
609     #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
610 #endif
611 #if defined(__has_attribute)
612     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
613 #else
614     #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
615 #endif
616 
617 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
618     #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
619 #endif
620 #if defined(__has_attribute)
621     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute)
622 #else
623     #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
624 #endif
625 
626 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
627     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
628 #endif
629 #if \
630     defined(__has_cpp_attribute) && \
631     defined(__cplusplus) && \
632     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
633     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
634 #else
635     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
636 #endif
637 
638 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
639     #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
640 #endif
641 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
642     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
643 #elif \
644     !defined(JSON_HEDLEY_PGI_VERSION) && \
645     !defined(JSON_HEDLEY_IAR_VERSION) && \
646     (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
647     (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
648     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
649 #else
650     #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
651 #endif
652 
653 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
654     #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
655 #endif
656 #if defined(__has_cpp_attribute) && defined(__cplusplus)
657     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
658 #else
659     #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
660 #endif
661 
662 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
663     #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
664 #endif
665 #if defined(__has_cpp_attribute) && defined(__cplusplus)
666     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
667 #else
668     #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
669 #endif
670 
671 #if defined(JSON_HEDLEY_HAS_BUILTIN)
672     #undef JSON_HEDLEY_HAS_BUILTIN
673 #endif
674 #if defined(__has_builtin)
675     #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
676 #else
677     #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
678 #endif
679 
680 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
681     #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
682 #endif
683 #if defined(__has_builtin)
684     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
685 #else
686     #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
687 #endif
688 
689 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
690     #undef JSON_HEDLEY_GCC_HAS_BUILTIN
691 #endif
692 #if defined(__has_builtin)
693     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
694 #else
695     #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
696 #endif
697 
698 #if defined(JSON_HEDLEY_HAS_FEATURE)
699     #undef JSON_HEDLEY_HAS_FEATURE
700 #endif
701 #if defined(__has_feature)
702     #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
703 #else
704     #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
705 #endif
706 
707 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
708     #undef JSON_HEDLEY_GNUC_HAS_FEATURE
709 #endif
710 #if defined(__has_feature)
711     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
712 #else
713     #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
714 #endif
715 
716 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
717     #undef JSON_HEDLEY_GCC_HAS_FEATURE
718 #endif
719 #if defined(__has_feature)
720     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
721 #else
722     #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
723 #endif
724 
725 #if defined(JSON_HEDLEY_HAS_EXTENSION)
726     #undef JSON_HEDLEY_HAS_EXTENSION
727 #endif
728 #if defined(__has_extension)
729     #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
730 #else
731     #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
732 #endif
733 
734 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
735     #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
736 #endif
737 #if defined(__has_extension)
738     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
739 #else
740     #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
741 #endif
742 
743 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
744     #undef JSON_HEDLEY_GCC_HAS_EXTENSION
745 #endif
746 #if defined(__has_extension)
747     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
748 #else
749     #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
750 #endif
751 
752 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
753     #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
754 #endif
755 #if defined(__has_declspec_attribute)
756     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
757 #else
758     #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
759 #endif
760 
761 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
762     #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
763 #endif
764 #if defined(__has_declspec_attribute)
765     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
766 #else
767     #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
768 #endif
769 
770 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
771     #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
772 #endif
773 #if defined(__has_declspec_attribute)
774     #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
775 #else
776     #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
777 #endif
778 
779 #if defined(JSON_HEDLEY_HAS_WARNING)
780     #undef JSON_HEDLEY_HAS_WARNING
781 #endif
782 #if defined(__has_warning)
783     #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
784 #else
785     #define JSON_HEDLEY_HAS_WARNING(warning) (0)
786 #endif
787 
788 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
789     #undef JSON_HEDLEY_GNUC_HAS_WARNING
790 #endif
791 #if defined(__has_warning)
792     #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
793 #else
794     #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
795 #endif
796 
797 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
798     #undef JSON_HEDLEY_GCC_HAS_WARNING
799 #endif
800 #if defined(__has_warning)
801     #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
802 #else
803     #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
804 #endif
805 
806 #if \
807     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
808     defined(__clang__) || \
809     JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
810     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
811     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
812     JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
813     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
814     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
815     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
816     JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
817     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
818     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
819     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
820     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
821     JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
822     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
823     JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
824     (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
825     #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
826 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
827     #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
828 #else
829     #define JSON_HEDLEY_PRAGMA(value)
830 #endif
831 
832 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
833     #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
834 #endif
835 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
836     #undef JSON_HEDLEY_DIAGNOSTIC_POP
837 #endif
838 #if defined(__clang__)
839     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
840     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
841 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
842     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
843     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
844 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
845     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
846     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
847 #elif \
848     JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
849     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
850     #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
851     #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
852 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
853     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
854     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
855 #elif \
856     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
857     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
858     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
859     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
860     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
861     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
862     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
863     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
864 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
865     #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
866     #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
867 #else
868     #define JSON_HEDLEY_DIAGNOSTIC_PUSH
869     #define JSON_HEDLEY_DIAGNOSTIC_POP
870 #endif
871 
872 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
873    HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
874 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
875     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
876 #endif
877 #if defined(__cplusplus)
878 #  if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
879 #    if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
880 #      if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
881 #        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
882     JSON_HEDLEY_DIAGNOSTIC_PUSH \
883     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
884     _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
885     _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
886     xpr \
887     JSON_HEDLEY_DIAGNOSTIC_POP
888 #      else
889 #        define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
890     JSON_HEDLEY_DIAGNOSTIC_PUSH \
891     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
892     _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
893     xpr \
894     JSON_HEDLEY_DIAGNOSTIC_POP
895 #      endif
896 #    else
897 #      define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
898     JSON_HEDLEY_DIAGNOSTIC_PUSH \
899     _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
900     xpr \
901     JSON_HEDLEY_DIAGNOSTIC_POP
902 #    endif
903 #  endif
904 #endif
905 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
906     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
907 #endif
908 
909 #if defined(JSON_HEDLEY_CONST_CAST)
910     #undef JSON_HEDLEY_CONST_CAST
911 #endif
912 #if defined(__cplusplus)
913 #  define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
914 #elif \
915   JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
916   JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
917   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
918 #  define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
919         JSON_HEDLEY_DIAGNOSTIC_PUSH \
920         JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
921         ((T) (expr)); \
922         JSON_HEDLEY_DIAGNOSTIC_POP \
923     }))
924 #else
925 #  define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
926 #endif
927 
928 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
929     #undef JSON_HEDLEY_REINTERPRET_CAST
930 #endif
931 #if defined(__cplusplus)
932     #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
933 #else
934     #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
935 #endif
936 
937 #if defined(JSON_HEDLEY_STATIC_CAST)
938     #undef JSON_HEDLEY_STATIC_CAST
939 #endif
940 #if defined(__cplusplus)
941     #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
942 #else
943     #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
944 #endif
945 
946 #if defined(JSON_HEDLEY_CPP_CAST)
947     #undef JSON_HEDLEY_CPP_CAST
948 #endif
949 #if defined(__cplusplus)
950 #  if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
951 #    define JSON_HEDLEY_CPP_CAST(T, expr) \
952     JSON_HEDLEY_DIAGNOSTIC_PUSH \
953     _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
954     ((T) (expr)) \
955     JSON_HEDLEY_DIAGNOSTIC_POP
956 #  elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
957 #    define JSON_HEDLEY_CPP_CAST(T, expr) \
958     JSON_HEDLEY_DIAGNOSTIC_PUSH \
959     _Pragma("diag_suppress=Pe137") \
960     JSON_HEDLEY_DIAGNOSTIC_POP
961 #  else
962 #    define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
963 #  endif
964 #else
965 #  define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
966 #endif
967 
968 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
969     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
970 #endif
971 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
972     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
973 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
974     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
975 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
976     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
977 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
978     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
979 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
980     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
981 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
982     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
983 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
984     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
985 #elif \
986     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
987     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
988     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
989     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
990     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
991     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
992     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
993     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
994     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
995     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
996     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
997     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
998 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
999     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1000 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1001     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1002 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1003     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1004 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1005     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1006 #else
1007     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1008 #endif
1009 
1010 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1011     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1012 #endif
1013 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1014     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1015 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1016     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1017 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1018     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1019 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1020     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1021 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1022     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1023 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1024     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1025 #elif \
1026     JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1027     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1028     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1029     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1030     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1031 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1032     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1033 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1034     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1035 #else
1036     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1037 #endif
1038 
1039 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1040     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1041 #endif
1042 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1043     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1044 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1045     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1046 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1047     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1048 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1049     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1050 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1051     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1052 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1053     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1054 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1055     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1056 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1057     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1058 #elif \
1059     JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1060     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1061     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1062     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1063 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1064     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1065 #else
1066     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1067 #endif
1068 
1069 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1070     #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1071 #endif
1072 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1073     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1074 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1075     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1076 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1077     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1078 #else
1079     #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1080 #endif
1081 
1082 #if defined(JSON_HEDLEY_DEPRECATED)
1083     #undef JSON_HEDLEY_DEPRECATED
1084 #endif
1085 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1086     #undef JSON_HEDLEY_DEPRECATED_FOR
1087 #endif
1088 #if \
1089     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1090     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1091     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1092     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1093 #elif \
1094     JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \
1095     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1096     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1097     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1098     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1099     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1100     JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1101     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1102     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1103     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1104     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1105     #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1106     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1107 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1108     #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1109     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1110 #elif \
1111     JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1112     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1113     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1114     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1115     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1116     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1117     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1118     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1119     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1120     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1121     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1122     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1123     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1124     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1125     #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1126     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1127 #elif \
1128     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1129     JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1130     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1131     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1132     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1133 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1134     #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1135     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1136 #else
1137     #define JSON_HEDLEY_DEPRECATED(since)
1138     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1139 #endif
1140 
1141 #if defined(JSON_HEDLEY_UNAVAILABLE)
1142     #undef JSON_HEDLEY_UNAVAILABLE
1143 #endif
1144 #if \
1145     JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1146     JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1147     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1148     #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1149 #else
1150     #define JSON_HEDLEY_UNAVAILABLE(available_since)
1151 #endif
1152 
1153 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1154     #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1155 #endif
1156 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1157     #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1158 #endif
1159 #if \
1160     JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1161     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1162     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1163     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1164     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1165     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1166     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1167     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1168     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1169     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1170     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1171     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1172     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1173     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1174     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1175     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1176     #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1177     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1178 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1179     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1180     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1181 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1182     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1183     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1184 #elif defined(_Check_return_) /* SAL */
1185     #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1186     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1187 #else
1188     #define JSON_HEDLEY_WARN_UNUSED_RESULT
1189     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1190 #endif
1191 
1192 #if defined(JSON_HEDLEY_SENTINEL)
1193     #undef JSON_HEDLEY_SENTINEL
1194 #endif
1195 #if \
1196     JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1197     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1198     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1199     JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0)
1200     #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1201 #else
1202     #define JSON_HEDLEY_SENTINEL(position)
1203 #endif
1204 
1205 #if defined(JSON_HEDLEY_NO_RETURN)
1206     #undef JSON_HEDLEY_NO_RETURN
1207 #endif
1208 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1209     #define JSON_HEDLEY_NO_RETURN __noreturn
1210 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1211     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1212 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1213     #define JSON_HEDLEY_NO_RETURN _Noreturn
1214 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1215     #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1216 #elif \
1217     JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1218     JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1219     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1220     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1221     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1222     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1233     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1234 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1235     #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1236 #elif \
1237     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1239     #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1240 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1241     #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1242 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1243     #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1244 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1245     #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1246 #else
1247     #define JSON_HEDLEY_NO_RETURN
1248 #endif
1249 
1250 #if defined(JSON_HEDLEY_NO_ESCAPE)
1251     #undef JSON_HEDLEY_NO_ESCAPE
1252 #endif
1253 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1254     #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1255 #else
1256     #define JSON_HEDLEY_NO_ESCAPE
1257 #endif
1258 
1259 #if defined(JSON_HEDLEY_UNREACHABLE)
1260     #undef JSON_HEDLEY_UNREACHABLE
1261 #endif
1262 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1263     #undef JSON_HEDLEY_UNREACHABLE_RETURN
1264 #endif
1265 #if defined(JSON_HEDLEY_ASSUME)
1266     #undef JSON_HEDLEY_ASSUME
1267 #endif
1268 #if \
1269     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1270     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1271     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1272     #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1273 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1274     #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1275 #elif \
1276     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1277     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1278     #if defined(__cplusplus)
1279         #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1280     #else
1281         #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1282     #endif
1283 #endif
1284 #if \
1285     (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1286     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1287     JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1288     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1289     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5)
1290     #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1291 #elif defined(JSON_HEDLEY_ASSUME)
1292     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1293 #endif
1294 #if !defined(JSON_HEDLEY_ASSUME)
1295     #if defined(JSON_HEDLEY_UNREACHABLE)
1296         #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1297     #else
1298         #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1299     #endif
1300 #endif
1301 #if defined(JSON_HEDLEY_UNREACHABLE)
1302     #if  \
1303         JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1304         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1305         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1306     #else
1307         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1308     #endif
1309 #else
1310     #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1311 #endif
1312 #if !defined(JSON_HEDLEY_UNREACHABLE)
1313     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1314 #endif
1315 
1316 JSON_HEDLEY_DIAGNOSTIC_PUSH
1317 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1318     #pragma clang diagnostic ignored "-Wpedantic"
1319 #endif
1320 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1321     #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1322 #endif
1323 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1324     #if defined(__clang__)
1325         #pragma clang diagnostic ignored "-Wvariadic-macros"
1326     #elif defined(JSON_HEDLEY_GCC_VERSION)
1327         #pragma GCC diagnostic ignored "-Wvariadic-macros"
1328     #endif
1329 #endif
1330 #if defined(JSON_HEDLEY_NON_NULL)
1331     #undef JSON_HEDLEY_NON_NULL
1332 #endif
1333 #if \
1334     JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1335     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1336     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1337     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1338     #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1339 #else
1340     #define JSON_HEDLEY_NON_NULL(...)
1341 #endif
1342 JSON_HEDLEY_DIAGNOSTIC_POP
1343 
1344 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1345     #undef JSON_HEDLEY_PRINTF_FORMAT
1346 #endif
1347 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1348     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1349 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1350     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1351 #elif \
1352     JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1353     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1354     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1355     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1356     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1357     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1358     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1359     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1360     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1361     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1362     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1363     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1364     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1365     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1366     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1367     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1368     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1369 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1370     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1371 #else
1372     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1373 #endif
1374 
1375 #if defined(JSON_HEDLEY_CONSTEXPR)
1376     #undef JSON_HEDLEY_CONSTEXPR
1377 #endif
1378 #if defined(__cplusplus)
1379     #if __cplusplus >= 201103L
1380         #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1381     #endif
1382 #endif
1383 #if !defined(JSON_HEDLEY_CONSTEXPR)
1384     #define JSON_HEDLEY_CONSTEXPR
1385 #endif
1386 
1387 #if defined(JSON_HEDLEY_PREDICT)
1388     #undef JSON_HEDLEY_PREDICT
1389 #endif
1390 #if defined(JSON_HEDLEY_LIKELY)
1391     #undef JSON_HEDLEY_LIKELY
1392 #endif
1393 #if defined(JSON_HEDLEY_UNLIKELY)
1394     #undef JSON_HEDLEY_UNLIKELY
1395 #endif
1396 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1397     #undef JSON_HEDLEY_UNPREDICTABLE
1398 #endif
1399 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1400     #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1401 #endif
1402 #if \
1403   (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1404   JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0)
1405 #  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
1406 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
1407 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
1408 #  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
1409 #  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
1410 #elif \
1411   (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1412   JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1413   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414   (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1415   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1416   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1417   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1418   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1419   JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1420   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1421   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1422   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1423   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1424   JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1425   JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1426 #  define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1427     (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1428 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1429     (__extension__ ({ \
1430         double hedley_probability_ = (probability); \
1431         ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1432     }))
1433 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1434     (__extension__ ({ \
1435         double hedley_probability_ = (probability); \
1436         ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1437     }))
1438 #  define JSON_HEDLEY_LIKELY(expr)   __builtin_expect(!!(expr), 1)
1439 #  define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1440 #else
1441 #  define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1442 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1443 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1444 #  define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1445 #  define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1446 #endif
1447 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1448     #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1449 #endif
1450 
1451 #if defined(JSON_HEDLEY_MALLOC)
1452     #undef JSON_HEDLEY_MALLOC
1453 #endif
1454 #if \
1455     JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1456     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1457     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1458     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1459     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1460     JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1461     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1462     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1463     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1464     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1465     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1466     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1467     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1468     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1469     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1470     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1471     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1472     #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1473 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1474     #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1475 #elif \
1476     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1477     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1478     #define JSON_HEDLEY_MALLOC __declspec(restrict)
1479 #else
1480     #define JSON_HEDLEY_MALLOC
1481 #endif
1482 
1483 #if defined(JSON_HEDLEY_PURE)
1484     #undef JSON_HEDLEY_PURE
1485 #endif
1486 #if \
1487   JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1488   JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1489   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1490   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1491   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1492   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1493   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1494   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1495   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1496   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1497   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1498   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1499   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1500   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1501   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1502   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1503   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1504   JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1505 #  define JSON_HEDLEY_PURE __attribute__((__pure__))
1506 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1507 #  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1508 #elif defined(__cplusplus) && \
1509     ( \
1510       JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1511       JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1512       JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1513     )
1514 #  define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1515 #else
1516 #  define JSON_HEDLEY_PURE
1517 #endif
1518 
1519 #if defined(JSON_HEDLEY_CONST)
1520     #undef JSON_HEDLEY_CONST
1521 #endif
1522 #if \
1523     JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1524     JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1525     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1526     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1527     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1528     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1529     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1530     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1531     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1532     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1533     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1534     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1535     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1536     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1537     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1538     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1539     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1540     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1541     #define JSON_HEDLEY_CONST __attribute__((__const__))
1542 #elif \
1543     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1544     #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1545 #else
1546     #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1547 #endif
1548 
1549 #if defined(JSON_HEDLEY_RESTRICT)
1550     #undef JSON_HEDLEY_RESTRICT
1551 #endif
1552 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1553     #define JSON_HEDLEY_RESTRICT restrict
1554 #elif \
1555     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1556     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1557     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1558     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1559     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1560     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1561     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1562     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1563     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1564     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1565     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1566     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1567     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1568     defined(__clang__)
1569     #define JSON_HEDLEY_RESTRICT __restrict
1570 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1571     #define JSON_HEDLEY_RESTRICT _Restrict
1572 #else
1573     #define JSON_HEDLEY_RESTRICT
1574 #endif
1575 
1576 #if defined(JSON_HEDLEY_INLINE)
1577     #undef JSON_HEDLEY_INLINE
1578 #endif
1579 #if \
1580     (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1581     (defined(__cplusplus) && (__cplusplus >= 199711L))
1582     #define JSON_HEDLEY_INLINE inline
1583 #elif \
1584     defined(JSON_HEDLEY_GCC_VERSION) || \
1585     JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1586     #define JSON_HEDLEY_INLINE __inline__
1587 #elif \
1588     JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1589     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1590     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1591     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1592     JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1593     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1594     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1595     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1596     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1597     #define JSON_HEDLEY_INLINE __inline
1598 #else
1599     #define JSON_HEDLEY_INLINE
1600 #endif
1601 
1602 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1603     #undef JSON_HEDLEY_ALWAYS_INLINE
1604 #endif
1605 #if \
1606   JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1607   JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1608   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1609   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1610   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1611   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1612   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1613   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1614   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1615   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1616   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1617   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1618   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1619   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1620   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1621   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1622   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1623 #  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1624 #elif \
1625   JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1626   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1627 #  define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1628 #elif defined(__cplusplus) && \
1629     ( \
1630       JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1631       JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1632       JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1633       JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1634       JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1635       JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1636     )
1637 #  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1638 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1639 #  define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1640 #else
1641 #  define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1642 #endif
1643 
1644 #if defined(JSON_HEDLEY_NEVER_INLINE)
1645     #undef JSON_HEDLEY_NEVER_INLINE
1646 #endif
1647 #if \
1648     JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1649     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1650     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1651     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1652     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1653     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1654     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1655     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1657     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1659     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1661     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1662     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1663     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1664     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1665     #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1666 #elif \
1667     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1668     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1669     #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1670 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1671     #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1672 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1673     #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1674 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1675     #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1676 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1677     #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1678 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1679     #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1680 #else
1681     #define JSON_HEDLEY_NEVER_INLINE
1682 #endif
1683 
1684 #if defined(JSON_HEDLEY_PRIVATE)
1685     #undef JSON_HEDLEY_PRIVATE
1686 #endif
1687 #if defined(JSON_HEDLEY_PUBLIC)
1688     #undef JSON_HEDLEY_PUBLIC
1689 #endif
1690 #if defined(JSON_HEDLEY_IMPORT)
1691     #undef JSON_HEDLEY_IMPORT
1692 #endif
1693 #if defined(_WIN32) || defined(__CYGWIN__)
1694 #  define JSON_HEDLEY_PRIVATE
1695 #  define JSON_HEDLEY_PUBLIC   __declspec(dllexport)
1696 #  define JSON_HEDLEY_IMPORT   __declspec(dllimport)
1697 #else
1698 #  if \
1699     JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1700     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1701     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1702     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1703     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1704     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1705     ( \
1706       defined(__TI_EABI__) && \
1707       ( \
1708         (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1709         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1710       ) \
1711     )
1712 #    define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1713 #    define JSON_HEDLEY_PUBLIC  __attribute__((__visibility__("default")))
1714 #  else
1715 #    define JSON_HEDLEY_PRIVATE
1716 #    define JSON_HEDLEY_PUBLIC
1717 #  endif
1718 #  define JSON_HEDLEY_IMPORT    extern
1719 #endif
1720 
1721 #if defined(JSON_HEDLEY_NO_THROW)
1722     #undef JSON_HEDLEY_NO_THROW
1723 #endif
1724 #if \
1725     JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1726     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1727     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1728     #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1729 #elif \
1730     JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1731     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1732     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1733     #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1734 #else
1735     #define JSON_HEDLEY_NO_THROW
1736 #endif
1737 
1738 #if defined(JSON_HEDLEY_FALL_THROUGH)
1739     #undef JSON_HEDLEY_FALL_THROUGH
1740 #endif
1741 #if \
1742     JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1743     JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0)
1744     #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1745 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1746     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1747 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1748     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1749 #elif defined(__fallthrough) /* SAL */
1750     #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1751 #else
1752     #define JSON_HEDLEY_FALL_THROUGH
1753 #endif
1754 
1755 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1756     #undef JSON_HEDLEY_RETURNS_NON_NULL
1757 #endif
1758 #if \
1759     JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1760     JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0)
1761     #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1762 #elif defined(_Ret_notnull_) /* SAL */
1763     #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1764 #else
1765     #define JSON_HEDLEY_RETURNS_NON_NULL
1766 #endif
1767 
1768 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1769     #undef JSON_HEDLEY_ARRAY_PARAM
1770 #endif
1771 #if \
1772     defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1773     !defined(__STDC_NO_VLA__) && \
1774     !defined(__cplusplus) && \
1775     !defined(JSON_HEDLEY_PGI_VERSION) && \
1776     !defined(JSON_HEDLEY_TINYC_VERSION)
1777     #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1778 #else
1779     #define JSON_HEDLEY_ARRAY_PARAM(name)
1780 #endif
1781 
1782 #if defined(JSON_HEDLEY_IS_CONSTANT)
1783     #undef JSON_HEDLEY_IS_CONSTANT
1784 #endif
1785 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1786     #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1787 #endif
1788 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1789    HEDLEY INTERNAL USE ONLY.  API subject to change without notice. */
1790 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1791     #undef JSON_HEDLEY_IS_CONSTEXPR_
1792 #endif
1793 #if \
1794     JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1795     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1796     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1797     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1798     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1799     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1800     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1801     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1802     JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0)
1803     #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1804 #endif
1805 #if !defined(__cplusplus)
1806 #  if \
1807        JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1808        JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1809        JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1810        JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1811        JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1812        JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1813        JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1814 #if defined(__INTPTR_TYPE__)
1815     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1816 #else
1817     #include <stdint.h>
1818     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1819 #endif
1820 #  elif \
1821        ( \
1822           defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1823           !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1824           !defined(JSON_HEDLEY_PGI_VERSION) && \
1825           !defined(JSON_HEDLEY_IAR_VERSION)) || \
1826        JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) || \
1827        JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1828        JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1829        JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1830        JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1831 #if defined(__INTPTR_TYPE__)
1832     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1833 #else
1834     #include <stdint.h>
1835     #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1836 #endif
1837 #  elif \
1838        defined(JSON_HEDLEY_GCC_VERSION) || \
1839        defined(JSON_HEDLEY_INTEL_VERSION) || \
1840        defined(JSON_HEDLEY_TINYC_VERSION) || \
1841        defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1842        JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1843        defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1844        defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1845        defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1846        defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1847        defined(__clang__)
1848 #    define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1849         sizeof(void) != \
1850         sizeof(*( \
1851                   1 ? \
1852                   ((void*) ((expr) * 0L) ) : \
1853 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1854                 ) \
1855               ) \
1856                                             )
1857 #  endif
1858 #endif
1859 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1860     #if !defined(JSON_HEDLEY_IS_CONSTANT)
1861         #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1862     #endif
1863     #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1864 #else
1865     #if !defined(JSON_HEDLEY_IS_CONSTANT)
1866         #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1867     #endif
1868     #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1869 #endif
1870 
1871 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1872     #undef JSON_HEDLEY_BEGIN_C_DECLS
1873 #endif
1874 #if defined(JSON_HEDLEY_END_C_DECLS)
1875     #undef JSON_HEDLEY_END_C_DECLS
1876 #endif
1877 #if defined(JSON_HEDLEY_C_DECL)
1878     #undef JSON_HEDLEY_C_DECL
1879 #endif
1880 #if defined(__cplusplus)
1881     #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1882     #define JSON_HEDLEY_END_C_DECLS }
1883     #define JSON_HEDLEY_C_DECL extern "C"
1884 #else
1885     #define JSON_HEDLEY_BEGIN_C_DECLS
1886     #define JSON_HEDLEY_END_C_DECLS
1887     #define JSON_HEDLEY_C_DECL
1888 #endif
1889 
1890 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1891     #undef JSON_HEDLEY_STATIC_ASSERT
1892 #endif
1893 #if \
1894   !defined(__cplusplus) && ( \
1895       (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1896       (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1897       JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1898       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1899       defined(_Static_assert) \
1900     )
1901 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1902 #elif \
1903   (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1904   JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1905   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1906 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1907 #else
1908 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1909 #endif
1910 
1911 #if defined(JSON_HEDLEY_NULL)
1912     #undef JSON_HEDLEY_NULL
1913 #endif
1914 #if defined(__cplusplus)
1915     #if __cplusplus >= 201103L
1916         #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1917     #elif defined(NULL)
1918         #define JSON_HEDLEY_NULL NULL
1919     #else
1920         #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1921     #endif
1922 #elif defined(NULL)
1923     #define JSON_HEDLEY_NULL NULL
1924 #else
1925     #define JSON_HEDLEY_NULL ((void*) 0)
1926 #endif
1927 
1928 #if defined(JSON_HEDLEY_MESSAGE)
1929     #undef JSON_HEDLEY_MESSAGE
1930 #endif
1931 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1932 #  define JSON_HEDLEY_MESSAGE(msg) \
1933     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1934     JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1935     JSON_HEDLEY_PRAGMA(message msg) \
1936     JSON_HEDLEY_DIAGNOSTIC_POP
1937 #elif \
1938   JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
1939   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1940 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
1941 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
1942 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
1943 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1944 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1945 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
1946 #  define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
1947 #else
1948 #  define JSON_HEDLEY_MESSAGE(msg)
1949 #endif
1950 
1951 #if defined(JSON_HEDLEY_WARNING)
1952     #undef JSON_HEDLEY_WARNING
1953 #endif
1954 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1955 #  define JSON_HEDLEY_WARNING(msg) \
1956     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1957     JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
1958     JSON_HEDLEY_PRAGMA(clang warning msg) \
1959     JSON_HEDLEY_DIAGNOSTIC_POP
1960 #elif \
1961   JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
1962   JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
1963   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1964 #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
1965 #elif \
1966   JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
1967   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1968 #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
1969 #else
1970 #  define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
1971 #endif
1972 
1973 #if defined(JSON_HEDLEY_REQUIRE)
1974     #undef JSON_HEDLEY_REQUIRE
1975 #endif
1976 #if defined(JSON_HEDLEY_REQUIRE_MSG)
1977     #undef JSON_HEDLEY_REQUIRE_MSG
1978 #endif
1979 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
1980 #  if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
1981 #    define JSON_HEDLEY_REQUIRE(expr) \
1982     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1983     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1984     __attribute__((diagnose_if(!(expr), #expr, "error"))) \
1985     JSON_HEDLEY_DIAGNOSTIC_POP
1986 #    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
1987     JSON_HEDLEY_DIAGNOSTIC_PUSH \
1988     _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
1989     __attribute__((diagnose_if(!(expr), msg, "error"))) \
1990     JSON_HEDLEY_DIAGNOSTIC_POP
1991 #  else
1992 #    define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
1993 #    define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
1994 #  endif
1995 #else
1996 #  define JSON_HEDLEY_REQUIRE(expr)
1997 #  define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
1998 #endif
1999 
2000 #if defined(JSON_HEDLEY_FLAGS)
2001     #undef JSON_HEDLEY_FLAGS
2002 #endif
2003 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum)
2004     #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2005 #else
2006     #define JSON_HEDLEY_FLAGS
2007 #endif
2008 
2009 #if defined(JSON_HEDLEY_FLAGS_CAST)
2010     #undef JSON_HEDLEY_FLAGS_CAST
2011 #endif
2012 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2013 #  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2014         JSON_HEDLEY_DIAGNOSTIC_PUSH \
2015         _Pragma("warning(disable:188)") \
2016         ((T) (expr)); \
2017         JSON_HEDLEY_DIAGNOSTIC_POP \
2018     }))
2019 #else
2020 #  define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2021 #endif
2022 
2023 #if defined(JSON_HEDLEY_EMPTY_BASES)
2024     #undef JSON_HEDLEY_EMPTY_BASES
2025 #endif
2026 #if \
2027     (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2028     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2029     #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2030 #else
2031     #define JSON_HEDLEY_EMPTY_BASES
2032 #endif
2033 
2034 /* Remaining macros are deprecated. */
2035 
2036 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2037     #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2038 #endif
2039 #if defined(__clang__)
2040     #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2041 #else
2042     #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2043 #endif
2044 
2045 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2046     #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2047 #endif
2048 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2049 
2050 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2051     #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2052 #endif
2053 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2054 
2055 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2056     #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2057 #endif
2058 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2059 
2060 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2061     #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2062 #endif
2063 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2064 
2065 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2066     #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2067 #endif
2068 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2069 
2070 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2071     #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2072 #endif
2073 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2074 
2075 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2076     #undef JSON_HEDLEY_CLANG_HAS_WARNING
2077 #endif
2078 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2079 
2080 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2081 
2082 
2083 // This file contains all internal macro definitions
2084 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2085 
2086 // exclude unsupported compilers
2087 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2088     #if defined(__clang__)
2089         #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2090             #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2091         #endif
2092     #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2093         #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2094             #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2095         #endif
2096     #endif
2097 #endif
2098 
2099 // C++ language standard detection
2100 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2101     #define JSON_HAS_CPP_20
2102     #define JSON_HAS_CPP_17
2103     #define JSON_HAS_CPP_14
2104 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2105     #define JSON_HAS_CPP_17
2106     #define JSON_HAS_CPP_14
2107 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2108     #define JSON_HAS_CPP_14
2109 #endif
2110 
2111 // disable float-equal warnings on GCC/clang
2112 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2113     #pragma GCC diagnostic push
2114     #pragma GCC diagnostic ignored "-Wfloat-equal"
2115 #endif
2116 
2117 // disable documentation warnings on clang
2118 #if defined(__clang__)
2119     #pragma GCC diagnostic push
2120     #pragma GCC diagnostic ignored "-Wdocumentation"
2121 #endif
2122 
2123 // allow to disable exceptions
2124 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2125     #define JSON_THROW(exception) throw exception
2126     #define JSON_TRY try
2127     #define JSON_CATCH(exception) catch(exception)
2128     #define JSON_INTERNAL_CATCH(exception) catch(exception)
2129 #else
2130     #include <cstdlib>
2131     #define JSON_THROW(exception) std::abort()
2132     #define JSON_TRY if(true)
2133     #define JSON_CATCH(exception) if(false)
2134     #define JSON_INTERNAL_CATCH(exception) if(false)
2135 #endif
2136 
2137 // override exception macros
2138 #if defined(JSON_THROW_USER)
2139     #undef JSON_THROW
2140     #define JSON_THROW JSON_THROW_USER
2141 #endif
2142 #if defined(JSON_TRY_USER)
2143     #undef JSON_TRY
2144     #define JSON_TRY JSON_TRY_USER
2145 #endif
2146 #if defined(JSON_CATCH_USER)
2147     #undef JSON_CATCH
2148     #define JSON_CATCH JSON_CATCH_USER
2149     #undef JSON_INTERNAL_CATCH
2150     #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2151 #endif
2152 #if defined(JSON_INTERNAL_CATCH_USER)
2153     #undef JSON_INTERNAL_CATCH
2154     #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2155 #endif
2156 
2157 // allow to override assert
2158 #if !defined(JSON_ASSERT)
2159     #include <cassert> // assert
2160     #define JSON_ASSERT(x) assert(x)
2161 #endif
2162 
2163 // allow to access some private functions (needed by the test suite)
2164 #if defined(JSON_TESTS_PRIVATE)
2165     #define JSON_PRIVATE_UNLESS_TESTED public
2166 #else
2167     #define JSON_PRIVATE_UNLESS_TESTED private
2168 #endif
2169 
2170 /*!
2171 @brief macro to briefly define a mapping between an enum and JSON
2172 @def NLOHMANN_JSON_SERIALIZE_ENUM
2173 @since version 3.4.0
2174 */
2175 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
2176     template<typename BasicJsonType>                                                            \
2177     inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
2178     {                                                                                           \
2179         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2180         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2181         auto it = std::find_if(std::begin(m), std::end(m),                                      \
2182                                [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
2183         {                                                                                       \
2184             return ej_pair.first == e;                                                          \
2185         });                                                                                     \
2186         j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
2187     }                                                                                           \
2188     template<typename BasicJsonType>                                                            \
2189     inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
2190     {                                                                                           \
2191         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2192         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2193         auto it = std::find_if(std::begin(m), std::end(m),                                      \
2194                                [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2195         {                                                                                       \
2196             return ej_pair.second == j;                                                         \
2197         });                                                                                     \
2198         e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
2199     }
2200 
2201 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2202 // may be removed in the future once the class is split.
2203 
2204 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
2205     template<template<typename, typename, typename...> class ObjectType,   \
2206              template<typename, typename...> class ArrayType,              \
2207              class StringType, class BooleanType, class NumberIntegerType, \
2208              class NumberUnsignedType, class NumberFloatType,              \
2209              template<typename> class AllocatorType,                       \
2210              template<typename, typename = void> class JSONSerializer,     \
2211              class BinaryType>
2212 
2213 #define NLOHMANN_BASIC_JSON_TPL                                            \
2214     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
2215     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
2216     AllocatorType, JSONSerializer, BinaryType>
2217 
2218 // Macros to simplify conversion from/to types
2219 
2220 #define NLOHMANN_JSON_EXPAND( x ) x
2221 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2222 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2223         NLOHMANN_JSON_PASTE64, \
2224         NLOHMANN_JSON_PASTE63, \
2225         NLOHMANN_JSON_PASTE62, \
2226         NLOHMANN_JSON_PASTE61, \
2227         NLOHMANN_JSON_PASTE60, \
2228         NLOHMANN_JSON_PASTE59, \
2229         NLOHMANN_JSON_PASTE58, \
2230         NLOHMANN_JSON_PASTE57, \
2231         NLOHMANN_JSON_PASTE56, \
2232         NLOHMANN_JSON_PASTE55, \
2233         NLOHMANN_JSON_PASTE54, \
2234         NLOHMANN_JSON_PASTE53, \
2235         NLOHMANN_JSON_PASTE52, \
2236         NLOHMANN_JSON_PASTE51, \
2237         NLOHMANN_JSON_PASTE50, \
2238         NLOHMANN_JSON_PASTE49, \
2239         NLOHMANN_JSON_PASTE48, \
2240         NLOHMANN_JSON_PASTE47, \
2241         NLOHMANN_JSON_PASTE46, \
2242         NLOHMANN_JSON_PASTE45, \
2243         NLOHMANN_JSON_PASTE44, \
2244         NLOHMANN_JSON_PASTE43, \
2245         NLOHMANN_JSON_PASTE42, \
2246         NLOHMANN_JSON_PASTE41, \
2247         NLOHMANN_JSON_PASTE40, \
2248         NLOHMANN_JSON_PASTE39, \
2249         NLOHMANN_JSON_PASTE38, \
2250         NLOHMANN_JSON_PASTE37, \
2251         NLOHMANN_JSON_PASTE36, \
2252         NLOHMANN_JSON_PASTE35, \
2253         NLOHMANN_JSON_PASTE34, \
2254         NLOHMANN_JSON_PASTE33, \
2255         NLOHMANN_JSON_PASTE32, \
2256         NLOHMANN_JSON_PASTE31, \
2257         NLOHMANN_JSON_PASTE30, \
2258         NLOHMANN_JSON_PASTE29, \
2259         NLOHMANN_JSON_PASTE28, \
2260         NLOHMANN_JSON_PASTE27, \
2261         NLOHMANN_JSON_PASTE26, \
2262         NLOHMANN_JSON_PASTE25, \
2263         NLOHMANN_JSON_PASTE24, \
2264         NLOHMANN_JSON_PASTE23, \
2265         NLOHMANN_JSON_PASTE22, \
2266         NLOHMANN_JSON_PASTE21, \
2267         NLOHMANN_JSON_PASTE20, \
2268         NLOHMANN_JSON_PASTE19, \
2269         NLOHMANN_JSON_PASTE18, \
2270         NLOHMANN_JSON_PASTE17, \
2271         NLOHMANN_JSON_PASTE16, \
2272         NLOHMANN_JSON_PASTE15, \
2273         NLOHMANN_JSON_PASTE14, \
2274         NLOHMANN_JSON_PASTE13, \
2275         NLOHMANN_JSON_PASTE12, \
2276         NLOHMANN_JSON_PASTE11, \
2277         NLOHMANN_JSON_PASTE10, \
2278         NLOHMANN_JSON_PASTE9, \
2279         NLOHMANN_JSON_PASTE8, \
2280         NLOHMANN_JSON_PASTE7, \
2281         NLOHMANN_JSON_PASTE6, \
2282         NLOHMANN_JSON_PASTE5, \
2283         NLOHMANN_JSON_PASTE4, \
2284         NLOHMANN_JSON_PASTE3, \
2285         NLOHMANN_JSON_PASTE2, \
2286         NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2287 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2288 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2289 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2290 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2291 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2292 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2293 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2294 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2295 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2296 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2297 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2298 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2299 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2300 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2301 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2302 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2303 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2304 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2305 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2306 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2307 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2308 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2309 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2310 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2311 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2312 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2313 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2314 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2315 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2316 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2317 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2318 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2319 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2320 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2321 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2322 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2323 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2324 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2325 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2326 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2327 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2328 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2329 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2330 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2331 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2332 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2333 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2334 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2335 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2336 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2337 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2338 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2339 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2340 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2341 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2342 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2343 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2344 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2345 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2346 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2347 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2348 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2349 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2350 
2351 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2352 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2353 
2354 /*!
2355 @brief macro
2356 @def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2357 @since version 3.9.0
2358 */
2359 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
2360     friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2361     friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2362 
2363 /*!
2364 @brief macro
2365 @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2366 @since version 3.9.0
2367 */
2368 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
2369     inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2370     inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2371 
2372 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2373     #define JSON_USE_IMPLICIT_CONVERSIONS 1
2374 #endif
2375 
2376 #if JSON_USE_IMPLICIT_CONVERSIONS
2377     #define JSON_EXPLICIT
2378 #else
2379     #define JSON_EXPLICIT explicit
2380 #endif
2381 
2382 
2383 namespace nlohmann
2384 {
2385 namespace detail
2386 {
2387 ////////////////
2388 // exceptions //
2389 ////////////////
2390 
2391 /*!
2392 @brief general exception of the @ref basic_json class
2393 
2394 This class is an extension of `std::exception` objects with a member @a id for
2395 exception ids. It is used as the base class for all exceptions thrown by the
2396 @ref basic_json class. This class can hence be used as "wildcard" to catch
2397 exceptions.
2398 
2399 Subclasses:
2400 - @ref parse_error for exceptions indicating a parse error
2401 - @ref invalid_iterator for exceptions indicating errors with iterators
2402 - @ref type_error for exceptions indicating executing a member function with
2403                   a wrong type
2404 - @ref out_of_range for exceptions indicating access out of the defined range
2405 - @ref other_error for exceptions indicating other library errors
2406 
2407 @internal
2408 @note To have nothrow-copy-constructible exceptions, we internally use
2409       `std::runtime_error` which can cope with arbitrary-length error messages.
2410       Intermediate strings are built with static functions and then passed to
2411       the actual constructor.
2412 @endinternal
2413 
2414 @liveexample{The following code shows how arbitrary library exceptions can be
2415 caught.,exception}
2416 
2417 @since version 3.0.0
2418 */
2419 class exception : public std::exception
2420 {
2421   public:
2422     /// returns the explanatory string
2423     JSON_HEDLEY_RETURNS_NON_NULL
what() const2424     const char* what() const noexcept override
2425     {
2426         return m.what();
2427     }
2428 
2429     /// the id of the exception
2430     const int id;
2431 
2432   protected:
2433     JSON_HEDLEY_NON_NULL(3)
exception(int id_,const char * what_arg)2434     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2435 
name(const std::string & ename,int id_)2436     static std::string name(const std::string& ename, int id_)
2437     {
2438         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2439     }
2440 
2441   private:
2442     /// an exception object as storage for error messages
2443     std::runtime_error m;
2444 };
2445 
2446 /*!
2447 @brief exception indicating a parse error
2448 
2449 This exception is thrown by the library when a parse error occurs. Parse errors
2450 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2451 as when using JSON Patch.
2452 
2453 Member @a byte holds the byte index of the last read character in the input
2454 file.
2455 
2456 Exceptions have ids 1xx.
2457 
2458 name / id                      | example message | description
2459 ------------------------------ | --------------- | -------------------------
2460 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.
2461 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.
2462 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.
2463 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.
2464 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.
2465 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`.
2466 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.
2467 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.
2468 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2469 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.
2470 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.
2471 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.
2472 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2473 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.
2474 
2475 @note For an input with n bytes, 1 is the index of the first character and n+1
2476       is the index of the terminating null byte or the end of file. This also
2477       holds true when reading a byte vector (CBOR or MessagePack).
2478 
2479 @liveexample{The following code shows how a `parse_error` exception can be
2480 caught.,parse_error}
2481 
2482 @sa - @ref exception for the base class of the library exceptions
2483 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2484 @sa - @ref type_error for exceptions indicating executing a member function with
2485                     a wrong type
2486 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2487 @sa - @ref other_error for exceptions indicating other library errors
2488 
2489 @since version 3.0.0
2490 */
2491 class parse_error : public exception
2492 {
2493   public:
2494     /*!
2495     @brief create a parse error exception
2496     @param[in] id_       the id of the exception
2497     @param[in] pos       the position where the error occurred (or with
2498                          chars_read_total=0 if the position cannot be
2499                          determined)
2500     @param[in] what_arg  the explanatory string
2501     @return parse_error object
2502     */
create(int id_,const position_t & pos,const std::string & what_arg)2503     static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
2504     {
2505         std::string w = exception::name("parse_error", id_) + "parse error" +
2506                         position_string(pos) + ": " + what_arg;
2507         return parse_error(id_, pos.chars_read_total, w.c_str());
2508     }
2509 
create(int id_,std::size_t byte_,const std::string & what_arg)2510     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
2511     {
2512         std::string w = exception::name("parse_error", id_) + "parse error" +
2513                         (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2514                         ": " + what_arg;
2515         return parse_error(id_, byte_, w.c_str());
2516     }
2517 
2518     /*!
2519     @brief byte index of the parse error
2520 
2521     The byte index of the last read character in the input file.
2522 
2523     @note For an input with n bytes, 1 is the index of the first character and
2524           n+1 is the index of the terminating null byte or the end of file.
2525           This also holds true when reading a byte vector (CBOR or MessagePack).
2526     */
2527     const std::size_t byte;
2528 
2529   private:
parse_error(int id_,std::size_t byte_,const char * what_arg)2530     parse_error(int id_, std::size_t byte_, const char* what_arg)
2531         : exception(id_, what_arg), byte(byte_) {}
2532 
position_string(const position_t & pos)2533     static std::string position_string(const position_t& pos)
2534     {
2535         return " at line " + std::to_string(pos.lines_read + 1) +
2536                ", column " + std::to_string(pos.chars_read_current_line);
2537     }
2538 };
2539 
2540 /*!
2541 @brief exception indicating errors with iterators
2542 
2543 This exception is thrown if iterators passed to a library function do not match
2544 the expected semantics.
2545 
2546 Exceptions have ids 2xx.
2547 
2548 name / id                           | example message | description
2549 ----------------------------------- | --------------- | -------------------------
2550 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.
2551 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.
2552 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.
2553 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.
2554 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.
2555 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.
2556 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.
2557 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.
2558 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.
2559 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.
2560 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.
2561 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2562 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2563 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().
2564 
2565 @liveexample{The following code shows how an `invalid_iterator` exception can be
2566 caught.,invalid_iterator}
2567 
2568 @sa - @ref exception for the base class of the library exceptions
2569 @sa - @ref parse_error for exceptions indicating a parse error
2570 @sa - @ref type_error for exceptions indicating executing a member function with
2571                     a wrong type
2572 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2573 @sa - @ref other_error for exceptions indicating other library errors
2574 
2575 @since version 3.0.0
2576 */
2577 class invalid_iterator : public exception
2578 {
2579   public:
create(int id_,const std::string & what_arg)2580     static invalid_iterator create(int id_, const std::string& what_arg)
2581     {
2582         std::string w = exception::name("invalid_iterator", id_) + what_arg;
2583         return invalid_iterator(id_, w.c_str());
2584     }
2585 
2586   private:
2587     JSON_HEDLEY_NON_NULL(3)
invalid_iterator(int id_,const char * what_arg)2588     invalid_iterator(int id_, const char* what_arg)
2589         : exception(id_, what_arg) {}
2590 };
2591 
2592 /*!
2593 @brief exception indicating executing a member function with a wrong type
2594 
2595 This exception is thrown in case of a type error; that is, a library function is
2596 executed on a JSON value whose type does not match the expected semantics.
2597 
2598 Exceptions have ids 3xx.
2599 
2600 name / id                     | example message | description
2601 ----------------------------- | --------------- | -------------------------
2602 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.
2603 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.
2604 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 &.
2605 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2606 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2607 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2608 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2609 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.
2610 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2611 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2612 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.
2613 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2614 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.
2615 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2616 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.
2617 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. |
2618 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) |
2619 
2620 @liveexample{The following code shows how a `type_error` exception can be
2621 caught.,type_error}
2622 
2623 @sa - @ref exception for the base class of the library exceptions
2624 @sa - @ref parse_error for exceptions indicating a parse error
2625 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2626 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2627 @sa - @ref other_error for exceptions indicating other library errors
2628 
2629 @since version 3.0.0
2630 */
2631 class type_error : public exception
2632 {
2633   public:
create(int id_,const std::string & what_arg)2634     static type_error create(int id_, const std::string& what_arg)
2635     {
2636         std::string w = exception::name("type_error", id_) + what_arg;
2637         return type_error(id_, w.c_str());
2638     }
2639 
2640   private:
2641     JSON_HEDLEY_NON_NULL(3)
type_error(int id_,const char * what_arg)2642     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2643 };
2644 
2645 /*!
2646 @brief exception indicating access out of the defined range
2647 
2648 This exception is thrown in case a library function is called on an input
2649 parameter that exceeds the expected range, for instance in case of array
2650 indices or nonexisting object keys.
2651 
2652 Exceptions have ids 4xx.
2653 
2654 name / id                       | example message | description
2655 ------------------------------- | --------------- | -------------------------
2656 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.
2657 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.
2658 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2659 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2660 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.
2661 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.
2662 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) |
2663 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2664 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 |
2665 
2666 @liveexample{The following code shows how an `out_of_range` exception can be
2667 caught.,out_of_range}
2668 
2669 @sa - @ref exception for the base class of the library exceptions
2670 @sa - @ref parse_error for exceptions indicating a parse error
2671 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2672 @sa - @ref type_error for exceptions indicating executing a member function with
2673                     a wrong type
2674 @sa - @ref other_error for exceptions indicating other library errors
2675 
2676 @since version 3.0.0
2677 */
2678 class out_of_range : public exception
2679 {
2680   public:
create(int id_,const std::string & what_arg)2681     static out_of_range create(int id_, const std::string& what_arg)
2682     {
2683         std::string w = exception::name("out_of_range", id_) + what_arg;
2684         return out_of_range(id_, w.c_str());
2685     }
2686 
2687   private:
2688     JSON_HEDLEY_NON_NULL(3)
out_of_range(int id_,const char * what_arg)2689     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2690 };
2691 
2692 /*!
2693 @brief exception indicating other library errors
2694 
2695 This exception is thrown in case of errors that cannot be classified with the
2696 other exception types.
2697 
2698 Exceptions have ids 5xx.
2699 
2700 name / id                      | example message | description
2701 ------------------------------ | --------------- | -------------------------
2702 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
2703 
2704 @sa - @ref exception for the base class of the library exceptions
2705 @sa - @ref parse_error for exceptions indicating a parse error
2706 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2707 @sa - @ref type_error for exceptions indicating executing a member function with
2708                     a wrong type
2709 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2710 
2711 @liveexample{The following code shows how an `other_error` exception can be
2712 caught.,other_error}
2713 
2714 @since version 3.0.0
2715 */
2716 class other_error : public exception
2717 {
2718   public:
create(int id_,const std::string & what_arg)2719     static other_error create(int id_, const std::string& what_arg)
2720     {
2721         std::string w = exception::name("other_error", id_) + what_arg;
2722         return other_error(id_, w.c_str());
2723     }
2724 
2725   private:
2726     JSON_HEDLEY_NON_NULL(3)
other_error(int id_,const char * what_arg)2727     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2728 };
2729 }  // namespace detail
2730 }  // namespace nlohmann
2731 
2732 // #include <nlohmann/detail/macro_scope.hpp>
2733 
2734 // #include <nlohmann/detail/meta/cpp_future.hpp>
2735 
2736 
2737 #include <cstddef> // size_t
2738 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2739 
2740 namespace nlohmann
2741 {
2742 namespace detail
2743 {
2744 // alias templates to reduce boilerplate
2745 template<bool B, typename T = void>
2746 using enable_if_t = typename std::enable_if<B, T>::type;
2747 
2748 template<typename T>
2749 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2750 
2751 // implementation of C++14 index_sequence and affiliates
2752 // source: https://stackoverflow.com/a/32223343
2753 template<std::size_t... Ints>
2754 struct index_sequence
2755 {
2756     using type = index_sequence;
2757     using value_type = std::size_t;
sizenlohmann::detail::index_sequence2758     static constexpr std::size_t size() noexcept
2759     {
2760         return sizeof...(Ints);
2761     }
2762 };
2763 
2764 template<class Sequence1, class Sequence2>
2765 struct merge_and_renumber;
2766 
2767 template<std::size_t... I1, std::size_t... I2>
2768 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
2769         : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
2770 
2771 template<std::size_t N>
2772 struct make_index_sequence
2773     : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
2774       typename make_index_sequence < N - N / 2 >::type > {};
2775 
2776 template<> struct make_index_sequence<0> : index_sequence<> {};
2777 template<> struct make_index_sequence<1> : index_sequence<0> {};
2778 
2779 template<typename... Ts>
2780 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
2781 
2782 // dispatch utility (taken from ranges-v3)
2783 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
2784 template<> struct priority_tag<0> {};
2785 
2786 // taken from ranges-v3
2787 template<typename T>
2788 struct static_const
2789 {
2790     static constexpr T value{};
2791 };
2792 
2793 template<typename T>
2794 constexpr T static_const<T>::value;
2795 }  // namespace detail
2796 }  // namespace nlohmann
2797 
2798 // #include <nlohmann/detail/meta/type_traits.hpp>
2799 
2800 
2801 #include <limits> // numeric_limits
2802 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
2803 #include <utility> // declval
2804 
2805 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2806 
2807 
2808 #include <iterator> // random_access_iterator_tag
2809 
2810 // #include <nlohmann/detail/meta/void_t.hpp>
2811 
2812 
2813 namespace nlohmann
2814 {
2815 namespace detail
2816 {
2817 template<typename ...Ts> struct make_void
2818 {
2819     using type = void;
2820 };
2821 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2822 } // namespace detail
2823 }  // namespace nlohmann
2824 
2825 // #include <nlohmann/detail/meta/cpp_future.hpp>
2826 
2827 
2828 namespace nlohmann
2829 {
2830 namespace detail
2831 {
2832 template<typename It, typename = void>
2833 struct iterator_types {};
2834 
2835 template<typename It>
2836 struct iterator_types <
2837     It,
2838     void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
2839     typename It::reference, typename It::iterator_category >>
2840 {
2841     using difference_type = typename It::difference_type;
2842     using value_type = typename It::value_type;
2843     using pointer = typename It::pointer;
2844     using reference = typename It::reference;
2845     using iterator_category = typename It::iterator_category;
2846 };
2847 
2848 // This is required as some compilers implement std::iterator_traits in a way that
2849 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
2850 template<typename T, typename = void>
2851 struct iterator_traits
2852 {
2853 };
2854 
2855 template<typename T>
2856 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
2857             : iterator_types<T>
2858 {
2859 };
2860 
2861 template<typename T>
2862 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
2863 {
2864     using iterator_category = std::random_access_iterator_tag;
2865     using value_type = T;
2866     using difference_type = ptrdiff_t;
2867     using pointer = T*;
2868     using reference = T&;
2869 };
2870 } // namespace detail
2871 } // namespace nlohmann
2872 
2873 // #include <nlohmann/detail/macro_scope.hpp>
2874 
2875 // #include <nlohmann/detail/meta/cpp_future.hpp>
2876 
2877 // #include <nlohmann/detail/meta/detected.hpp>
2878 
2879 
2880 #include <type_traits>
2881 
2882 // #include <nlohmann/detail/meta/void_t.hpp>
2883 
2884 
2885 // https://en.cppreference.com/w/cpp/experimental/is_detected
2886 namespace nlohmann
2887 {
2888 namespace detail
2889 {
2890 struct nonesuch
2891 {
2892     nonesuch() = delete;
2893     ~nonesuch() = delete;
2894     nonesuch(nonesuch const&) = delete;
2895     nonesuch(nonesuch const&&) = delete;
2896     void operator=(nonesuch const&) = delete;
2897     void operator=(nonesuch&&) = delete;
2898 };
2899 
2900 template<class Default,
2901          class AlwaysVoid,
2902          template<class...> class Op,
2903          class... Args>
2904 struct detector
2905 {
2906     using value_t = std::false_type;
2907     using type = Default;
2908 };
2909 
2910 template<class Default, template<class...> class Op, class... Args>
2911 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2912 {
2913     using value_t = std::true_type;
2914     using type = Op<Args...>;
2915 };
2916 
2917 template<template<class...> class Op, class... Args>
2918 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2919 
2920 template<template<class...> class Op, class... Args>
2921 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2922 
2923 template<class Default, template<class...> class Op, class... Args>
2924 using detected_or = detector<Default, void, Op, Args...>;
2925 
2926 template<class Default, template<class...> class Op, class... Args>
2927 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2928 
2929 template<class Expected, template<class...> class Op, class... Args>
2930 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2931 
2932 template<class To, template<class...> class Op, class... Args>
2933 using is_detected_convertible =
2934     std::is_convertible<detected_t<Op, Args...>, To>;
2935 }  // namespace detail
2936 }  // namespace nlohmann
2937 
2938 // #include <nlohmann/json_fwd.hpp>
2939 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
2940 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
2941 
2942 #include <cstdint> // int64_t, uint64_t
2943 #include <map> // map
2944 #include <memory> // allocator
2945 #include <string> // string
2946 #include <vector> // vector
2947 
2948 /*!
2949 @brief namespace for Niels Lohmann
2950 @see https://github.com/nlohmann
2951 @since version 1.0.0
2952 */
2953 namespace nlohmann
2954 {
2955 /*!
2956 @brief default JSONSerializer template argument
2957 
2958 This serializer ignores the template arguments and uses ADL
2959 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
2960 for serialization.
2961 */
2962 template<typename T = void, typename SFINAE = void>
2963 struct adl_serializer;
2964 
2965 template<template<typename U, typename V, typename... Args> class ObjectType =
2966          std::map,
2967          template<typename U, typename... Args> class ArrayType = std::vector,
2968          class StringType = std::string, class BooleanType = bool,
2969          class NumberIntegerType = std::int64_t,
2970          class NumberUnsignedType = std::uint64_t,
2971          class NumberFloatType = double,
2972          template<typename U> class AllocatorType = std::allocator,
2973          template<typename T, typename SFINAE = void> class JSONSerializer =
2974          adl_serializer,
2975          class BinaryType = std::vector<std::uint8_t>>
2976 class basic_json;
2977 
2978 /*!
2979 @brief JSON Pointer
2980 
2981 A JSON pointer defines a string syntax for identifying a specific value
2982 within a JSON document. It can be used with functions `at` and
2983 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
2984 
2985 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
2986 
2987 @since version 2.0.0
2988 */
2989 template<typename BasicJsonType>
2990 class json_pointer;
2991 
2992 /*!
2993 @brief default JSON class
2994 
2995 This type is the default specialization of the @ref basic_json class which
2996 uses the standard template types.
2997 
2998 @since version 1.0.0
2999 */
3000 using json = basic_json<>;
3001 
3002 template<class Key, class T, class IgnoredLess, class Allocator>
3003 struct ordered_map;
3004 
3005 /*!
3006 @brief ordered JSON class
3007 
3008 This type preserves the insertion order of object keys.
3009 
3010 @since version 3.9.0
3011 */
3012 using ordered_json = basic_json<nlohmann::ordered_map>;
3013 
3014 }  // namespace nlohmann
3015 
3016 #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3017 
3018 
3019 namespace nlohmann
3020 {
3021 /*!
3022 @brief detail namespace with internal helper functions
3023 
3024 This namespace collects functions that should not be exposed,
3025 implementations of some @ref basic_json methods, and meta-programming helpers.
3026 
3027 @since version 2.1.0
3028 */
3029 namespace detail
3030 {
3031 /////////////
3032 // helpers //
3033 /////////////
3034 
3035 // Note to maintainers:
3036 //
3037 // Every trait in this file expects a non CV-qualified type.
3038 // The only exceptions are in the 'aliases for detected' section
3039 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3040 //
3041 // In this case, T has to be properly CV-qualified to constraint the function arguments
3042 // (e.g. to_json(BasicJsonType&, const T&))
3043 
3044 template<typename> struct is_basic_json : std::false_type {};
3045 
3046 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3047 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3048 
3049 //////////////////////
3050 // json_ref helpers //
3051 //////////////////////
3052 
3053 template<typename>
3054 class json_ref;
3055 
3056 template<typename>
3057 struct is_json_ref : std::false_type {};
3058 
3059 template<typename T>
3060 struct is_json_ref<json_ref<T>> : std::true_type {};
3061 
3062 //////////////////////////
3063 // aliases for detected //
3064 //////////////////////////
3065 
3066 template<typename T>
3067 using mapped_type_t = typename T::mapped_type;
3068 
3069 template<typename T>
3070 using key_type_t = typename T::key_type;
3071 
3072 template<typename T>
3073 using value_type_t = typename T::value_type;
3074 
3075 template<typename T>
3076 using difference_type_t = typename T::difference_type;
3077 
3078 template<typename T>
3079 using pointer_t = typename T::pointer;
3080 
3081 template<typename T>
3082 using reference_t = typename T::reference;
3083 
3084 template<typename T>
3085 using iterator_category_t = typename T::iterator_category;
3086 
3087 template<typename T>
3088 using iterator_t = typename T::iterator;
3089 
3090 template<typename T, typename... Args>
3091 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3092 
3093 template<typename T, typename... Args>
3094 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3095 
3096 template<typename T, typename U>
3097 using get_template_function = decltype(std::declval<T>().template get<U>());
3098 
3099 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3100 template<typename BasicJsonType, typename T, typename = void>
3101 struct has_from_json : std::false_type {};
3102 
3103 // trait checking if j.get<T> is valid
3104 // use this trait instead of std::is_constructible or std::is_convertible,
3105 // both rely on, or make use of implicit conversions, and thus fail when T
3106 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3107 template <typename BasicJsonType, typename T>
3108 struct is_getable
3109 {
3110     static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3111 };
3112 
3113 template<typename BasicJsonType, typename T>
3114 struct has_from_json < BasicJsonType, T,
3115            enable_if_t < !is_basic_json<T>::value >>
3116 {
3117     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3118 
3119     static constexpr bool value =
3120         is_detected_exact<void, from_json_function, serializer,
3121         const BasicJsonType&, T&>::value;
3122 };
3123 
3124 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3125 // this overload is used for non-default-constructible user-defined-types
3126 template<typename BasicJsonType, typename T, typename = void>
3127 struct has_non_default_from_json : std::false_type {};
3128 
3129 template<typename BasicJsonType, typename T>
3130 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3131 {
3132     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3133 
3134     static constexpr bool value =
3135         is_detected_exact<T, from_json_function, serializer,
3136         const BasicJsonType&>::value;
3137 };
3138 
3139 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3140 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3141 template<typename BasicJsonType, typename T, typename = void>
3142 struct has_to_json : std::false_type {};
3143 
3144 template<typename BasicJsonType, typename T>
3145 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3146 {
3147     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3148 
3149     static constexpr bool value =
3150         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3151         T>::value;
3152 };
3153 
3154 
3155 ///////////////////
3156 // is_ functions //
3157 ///////////////////
3158 
3159 template<typename T, typename = void>
3160 struct is_iterator_traits : std::false_type {};
3161 
3162 template<typename T>
3163 struct is_iterator_traits<iterator_traits<T>>
3164 {
3165   private:
3166     using traits = iterator_traits<T>;
3167 
3168   public:
3169     static constexpr auto value =
3170         is_detected<value_type_t, traits>::value &&
3171         is_detected<difference_type_t, traits>::value &&
3172         is_detected<pointer_t, traits>::value &&
3173         is_detected<iterator_category_t, traits>::value &&
3174         is_detected<reference_t, traits>::value;
3175 };
3176 
3177 // source: https://stackoverflow.com/a/37193089/4116453
3178 
3179 template<typename T, typename = void>
3180 struct is_complete_type : std::false_type {};
3181 
3182 template<typename T>
3183 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3184 
3185 template<typename BasicJsonType, typename CompatibleObjectType,
3186          typename = void>
3187 struct is_compatible_object_type_impl : std::false_type {};
3188 
3189 template<typename BasicJsonType, typename CompatibleObjectType>
3190 struct is_compatible_object_type_impl <
3191     BasicJsonType, CompatibleObjectType,
3192     enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3193     is_detected<key_type_t, CompatibleObjectType>::value >>
3194 {
3195 
3196     using object_t = typename BasicJsonType::object_t;
3197 
3198     // macOS's is_constructible does not play well with nonesuch...
3199     static constexpr bool value =
3200         std::is_constructible<typename object_t::key_type,
3201         typename CompatibleObjectType::key_type>::value &&
3202         std::is_constructible<typename object_t::mapped_type,
3203         typename CompatibleObjectType::mapped_type>::value;
3204 };
3205 
3206 template<typename BasicJsonType, typename CompatibleObjectType>
3207 struct is_compatible_object_type
3208     : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3209 
3210 template<typename BasicJsonType, typename ConstructibleObjectType,
3211          typename = void>
3212 struct is_constructible_object_type_impl : std::false_type {};
3213 
3214 template<typename BasicJsonType, typename ConstructibleObjectType>
3215 struct is_constructible_object_type_impl <
3216     BasicJsonType, ConstructibleObjectType,
3217     enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3218     is_detected<key_type_t, ConstructibleObjectType>::value >>
3219 {
3220     using object_t = typename BasicJsonType::object_t;
3221 
3222     static constexpr bool value =
3223         (std::is_default_constructible<ConstructibleObjectType>::value &&
3224          (std::is_move_assignable<ConstructibleObjectType>::value ||
3225           std::is_copy_assignable<ConstructibleObjectType>::value) &&
3226          (std::is_constructible<typename ConstructibleObjectType::key_type,
3227           typename object_t::key_type>::value &&
3228           std::is_same <
3229           typename object_t::mapped_type,
3230           typename ConstructibleObjectType::mapped_type >::value)) ||
3231         (has_from_json<BasicJsonType,
3232          typename ConstructibleObjectType::mapped_type>::value ||
3233          has_non_default_from_json <
3234          BasicJsonType,
3235          typename ConstructibleObjectType::mapped_type >::value);
3236 };
3237 
3238 template<typename BasicJsonType, typename ConstructibleObjectType>
3239 struct is_constructible_object_type
3240     : is_constructible_object_type_impl<BasicJsonType,
3241       ConstructibleObjectType> {};
3242 
3243 template<typename BasicJsonType, typename CompatibleStringType,
3244          typename = void>
3245 struct is_compatible_string_type_impl : std::false_type {};
3246 
3247 template<typename BasicJsonType, typename CompatibleStringType>
3248 struct is_compatible_string_type_impl <
3249     BasicJsonType, CompatibleStringType,
3250     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3251     value_type_t, CompatibleStringType>::value >>
3252 {
3253     static constexpr auto value =
3254         std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3255 };
3256 
3257 template<typename BasicJsonType, typename ConstructibleStringType>
3258 struct is_compatible_string_type
3259     : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3260 
3261 template<typename BasicJsonType, typename ConstructibleStringType,
3262          typename = void>
3263 struct is_constructible_string_type_impl : std::false_type {};
3264 
3265 template<typename BasicJsonType, typename ConstructibleStringType>
3266 struct is_constructible_string_type_impl <
3267     BasicJsonType, ConstructibleStringType,
3268     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3269     value_type_t, ConstructibleStringType>::value >>
3270 {
3271     static constexpr auto value =
3272         std::is_constructible<ConstructibleStringType,
3273         typename BasicJsonType::string_t>::value;
3274 };
3275 
3276 template<typename BasicJsonType, typename ConstructibleStringType>
3277 struct is_constructible_string_type
3278     : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3279 
3280 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3281 struct is_compatible_array_type_impl : std::false_type {};
3282 
3283 template<typename BasicJsonType, typename CompatibleArrayType>
3284 struct is_compatible_array_type_impl <
3285     BasicJsonType, CompatibleArrayType,
3286     enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3287     is_detected<iterator_t, CompatibleArrayType>::value&&
3288 // This is needed because json_reverse_iterator has a ::iterator type...
3289 // Therefore it is detected as a CompatibleArrayType.
3290 // The real fix would be to have an Iterable concept.
3291     !is_iterator_traits <
3292     iterator_traits<CompatibleArrayType >>::value >>
3293 {
3294     static constexpr bool value =
3295         std::is_constructible<BasicJsonType,
3296         typename CompatibleArrayType::value_type>::value;
3297 };
3298 
3299 template<typename BasicJsonType, typename CompatibleArrayType>
3300 struct is_compatible_array_type
3301     : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3302 
3303 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3304 struct is_constructible_array_type_impl : std::false_type {};
3305 
3306 template<typename BasicJsonType, typename ConstructibleArrayType>
3307 struct is_constructible_array_type_impl <
3308     BasicJsonType, ConstructibleArrayType,
3309     enable_if_t<std::is_same<ConstructibleArrayType,
3310     typename BasicJsonType::value_type>::value >>
3311             : std::true_type {};
3312 
3313 template<typename BasicJsonType, typename ConstructibleArrayType>
3314 struct is_constructible_array_type_impl <
3315     BasicJsonType, ConstructibleArrayType,
3316     enable_if_t < !std::is_same<ConstructibleArrayType,
3317     typename BasicJsonType::value_type>::value&&
3318     std::is_default_constructible<ConstructibleArrayType>::value&&
3319 (std::is_move_assignable<ConstructibleArrayType>::value ||
3320  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3321 is_detected<value_type_t, ConstructibleArrayType>::value&&
3322 is_detected<iterator_t, ConstructibleArrayType>::value&&
3323 is_complete_type <
3324 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3325 {
3326     static constexpr bool value =
3327         // This is needed because json_reverse_iterator has a ::iterator type,
3328         // furthermore, std::back_insert_iterator (and other iterators) have a
3329         // base class `iterator`... Therefore it is detected as a
3330         // ConstructibleArrayType. The real fix would be to have an Iterable
3331         // concept.
3332         !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3333 
3334         (std::is_same<typename ConstructibleArrayType::value_type,
3335          typename BasicJsonType::array_t::value_type>::value ||
3336          has_from_json<BasicJsonType,
3337          typename ConstructibleArrayType::value_type>::value ||
3338          has_non_default_from_json <
3339          BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3340 };
3341 
3342 template<typename BasicJsonType, typename ConstructibleArrayType>
3343 struct is_constructible_array_type
3344     : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3345 
3346 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3347          typename = void>
3348 struct is_compatible_integer_type_impl : std::false_type {};
3349 
3350 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3351 struct is_compatible_integer_type_impl <
3352     RealIntegerType, CompatibleNumberIntegerType,
3353     enable_if_t < std::is_integral<RealIntegerType>::value&&
3354     std::is_integral<CompatibleNumberIntegerType>::value&&
3355     !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3356 {
3357     // is there an assert somewhere on overflows?
3358     using RealLimits = std::numeric_limits<RealIntegerType>;
3359     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3360 
3361     static constexpr auto value =
3362         std::is_constructible<RealIntegerType,
3363         CompatibleNumberIntegerType>::value &&
3364         CompatibleLimits::is_integer &&
3365         RealLimits::is_signed == CompatibleLimits::is_signed;
3366 };
3367 
3368 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3369 struct is_compatible_integer_type
3370     : is_compatible_integer_type_impl<RealIntegerType,
3371       CompatibleNumberIntegerType> {};
3372 
3373 template<typename BasicJsonType, typename CompatibleType, typename = void>
3374 struct is_compatible_type_impl: std::false_type {};
3375 
3376 template<typename BasicJsonType, typename CompatibleType>
3377 struct is_compatible_type_impl <
3378     BasicJsonType, CompatibleType,
3379     enable_if_t<is_complete_type<CompatibleType>::value >>
3380 {
3381     static constexpr bool value =
3382         has_to_json<BasicJsonType, CompatibleType>::value;
3383 };
3384 
3385 template<typename BasicJsonType, typename CompatibleType>
3386 struct is_compatible_type
3387     : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3388 
3389 // https://en.cppreference.com/w/cpp/types/conjunction
3390 template<class...> struct conjunction : std::true_type { };
3391 template<class B1> struct conjunction<B1> : B1 { };
3392 template<class B1, class... Bn>
3393 struct conjunction<B1, Bn...>
3394 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3395 
3396 template<typename T1, typename T2>
3397 struct is_constructible_tuple : std::false_type {};
3398 
3399 template<typename T1, typename... Args>
3400 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<std::is_constructible<T1, Args>...> {};
3401 }  // namespace detail
3402 }  // namespace nlohmann
3403 
3404 // #include <nlohmann/detail/value_t.hpp>
3405 
3406 
3407 #include <array> // array
3408 #include <cstddef> // size_t
3409 #include <cstdint> // uint8_t
3410 #include <string> // string
3411 
3412 namespace nlohmann
3413 {
3414 namespace detail
3415 {
3416 ///////////////////////////
3417 // JSON type enumeration //
3418 ///////////////////////////
3419 
3420 /*!
3421 @brief the JSON type enumeration
3422 
3423 This enumeration collects the different JSON types. It is internally used to
3424 distinguish the stored values, and the functions @ref basic_json::is_null(),
3425 @ref basic_json::is_object(), @ref basic_json::is_array(),
3426 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
3427 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
3428 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
3429 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
3430 @ref basic_json::is_structured() rely on it.
3431 
3432 @note There are three enumeration entries (number_integer, number_unsigned, and
3433 number_float), because the library distinguishes these three types for numbers:
3434 @ref basic_json::number_unsigned_t is used for unsigned integers,
3435 @ref basic_json::number_integer_t is used for signed integers, and
3436 @ref basic_json::number_float_t is used for floating-point numbers or to
3437 approximate integers which do not fit in the limits of their respective type.
3438 
3439 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
3440 value with the default value for a given type
3441 
3442 @since version 1.0.0
3443 */
3444 enum class value_t : std::uint8_t
3445 {
3446     null,             ///< null value
3447     object,           ///< object (unordered set of name/value pairs)
3448     array,            ///< array (ordered collection of values)
3449     string,           ///< string value
3450     boolean,          ///< boolean value
3451     number_integer,   ///< number value (signed integer)
3452     number_unsigned,  ///< number value (unsigned integer)
3453     number_float,     ///< number value (floating-point)
3454     binary,           ///< binary array (ordered collection of bytes)
3455     discarded         ///< discarded by the parser callback function
3456 };
3457 
3458 /*!
3459 @brief comparison operator for JSON types
3460 
3461 Returns an ordering that is similar to Python:
3462 - order: null < boolean < number < object < array < string < binary
3463 - furthermore, each type is not smaller than itself
3464 - discarded values are not comparable
3465 - binary is represented as a b"" string in python and directly comparable to a
3466   string; however, making a binary array directly comparable with a string would
3467   be surprising behavior in a JSON file.
3468 
3469 @since version 1.0.0
3470 */
operator <(const value_t lhs,const value_t rhs)3471 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
3472 {
3473     static constexpr std::array<std::uint8_t, 9> order = {{
3474             0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
3475             1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
3476             6 /* binary */
3477         }
3478     };
3479 
3480     const auto l_index = static_cast<std::size_t>(lhs);
3481     const auto r_index = static_cast<std::size_t>(rhs);
3482     return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
3483 }
3484 }  // namespace detail
3485 }  // namespace nlohmann
3486 
3487 
3488 namespace nlohmann
3489 {
3490 namespace detail
3491 {
3492 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)3493 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3494 {
3495     if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3496     {
3497         JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
3498     }
3499     n = nullptr;
3500 }
3501 
3502 // overloads for basic_json template parameters
3503 template < typename BasicJsonType, typename ArithmeticType,
3504            enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3505                          !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3506                          int > = 0 >
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)3507 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3508 {
3509     switch (static_cast<value_t>(j))
3510     {
3511         case value_t::number_unsigned:
3512         {
3513             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3514             break;
3515         }
3516         case value_t::number_integer:
3517         {
3518             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3519             break;
3520         }
3521         case value_t::number_float:
3522         {
3523             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3524             break;
3525         }
3526 
3527         default:
3528             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3529     }
3530 }
3531 
3532 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)3533 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3534 {
3535     if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3536     {
3537         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
3538     }
3539     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3540 }
3541 
3542 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)3543 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3544 {
3545     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3546     {
3547         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3548     }
3549     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3550 }
3551 
3552 template <
3553     typename BasicJsonType, typename ConstructibleStringType,
3554     enable_if_t <
3555         is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3556         !std::is_same<typename BasicJsonType::string_t,
3557                       ConstructibleStringType>::value,
3558         int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)3559 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3560 {
3561     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3562     {
3563         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
3564     }
3565 
3566     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3567 }
3568 
3569 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)3570 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3571 {
3572     get_arithmetic_value(j, val);
3573 }
3574 
3575 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)3576 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3577 {
3578     get_arithmetic_value(j, val);
3579 }
3580 
3581 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)3582 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3583 {
3584     get_arithmetic_value(j, val);
3585 }
3586 
3587 template<typename BasicJsonType, typename EnumType,
3588          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)3589 void from_json(const BasicJsonType& j, EnumType& e)
3590 {
3591     typename std::underlying_type<EnumType>::type val;
3592     get_arithmetic_value(j, val);
3593     e = static_cast<EnumType>(val);
3594 }
3595 
3596 // forward_list doesn't have an insert method
3597 template<typename BasicJsonType, typename T, typename Allocator,
3598          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)3599 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3600 {
3601     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3602     {
3603         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3604     }
3605     l.clear();
3606     std::transform(j.rbegin(), j.rend(),
3607                    std::front_inserter(l), [](const BasicJsonType & i)
3608     {
3609         return i.template get<T>();
3610     });
3611 }
3612 
3613 // valarray doesn't have an insert method
3614 template<typename BasicJsonType, typename T,
3615          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)3616 void from_json(const BasicJsonType& j, std::valarray<T>& l)
3617 {
3618     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3619     {
3620         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3621     }
3622     l.resize(j.size());
3623     std::transform(j.begin(), j.end(), std::begin(l),
3624                    [](const BasicJsonType & elem)
3625     {
3626         return elem.template get<T>();
3627     });
3628 }
3629 
3630 template<typename BasicJsonType, typename T, std::size_t N>
from_json(const BasicJsonType & j,T (& arr)[N])3631 auto from_json(const BasicJsonType& j, T (&arr)[N])
3632 -> decltype(j.template get<T>(), void())
3633 {
3634     for (std::size_t i = 0; i < N; ++i)
3635     {
3636         arr[i] = j.at(i).template get<T>();
3637     }
3638 }
3639 
3640 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)3641 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3642 {
3643     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3644 }
3645 
3646 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)3647 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3648                           priority_tag<2> /*unused*/)
3649 -> decltype(j.template get<T>(), void())
3650 {
3651     for (std::size_t i = 0; i < N; ++i)
3652     {
3653         arr[i] = j.at(i).template get<T>();
3654     }
3655 }
3656 
3657 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)3658 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
3659 -> decltype(
3660     arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
3661     j.template get<typename ConstructibleArrayType::value_type>(),
3662     void())
3663 {
3664     using std::end;
3665 
3666     ConstructibleArrayType ret;
3667     ret.reserve(j.size());
3668     std::transform(j.begin(), j.end(),
3669                    std::inserter(ret, end(ret)), [](const BasicJsonType & i)
3670     {
3671         // get<BasicJsonType>() returns *this, this won't call a from_json
3672         // method when value_type is BasicJsonType
3673         return i.template get<typename ConstructibleArrayType::value_type>();
3674     });
3675     arr = std::move(ret);
3676 }
3677 
3678 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)3679 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
3680                           priority_tag<0> /*unused*/)
3681 {
3682     using std::end;
3683 
3684     ConstructibleArrayType ret;
3685     std::transform(
3686         j.begin(), j.end(), std::inserter(ret, end(ret)),
3687         [](const BasicJsonType & i)
3688     {
3689         // get<BasicJsonType>() returns *this, this won't call a from_json
3690         // method when value_type is BasicJsonType
3691         return i.template get<typename ConstructibleArrayType::value_type>();
3692     });
3693     arr = std::move(ret);
3694 }
3695 
3696 template < typename BasicJsonType, typename ConstructibleArrayType,
3697            enable_if_t <
3698                is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
3699                !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
3700                !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3701                !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
3702                !is_basic_json<ConstructibleArrayType>::value,
3703                int > = 0 >
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)3704 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
3705 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
3706 j.template get<typename ConstructibleArrayType::value_type>(),
3707 void())
3708 {
3709     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3710     {
3711         JSON_THROW(type_error::create(302, "type must be array, but is " +
3712                                       std::string(j.type_name())));
3713     }
3714 
3715     from_json_array_impl(j, arr, priority_tag<3> {});
3716 }
3717 
3718 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::binary_t & bin)3719 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
3720 {
3721     if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
3722     {
3723         JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name())));
3724     }
3725 
3726     bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
3727 }
3728 
3729 template<typename BasicJsonType, typename ConstructibleObjectType,
3730          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)3731 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
3732 {
3733     if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
3734     {
3735         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
3736     }
3737 
3738     ConstructibleObjectType ret;
3739     auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
3740     using value_type = typename ConstructibleObjectType::value_type;
3741     std::transform(
3742         inner_object->begin(), inner_object->end(),
3743         std::inserter(ret, ret.begin()),
3744         [](typename BasicJsonType::object_t::value_type const & p)
3745     {
3746         return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
3747     });
3748     obj = std::move(ret);
3749 }
3750 
3751 // overload for arithmetic types, not chosen for basic_json template arguments
3752 // (BooleanType, etc..); note: Is it really necessary to provide explicit
3753 // overloads for boolean_t etc. in case of a custom BooleanType which is not
3754 // an arithmetic type?
3755 template < typename BasicJsonType, typename ArithmeticType,
3756            enable_if_t <
3757                std::is_arithmetic<ArithmeticType>::value&&
3758                !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
3759                !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
3760                !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
3761                !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3762                int > = 0 >
from_json(const BasicJsonType & j,ArithmeticType & val)3763 void from_json(const BasicJsonType& j, ArithmeticType& val)
3764 {
3765     switch (static_cast<value_t>(j))
3766     {
3767         case value_t::number_unsigned:
3768         {
3769             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3770             break;
3771         }
3772         case value_t::number_integer:
3773         {
3774             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3775             break;
3776         }
3777         case value_t::number_float:
3778         {
3779             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3780             break;
3781         }
3782         case value_t::boolean:
3783         {
3784             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
3785             break;
3786         }
3787 
3788         default:
3789             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
3790     }
3791 }
3792 
3793 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)3794 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
3795 {
3796     p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
3797 }
3798 
3799 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)3800 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
3801 {
3802     t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
3803 }
3804 
3805 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)3806 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
3807 {
3808     from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
3809 }
3810 
3811 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
3812            typename = enable_if_t < !std::is_constructible <
3813                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)3814 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
3815 {
3816     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3817     {
3818         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3819     }
3820     m.clear();
3821     for (const auto& p : j)
3822     {
3823         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3824         {
3825             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3826         }
3827         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3828     }
3829 }
3830 
3831 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
3832            typename = enable_if_t < !std::is_constructible <
3833                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)3834 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
3835 {
3836     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3837     {
3838         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
3839     }
3840     m.clear();
3841     for (const auto& p : j)
3842     {
3843         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
3844         {
3845             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
3846         }
3847         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
3848     }
3849 }
3850 
3851 struct from_json_fn
3852 {
3853     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn3854     auto operator()(const BasicJsonType& j, T& val) const
3855     noexcept(noexcept(from_json(j, val)))
3856     -> decltype(from_json(j, val), void())
3857     {
3858         return from_json(j, val);
3859     }
3860 };
3861 }  // namespace detail
3862 
3863 /// namespace to hold default `from_json` function
3864 /// to see why this is required:
3865 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
3866 namespace
3867 {
3868 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
3869 } // namespace
3870 } // namespace nlohmann
3871 
3872 // #include <nlohmann/detail/conversions/to_json.hpp>
3873 
3874 
3875 #include <algorithm> // copy
3876 #include <iterator> // begin, end
3877 #include <string> // string
3878 #include <tuple> // tuple, get
3879 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
3880 #include <utility> // move, forward, declval, pair
3881 #include <valarray> // valarray
3882 #include <vector> // vector
3883 
3884 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
3885 
3886 
3887 #include <cstddef> // size_t
3888 #include <iterator> // input_iterator_tag
3889 #include <string> // string, to_string
3890 #include <tuple> // tuple_size, get, tuple_element
3891 
3892 // #include <nlohmann/detail/meta/type_traits.hpp>
3893 
3894 // #include <nlohmann/detail/value_t.hpp>
3895 
3896 
3897 namespace nlohmann
3898 {
3899 namespace detail
3900 {
3901 template<typename string_type>
int_to_string(string_type & target,std::size_t value)3902 void int_to_string( string_type& target, std::size_t value )
3903 {
3904     // For ADL
3905     using std::to_string;
3906     target = to_string(value);
3907 }
3908 template<typename IteratorType> class iteration_proxy_value
3909 {
3910   public:
3911     using difference_type = std::ptrdiff_t;
3912     using value_type = iteration_proxy_value;
3913     using pointer = value_type * ;
3914     using reference = value_type & ;
3915     using iterator_category = std::input_iterator_tag;
3916     using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
3917 
3918   private:
3919     /// the iterator
3920     IteratorType anchor;
3921     /// an index for arrays (used to create key names)
3922     std::size_t array_index = 0;
3923     /// last stringified array index
3924     mutable std::size_t array_index_last = 0;
3925     /// a string representation of the array index
3926     mutable string_type array_index_str = "0";
3927     /// an empty string (to return a reference for primitive values)
3928     const string_type empty_str = "";
3929 
3930   public:
iteration_proxy_value(IteratorType it)3931     explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
3932 
3933     /// dereference operator (needed for range-based for)
operator *()3934     iteration_proxy_value& operator*()
3935     {
3936         return *this;
3937     }
3938 
3939     /// increment operator (needed for range-based for)
operator ++()3940     iteration_proxy_value& operator++()
3941     {
3942         ++anchor;
3943         ++array_index;
3944 
3945         return *this;
3946     }
3947 
3948     /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const3949     bool operator==(const iteration_proxy_value& o) const
3950     {
3951         return anchor == o.anchor;
3952     }
3953 
3954     /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const3955     bool operator!=(const iteration_proxy_value& o) const
3956     {
3957         return anchor != o.anchor;
3958     }
3959 
3960     /// return key of the iterator
key() const3961     const string_type& key() const
3962     {
3963         JSON_ASSERT(anchor.m_object != nullptr);
3964 
3965         switch (anchor.m_object->type())
3966         {
3967             // use integer array index as key
3968             case value_t::array:
3969             {
3970                 if (array_index != array_index_last)
3971                 {
3972                     int_to_string( array_index_str, array_index );
3973                     array_index_last = array_index;
3974                 }
3975                 return array_index_str;
3976             }
3977 
3978             // use key from the object
3979             case value_t::object:
3980                 return anchor.key();
3981 
3982             // use an empty key for all primitive types
3983             default:
3984                 return empty_str;
3985         }
3986     }
3987 
3988     /// return value of the iterator
value() const3989     typename IteratorType::reference value() const
3990     {
3991         return anchor.value();
3992     }
3993 };
3994 
3995 /// proxy class for the items() function
3996 template<typename IteratorType> class iteration_proxy
3997 {
3998   private:
3999     /// the container to iterate
4000     typename IteratorType::reference container;
4001 
4002   public:
4003     /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)4004     explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4005         : container(cont) {}
4006 
4007     /// return iterator begin (needed for range-based for)
begin()4008     iteration_proxy_value<IteratorType> begin() noexcept
4009     {
4010         return iteration_proxy_value<IteratorType>(container.begin());
4011     }
4012 
4013     /// return iterator end (needed for range-based for)
end()4014     iteration_proxy_value<IteratorType> end() noexcept
4015     {
4016         return iteration_proxy_value<IteratorType>(container.end());
4017     }
4018 };
4019 // Structured Bindings Support
4020 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4021 // And see https://github.com/nlohmann/json/pull/1391
4022 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)4023 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4024 {
4025     return i.key();
4026 }
4027 // Structured Bindings Support
4028 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4029 // And see https://github.com/nlohmann/json/pull/1391
4030 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)4031 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4032 {
4033     return i.value();
4034 }
4035 }  // namespace detail
4036 }  // namespace nlohmann
4037 
4038 // The Addition to the STD Namespace is required to add
4039 // Structured Bindings Support to the iteration_proxy_value class
4040 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4041 // And see https://github.com/nlohmann/json/pull/1391
4042 namespace std
4043 {
4044 #if defined(__clang__)
4045     // Fix: https://github.com/nlohmann/json/issues/1401
4046     #pragma clang diagnostic push
4047     #pragma clang diagnostic ignored "-Wmismatched-tags"
4048 #endif
4049 template<typename IteratorType>
4050 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4051             : public std::integral_constant<std::size_t, 2> {};
4052 
4053 template<std::size_t N, typename IteratorType>
4054 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4055 {
4056   public:
4057     using type = decltype(
4058                      get<N>(std::declval <
4059                             ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4060 };
4061 #if defined(__clang__)
4062     #pragma clang diagnostic pop
4063 #endif
4064 } // namespace std
4065 
4066 // #include <nlohmann/detail/meta/cpp_future.hpp>
4067 
4068 // #include <nlohmann/detail/meta/type_traits.hpp>
4069 
4070 // #include <nlohmann/detail/value_t.hpp>
4071 
4072 
4073 namespace nlohmann
4074 {
4075 namespace detail
4076 {
4077 //////////////////
4078 // constructors //
4079 //////////////////
4080 
4081 template<value_t> struct external_constructor;
4082 
4083 template<>
4084 struct external_constructor<value_t::boolean>
4085 {
4086     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4087     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4088     {
4089         j.m_type = value_t::boolean;
4090         j.m_value = b;
4091         j.assert_invariant();
4092     }
4093 };
4094 
4095 template<>
4096 struct external_constructor<value_t::string>
4097 {
4098     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4099     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4100     {
4101         j.m_type = value_t::string;
4102         j.m_value = s;
4103         j.assert_invariant();
4104     }
4105 
4106     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4107     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4108     {
4109         j.m_type = value_t::string;
4110         j.m_value = std::move(s);
4111         j.assert_invariant();
4112     }
4113 
4114     template < typename BasicJsonType, typename CompatibleStringType,
4115                enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4116                              int > = 0 >
constructnlohmann::detail::external_constructor4117     static void construct(BasicJsonType& j, const CompatibleStringType& str)
4118     {
4119         j.m_type = value_t::string;
4120         j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4121         j.assert_invariant();
4122     }
4123 };
4124 
4125 template<>
4126 struct external_constructor<value_t::binary>
4127 {
4128     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4129     static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4130     {
4131         j.m_type = value_t::binary;
4132         typename BasicJsonType::binary_t value{b};
4133         j.m_value = value;
4134         j.assert_invariant();
4135     }
4136 
4137     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4138     static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4139     {
4140         j.m_type = value_t::binary;
4141         typename BasicJsonType::binary_t value{std::move(b)};
4142         j.m_value = value;
4143         j.assert_invariant();
4144     }
4145 };
4146 
4147 template<>
4148 struct external_constructor<value_t::number_float>
4149 {
4150     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4151     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4152     {
4153         j.m_type = value_t::number_float;
4154         j.m_value = val;
4155         j.assert_invariant();
4156     }
4157 };
4158 
4159 template<>
4160 struct external_constructor<value_t::number_unsigned>
4161 {
4162     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4163     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4164     {
4165         j.m_type = value_t::number_unsigned;
4166         j.m_value = val;
4167         j.assert_invariant();
4168     }
4169 };
4170 
4171 template<>
4172 struct external_constructor<value_t::number_integer>
4173 {
4174     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4175     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4176     {
4177         j.m_type = value_t::number_integer;
4178         j.m_value = val;
4179         j.assert_invariant();
4180     }
4181 };
4182 
4183 template<>
4184 struct external_constructor<value_t::array>
4185 {
4186     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4187     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4188     {
4189         j.m_type = value_t::array;
4190         j.m_value = arr;
4191         j.assert_invariant();
4192     }
4193 
4194     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4195     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4196     {
4197         j.m_type = value_t::array;
4198         j.m_value = std::move(arr);
4199         j.assert_invariant();
4200     }
4201 
4202     template < typename BasicJsonType, typename CompatibleArrayType,
4203                enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4204                              int > = 0 >
constructnlohmann::detail::external_constructor4205     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4206     {
4207         using std::begin;
4208         using std::end;
4209         j.m_type = value_t::array;
4210         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4211         j.assert_invariant();
4212     }
4213 
4214     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4215     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4216     {
4217         j.m_type = value_t::array;
4218         j.m_value = value_t::array;
4219         j.m_value.array->reserve(arr.size());
4220         for (const bool x : arr)
4221         {
4222             j.m_value.array->push_back(x);
4223         }
4224         j.assert_invariant();
4225     }
4226 
4227     template<typename BasicJsonType, typename T,
4228              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor4229     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4230     {
4231         j.m_type = value_t::array;
4232         j.m_value = value_t::array;
4233         j.m_value.array->resize(arr.size());
4234         if (arr.size() > 0)
4235         {
4236             std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4237         }
4238         j.assert_invariant();
4239     }
4240 };
4241 
4242 template<>
4243 struct external_constructor<value_t::object>
4244 {
4245     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4246     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4247     {
4248         j.m_type = value_t::object;
4249         j.m_value = obj;
4250         j.assert_invariant();
4251     }
4252 
4253     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4254     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4255     {
4256         j.m_type = value_t::object;
4257         j.m_value = std::move(obj);
4258         j.assert_invariant();
4259     }
4260 
4261     template < typename BasicJsonType, typename CompatibleObjectType,
4262                enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
constructnlohmann::detail::external_constructor4263     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4264     {
4265         using std::begin;
4266         using std::end;
4267 
4268         j.m_type = value_t::object;
4269         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4270         j.assert_invariant();
4271     }
4272 };
4273 
4274 /////////////
4275 // to_json //
4276 /////////////
4277 
4278 template<typename BasicJsonType, typename T,
4279          enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)4280 void to_json(BasicJsonType& j, T b) noexcept
4281 {
4282     external_constructor<value_t::boolean>::construct(j, b);
4283 }
4284 
4285 template<typename BasicJsonType, typename CompatibleString,
4286          enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)4287 void to_json(BasicJsonType& j, const CompatibleString& s)
4288 {
4289     external_constructor<value_t::string>::construct(j, s);
4290 }
4291 
4292 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)4293 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4294 {
4295     external_constructor<value_t::string>::construct(j, std::move(s));
4296 }
4297 
4298 template<typename BasicJsonType, typename FloatType,
4299          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)4300 void to_json(BasicJsonType& j, FloatType val) noexcept
4301 {
4302     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4303 }
4304 
4305 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4306          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)4307 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4308 {
4309     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4310 }
4311 
4312 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4313          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)4314 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4315 {
4316     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4317 }
4318 
4319 template<typename BasicJsonType, typename EnumType,
4320          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)4321 void to_json(BasicJsonType& j, EnumType e) noexcept
4322 {
4323     using underlying_type = typename std::underlying_type<EnumType>::type;
4324     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4325 }
4326 
4327 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)4328 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4329 {
4330     external_constructor<value_t::array>::construct(j, e);
4331 }
4332 
4333 template < typename BasicJsonType, typename CompatibleArrayType,
4334            enable_if_t < is_compatible_array_type<BasicJsonType,
4335                          CompatibleArrayType>::value&&
4336                          !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4337                          !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4338                          !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4339                          !is_basic_json<CompatibleArrayType>::value,
4340                          int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)4341 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4342 {
4343     external_constructor<value_t::array>::construct(j, arr);
4344 }
4345 
4346 template<typename BasicJsonType>
to_json(BasicJsonType & j,const typename BasicJsonType::binary_t & bin)4347 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4348 {
4349     external_constructor<value_t::binary>::construct(j, bin);
4350 }
4351 
4352 template<typename BasicJsonType, typename T,
4353          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)4354 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4355 {
4356     external_constructor<value_t::array>::construct(j, std::move(arr));
4357 }
4358 
4359 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)4360 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4361 {
4362     external_constructor<value_t::array>::construct(j, std::move(arr));
4363 }
4364 
4365 template < typename BasicJsonType, typename CompatibleObjectType,
4366            enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)4367 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4368 {
4369     external_constructor<value_t::object>::construct(j, obj);
4370 }
4371 
4372 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)4373 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4374 {
4375     external_constructor<value_t::object>::construct(j, std::move(obj));
4376 }
4377 
4378 template <
4379     typename BasicJsonType, typename T, std::size_t N,
4380     enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4381                   const T(&)[N]>::value,
4382                   int > = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])4383 void to_json(BasicJsonType& j, const T(&arr)[N])
4384 {
4385     external_constructor<value_t::array>::construct(j, arr);
4386 }
4387 
4388 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
to_json(BasicJsonType & j,const std::pair<T1,T2> & p)4389 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4390 {
4391     j = { p.first, p.second };
4392 }
4393 
4394 // for https://github.com/nlohmann/json/pull/1134
4395 template<typename BasicJsonType, typename T,
4396          enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)4397 void to_json(BasicJsonType& j, const T& b)
4398 {
4399     j = { {b.key(), b.value()} };
4400 }
4401 
4402 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)4403 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4404 {
4405     j = { std::get<Idx>(t)... };
4406 }
4407 
4408 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
to_json(BasicJsonType & j,const T & t)4409 void to_json(BasicJsonType& j, const T& t)
4410 {
4411     to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4412 }
4413 
4414 struct to_json_fn
4415 {
4416     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn4417     auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4418     -> decltype(to_json(j, std::forward<T>(val)), void())
4419     {
4420         return to_json(j, std::forward<T>(val));
4421     }
4422 };
4423 }  // namespace detail
4424 
4425 /// namespace to hold default `to_json` function
4426 namespace
4427 {
4428 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
4429 } // namespace
4430 } // namespace nlohmann
4431 
4432 
4433 namespace nlohmann
4434 {
4435 
4436 template<typename, typename>
4437 struct adl_serializer
4438 {
4439     /*!
4440     @brief convert a JSON value to any value type
4441 
4442     This function is usually called by the `get()` function of the
4443     @ref basic_json class (either explicit or via conversion operators).
4444 
4445     @param[in] j        JSON value to read from
4446     @param[in,out] val  value to write to
4447     */
4448     template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer4449     static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
4450         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4451     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4452     {
4453         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4454     }
4455 
4456     /*!
4457     @brief convert any value type to a JSON value
4458 
4459     This function is usually called by the constructors of the @ref basic_json
4460     class.
4461 
4462     @param[in,out] j  JSON value to write to
4463     @param[in] val    value to read from
4464     */
4465     template<typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer4466     static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
4467         noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
4468     -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
4469     {
4470         ::nlohmann::to_json(j, std::forward<ValueType>(val));
4471     }
4472 };
4473 
4474 }  // namespace nlohmann
4475 
4476 // #include <nlohmann/byte_container_with_subtype.hpp>
4477 
4478 
4479 #include <cstdint> // uint8_t
4480 #include <tuple> // tie
4481 #include <utility> // move
4482 
4483 namespace nlohmann
4484 {
4485 
4486 /*!
4487 @brief an internal type for a backed binary type
4488 
4489 This type extends the template parameter @a BinaryType provided to `basic_json`
4490 with a subtype used by BSON and MessagePack. This type exists so that the user
4491 does not have to specify a type themselves with a specific naming scheme in
4492 order to override the binary type.
4493 
4494 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
4495                    default)
4496 
4497 @since version 3.8.0
4498 */
4499 template<typename BinaryType>
4500 class byte_container_with_subtype : public BinaryType
4501 {
4502   public:
4503     /// the type of the underlying container
4504     using container_type = BinaryType;
4505 
byte_container_with_subtype()4506     byte_container_with_subtype() noexcept(noexcept(container_type()))
4507         : container_type()
4508     {}
4509 
byte_container_with_subtype(const container_type & b)4510     byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
4511         : container_type(b)
4512     {}
4513 
byte_container_with_subtype(container_type && b)4514     byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4515         : container_type(std::move(b))
4516     {}
4517 
byte_container_with_subtype(const container_type & b,std::uint8_t subtype)4518     byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b)))
4519         : container_type(b)
4520         , m_subtype(subtype)
4521         , m_has_subtype(true)
4522     {}
4523 
byte_container_with_subtype(container_type && b,std::uint8_t subtype)4524     byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b))))
4525         : container_type(std::move(b))
4526         , m_subtype(subtype)
4527         , m_has_subtype(true)
4528     {}
4529 
operator ==(const byte_container_with_subtype & rhs) const4530     bool operator==(const byte_container_with_subtype& rhs) const
4531     {
4532         return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
4533                std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
4534     }
4535 
operator !=(const byte_container_with_subtype & rhs) const4536     bool operator!=(const byte_container_with_subtype& rhs) const
4537     {
4538         return !(rhs == *this);
4539     }
4540 
4541     /*!
4542     @brief sets the binary subtype
4543 
4544     Sets the binary subtype of the value, also flags a binary JSON value as
4545     having a subtype, which has implications for serialization.
4546 
4547     @complexity Constant.
4548 
4549     @exceptionsafety No-throw guarantee: this member function never throws
4550     exceptions.
4551 
4552     @sa @ref subtype() -- return the binary subtype
4553     @sa @ref clear_subtype() -- clears the binary subtype
4554     @sa @ref has_subtype() -- returns whether or not the binary value has a
4555     subtype
4556 
4557     @since version 3.8.0
4558     */
set_subtype(std::uint8_t subtype)4559     void set_subtype(std::uint8_t subtype) noexcept
4560     {
4561         m_subtype = subtype;
4562         m_has_subtype = true;
4563     }
4564 
4565     /*!
4566     @brief return the binary subtype
4567 
4568     Returns the numerical subtype of the value if it has a subtype. If it does
4569     not have a subtype, this function will return size_t(-1) as a sentinel
4570     value.
4571 
4572     @return the numerical subtype of the binary value
4573 
4574     @complexity Constant.
4575 
4576     @exceptionsafety No-throw guarantee: this member function never throws
4577     exceptions.
4578 
4579     @sa @ref set_subtype() -- sets the binary subtype
4580     @sa @ref clear_subtype() -- clears the binary subtype
4581     @sa @ref has_subtype() -- returns whether or not the binary value has a
4582     subtype
4583 
4584     @since version 3.8.0
4585     */
subtype() const4586     constexpr std::uint8_t subtype() const noexcept
4587     {
4588         return m_subtype;
4589     }
4590 
4591     /*!
4592     @brief return whether the value has a subtype
4593 
4594     @return whether the value has a subtype
4595 
4596     @complexity Constant.
4597 
4598     @exceptionsafety No-throw guarantee: this member function never throws
4599     exceptions.
4600 
4601     @sa @ref subtype() -- return the binary subtype
4602     @sa @ref set_subtype() -- sets the binary subtype
4603     @sa @ref clear_subtype() -- clears the binary subtype
4604 
4605     @since version 3.8.0
4606     */
has_subtype() const4607     constexpr bool has_subtype() const noexcept
4608     {
4609         return m_has_subtype;
4610     }
4611 
4612     /*!
4613     @brief clears the binary subtype
4614 
4615     Clears the binary subtype and flags the value as not having a subtype, which
4616     has implications for serialization; for instance MessagePack will prefer the
4617     bin family over the ext family.
4618 
4619     @complexity Constant.
4620 
4621     @exceptionsafety No-throw guarantee: this member function never throws
4622     exceptions.
4623 
4624     @sa @ref subtype() -- return the binary subtype
4625     @sa @ref set_subtype() -- sets the binary subtype
4626     @sa @ref has_subtype() -- returns whether or not the binary value has a
4627     subtype
4628 
4629     @since version 3.8.0
4630     */
clear_subtype()4631     void clear_subtype() noexcept
4632     {
4633         m_subtype = 0;
4634         m_has_subtype = false;
4635     }
4636 
4637   private:
4638     std::uint8_t m_subtype = 0;
4639     bool m_has_subtype = false;
4640 };
4641 
4642 }  // namespace nlohmann
4643 
4644 // #include <nlohmann/detail/conversions/from_json.hpp>
4645 
4646 // #include <nlohmann/detail/conversions/to_json.hpp>
4647 
4648 // #include <nlohmann/detail/exceptions.hpp>
4649 
4650 // #include <nlohmann/detail/hash.hpp>
4651 
4652 
4653 #include <cstddef> // size_t, uint8_t
4654 #include <functional> // hash
4655 
4656 namespace nlohmann
4657 {
4658 namespace detail
4659 {
4660 
4661 // boost::hash_combine
combine(std::size_t seed,std::size_t h)4662 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
4663 {
4664     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
4665     return seed;
4666 }
4667 
4668 /*!
4669 @brief hash a JSON value
4670 
4671 The hash function tries to rely on std::hash where possible. Furthermore, the
4672 type of the JSON value is taken into account to have different hash values for
4673 null, 0, 0U, and false, etc.
4674 
4675 @tparam BasicJsonType basic_json specialization
4676 @param j JSON value to hash
4677 @return hash value of j
4678 */
4679 template<typename BasicJsonType>
hash(const BasicJsonType & j)4680 std::size_t hash(const BasicJsonType& j)
4681 {
4682     using string_t = typename BasicJsonType::string_t;
4683     using number_integer_t = typename BasicJsonType::number_integer_t;
4684     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4685     using number_float_t = typename BasicJsonType::number_float_t;
4686 
4687     const auto type = static_cast<std::size_t>(j.type());
4688     switch (j.type())
4689     {
4690         case BasicJsonType::value_t::null:
4691         case BasicJsonType::value_t::discarded:
4692         {
4693             return combine(type, 0);
4694         }
4695 
4696         case BasicJsonType::value_t::object:
4697         {
4698             auto seed = combine(type, j.size());
4699             for (const auto& element : j.items())
4700             {
4701                 const auto h = std::hash<string_t> {}(element.key());
4702                 seed = combine(seed, h);
4703                 seed = combine(seed, hash(element.value()));
4704             }
4705             return seed;
4706         }
4707 
4708         case BasicJsonType::value_t::array:
4709         {
4710             auto seed = combine(type, j.size());
4711             for (const auto& element : j)
4712             {
4713                 seed = combine(seed, hash(element));
4714             }
4715             return seed;
4716         }
4717 
4718         case BasicJsonType::value_t::string:
4719         {
4720             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
4721             return combine(type, h);
4722         }
4723 
4724         case BasicJsonType::value_t::boolean:
4725         {
4726             const auto h = std::hash<bool> {}(j.template get<bool>());
4727             return combine(type, h);
4728         }
4729 
4730         case BasicJsonType::value_t::number_integer:
4731         {
4732             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
4733             return combine(type, h);
4734         }
4735 
4736         case BasicJsonType::value_t::number_unsigned:
4737         {
4738             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
4739             return combine(type, h);
4740         }
4741 
4742         case BasicJsonType::value_t::number_float:
4743         {
4744             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
4745             return combine(type, h);
4746         }
4747 
4748         case BasicJsonType::value_t::binary:
4749         {
4750             auto seed = combine(type, j.get_binary().size());
4751             const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
4752             seed = combine(seed, h);
4753             seed = combine(seed, j.get_binary().subtype());
4754             for (const auto byte : j.get_binary())
4755             {
4756                 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
4757             }
4758             return seed;
4759         }
4760 
4761         default:                   // LCOV_EXCL_LINE
4762             JSON_ASSERT(false);    // LCOV_EXCL_LINE
4763             return 0;              // LCOV_EXCL_LINE
4764     }
4765 }
4766 
4767 }  // namespace detail
4768 }  // namespace nlohmann
4769 
4770 // #include <nlohmann/detail/input/binary_reader.hpp>
4771 
4772 
4773 #include <algorithm> // generate_n
4774 #include <array> // array
4775 #include <cmath> // ldexp
4776 #include <cstddef> // size_t
4777 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
4778 #include <cstdio> // snprintf
4779 #include <cstring> // memcpy
4780 #include <iterator> // back_inserter
4781 #include <limits> // numeric_limits
4782 #include <string> // char_traits, string
4783 #include <utility> // make_pair, move
4784 
4785 // #include <nlohmann/detail/exceptions.hpp>
4786 
4787 // #include <nlohmann/detail/input/input_adapters.hpp>
4788 
4789 
4790 #include <array> // array
4791 #include <cstddef> // size_t
4792 #include <cstdio> //FILE *
4793 #include <cstring> // strlen
4794 #include <istream> // istream
4795 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
4796 #include <memory> // shared_ptr, make_shared, addressof
4797 #include <numeric> // accumulate
4798 #include <string> // string, char_traits
4799 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
4800 #include <utility> // pair, declval
4801 
4802 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
4803 
4804 // #include <nlohmann/detail/macro_scope.hpp>
4805 
4806 
4807 namespace nlohmann
4808 {
4809 namespace detail
4810 {
4811 /// the supported input formats
4812 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
4813 
4814 ////////////////////
4815 // input adapters //
4816 ////////////////////
4817 
4818 /*!
4819 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
4820  buffer. This adapter is a very low level adapter.
4821 */
4822 class file_input_adapter
4823 {
4824   public:
4825     using char_type = char;
4826 
4827     JSON_HEDLEY_NON_NULL(2)
file_input_adapter(std::FILE * f)4828     explicit file_input_adapter(std::FILE* f) noexcept
4829         : m_file(f)
4830     {}
4831 
4832     // make class move-only
4833     file_input_adapter(const file_input_adapter&) = delete;
4834     file_input_adapter(file_input_adapter&&) = default;
4835     file_input_adapter& operator=(const file_input_adapter&) = delete;
4836     file_input_adapter& operator=(file_input_adapter&&) = delete;
4837 
get_character()4838     std::char_traits<char>::int_type get_character() noexcept
4839     {
4840         return std::fgetc(m_file);
4841     }
4842 
4843   private:
4844     /// the file pointer to read from
4845     std::FILE* m_file;
4846 };
4847 
4848 
4849 /*!
4850 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
4851 beginning of input. Does not support changing the underlying std::streambuf
4852 in mid-input. Maintains underlying std::istream and std::streambuf to support
4853 subsequent use of standard std::istream operations to process any input
4854 characters following those used in parsing the JSON input.  Clears the
4855 std::istream flags; any input errors (e.g., EOF) will be detected by the first
4856 subsequent call for input from the std::istream.
4857 */
4858 class input_stream_adapter
4859 {
4860   public:
4861     using char_type = char;
4862 
~input_stream_adapter()4863     ~input_stream_adapter()
4864     {
4865         // clear stream flags; we use underlying streambuf I/O, do not
4866         // maintain ifstream flags, except eof
4867         if (is != nullptr)
4868         {
4869             is->clear(is->rdstate() & std::ios::eofbit);
4870         }
4871     }
4872 
input_stream_adapter(std::istream & i)4873     explicit input_stream_adapter(std::istream& i)
4874         : is(&i), sb(i.rdbuf())
4875     {}
4876 
4877     // delete because of pointer members
4878     input_stream_adapter(const input_stream_adapter&) = delete;
4879     input_stream_adapter& operator=(input_stream_adapter&) = delete;
4880     input_stream_adapter& operator=(input_stream_adapter&& rhs) = delete;
4881 
input_stream_adapter(input_stream_adapter && rhs)4882     input_stream_adapter(input_stream_adapter&& rhs) noexcept : is(rhs.is), sb(rhs.sb)
4883     {
4884         rhs.is = nullptr;
4885         rhs.sb = nullptr;
4886     }
4887 
4888     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
4889     // ensure that std::char_traits<char>::eof() and the character 0xFF do not
4890     // end up as the same value, eg. 0xFFFFFFFF.
get_character()4891     std::char_traits<char>::int_type get_character()
4892     {
4893         auto res = sb->sbumpc();
4894         // set eof manually, as we don't use the istream interface.
4895         if (JSON_HEDLEY_UNLIKELY(res == EOF))
4896         {
4897             is->clear(is->rdstate() | std::ios::eofbit);
4898         }
4899         return res;
4900     }
4901 
4902   private:
4903     /// the associated input stream
4904     std::istream* is = nullptr;
4905     std::streambuf* sb = nullptr;
4906 };
4907 
4908 // General-purpose iterator-based adapter. It might not be as fast as
4909 // theoretically possible for some containers, but it is extremely versatile.
4910 template<typename IteratorType>
4911 class iterator_input_adapter
4912 {
4913   public:
4914     using char_type = typename std::iterator_traits<IteratorType>::value_type;
4915 
iterator_input_adapter(IteratorType first,IteratorType last)4916     iterator_input_adapter(IteratorType first, IteratorType last)
4917         : current(std::move(first)), end(std::move(last)) {}
4918 
get_character()4919     typename std::char_traits<char_type>::int_type get_character()
4920     {
4921         if (JSON_HEDLEY_LIKELY(current != end))
4922         {
4923             auto result = std::char_traits<char_type>::to_int_type(*current);
4924             std::advance(current, 1);
4925             return result;
4926         }
4927         else
4928         {
4929             return std::char_traits<char_type>::eof();
4930         }
4931     }
4932 
4933   private:
4934     IteratorType current;
4935     IteratorType end;
4936 
4937     template<typename BaseInputAdapter, size_t T>
4938     friend struct wide_string_input_helper;
4939 
empty() const4940     bool empty() const
4941     {
4942         return current == end;
4943     }
4944 
4945 };
4946 
4947 
4948 template<typename BaseInputAdapter, size_t T>
4949 struct wide_string_input_helper;
4950 
4951 template<typename BaseInputAdapter>
4952 struct wide_string_input_helper<BaseInputAdapter, 4>
4953 {
4954     // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper4955     static void fill_buffer(BaseInputAdapter& input,
4956                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
4957                             size_t& utf8_bytes_index,
4958                             size_t& utf8_bytes_filled)
4959     {
4960         utf8_bytes_index = 0;
4961 
4962         if (JSON_HEDLEY_UNLIKELY(input.empty()))
4963         {
4964             utf8_bytes[0] = std::char_traits<char>::eof();
4965             utf8_bytes_filled = 1;
4966         }
4967         else
4968         {
4969             // get the current character
4970             const auto wc = input.get_character();
4971 
4972             // UTF-32 to UTF-8 encoding
4973             if (wc < 0x80)
4974             {
4975                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
4976                 utf8_bytes_filled = 1;
4977             }
4978             else if (wc <= 0x7FF)
4979             {
4980                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
4981                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4982                 utf8_bytes_filled = 2;
4983             }
4984             else if (wc <= 0xFFFF)
4985             {
4986                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
4987                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4988                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4989                 utf8_bytes_filled = 3;
4990             }
4991             else if (wc <= 0x10FFFF)
4992             {
4993                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
4994                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
4995                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
4996                 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
4997                 utf8_bytes_filled = 4;
4998             }
4999             else
5000             {
5001                 // unknown character
5002                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5003                 utf8_bytes_filled = 1;
5004             }
5005         }
5006     }
5007 };
5008 
5009 template<typename BaseInputAdapter>
5010 struct wide_string_input_helper<BaseInputAdapter, 2>
5011 {
5012     // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper5013     static void fill_buffer(BaseInputAdapter& input,
5014                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5015                             size_t& utf8_bytes_index,
5016                             size_t& utf8_bytes_filled)
5017     {
5018         utf8_bytes_index = 0;
5019 
5020         if (JSON_HEDLEY_UNLIKELY(input.empty()))
5021         {
5022             utf8_bytes[0] = std::char_traits<char>::eof();
5023             utf8_bytes_filled = 1;
5024         }
5025         else
5026         {
5027             // get the current character
5028             const auto wc = input.get_character();
5029 
5030             // UTF-16 to UTF-8 encoding
5031             if (wc < 0x80)
5032             {
5033                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5034                 utf8_bytes_filled = 1;
5035             }
5036             else if (wc <= 0x7FF)
5037             {
5038                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5039                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5040                 utf8_bytes_filled = 2;
5041             }
5042             else if (0xD800 > wc || wc >= 0xE000)
5043             {
5044                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5045                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5046                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5047                 utf8_bytes_filled = 3;
5048             }
5049             else
5050             {
5051                 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5052                 {
5053                     const auto wc2 = static_cast<unsigned int>(input.get_character());
5054                     const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5055                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5056                     utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5057                     utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5058                     utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5059                     utf8_bytes_filled = 4;
5060                 }
5061                 else
5062                 {
5063                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5064                     utf8_bytes_filled = 1;
5065                 }
5066             }
5067         }
5068     }
5069 };
5070 
5071 // Wraps another input apdater to convert wide character types into individual bytes.
5072 template<typename BaseInputAdapter, typename WideCharType>
5073 class wide_string_input_adapter
5074 {
5075   public:
5076     using char_type = char;
5077 
wide_string_input_adapter(BaseInputAdapter base)5078     wide_string_input_adapter(BaseInputAdapter base)
5079         : base_adapter(base) {}
5080 
get_character()5081     typename std::char_traits<char>::int_type get_character() noexcept
5082     {
5083         // check if buffer needs to be filled
5084         if (utf8_bytes_index == utf8_bytes_filled)
5085         {
5086             fill_buffer<sizeof(WideCharType)>();
5087 
5088             JSON_ASSERT(utf8_bytes_filled > 0);
5089             JSON_ASSERT(utf8_bytes_index == 0);
5090         }
5091 
5092         // use buffer
5093         JSON_ASSERT(utf8_bytes_filled > 0);
5094         JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5095         return utf8_bytes[utf8_bytes_index++];
5096     }
5097 
5098   private:
5099     BaseInputAdapter base_adapter;
5100 
5101     template<size_t T>
fill_buffer()5102     void fill_buffer()
5103     {
5104         wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5105     }
5106 
5107     /// a buffer for UTF-8 bytes
5108     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5109 
5110     /// index to the utf8_codes array for the next valid byte
5111     std::size_t utf8_bytes_index = 0;
5112     /// number of valid bytes in the utf8_codes array
5113     std::size_t utf8_bytes_filled = 0;
5114 };
5115 
5116 
5117 template<typename IteratorType, typename Enable = void>
5118 struct iterator_input_adapter_factory
5119 {
5120     using iterator_type = IteratorType;
5121     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5122     using adapter_type = iterator_input_adapter<iterator_type>;
5123 
createnlohmann::detail::iterator_input_adapter_factory5124     static adapter_type create(IteratorType first, IteratorType last)
5125     {
5126         return adapter_type(std::move(first), std::move(last));
5127     }
5128 };
5129 
5130 template<typename T>
5131 struct is_iterator_of_multibyte
5132 {
5133     using value_type = typename std::iterator_traits<T>::value_type;
5134     enum
5135     {
5136         value = sizeof(value_type) > 1
5137     };
5138 };
5139 
5140 template<typename IteratorType>
5141 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5142 {
5143     using iterator_type = IteratorType;
5144     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5145     using base_adapter_type = iterator_input_adapter<iterator_type>;
5146     using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5147 
createnlohmann::detail::iterator_input_adapter_factory5148     static adapter_type create(IteratorType first, IteratorType last)
5149     {
5150         return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5151     }
5152 };
5153 
5154 // General purpose iterator-based input
5155 template<typename IteratorType>
input_adapter(IteratorType first,IteratorType last)5156 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5157 {
5158     using factory_type = iterator_input_adapter_factory<IteratorType>;
5159     return factory_type::create(first, last);
5160 }
5161 
5162 // Convenience shorthand from container to iterator
5163 template<typename ContainerType>
input_adapter(const ContainerType & container)5164 auto input_adapter(const ContainerType& container) -> decltype(input_adapter(begin(container), end(container)))
5165 {
5166     // Enable ADL
5167     using std::begin;
5168     using std::end;
5169 
5170     return input_adapter(begin(container), end(container));
5171 }
5172 
5173 // Special cases with fast paths
input_adapter(std::FILE * file)5174 inline file_input_adapter input_adapter(std::FILE* file)
5175 {
5176     return file_input_adapter(file);
5177 }
5178 
input_adapter(std::istream & stream)5179 inline input_stream_adapter input_adapter(std::istream& stream)
5180 {
5181     return input_stream_adapter(stream);
5182 }
5183 
input_adapter(std::istream && stream)5184 inline input_stream_adapter input_adapter(std::istream&& stream)
5185 {
5186     return input_stream_adapter(stream);
5187 }
5188 
5189 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5190 
5191 // Null-delimited strings, and the like.
5192 template < typename CharT,
5193            typename std::enable_if <
5194                std::is_pointer<CharT>::value&&
5195                !std::is_array<CharT>::value&&
5196                std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5197                sizeof(typename std::remove_pointer<CharT>::type) == 1,
5198                int >::type = 0 >
input_adapter(CharT b)5199 contiguous_bytes_input_adapter input_adapter(CharT b)
5200 {
5201     auto length = std::strlen(reinterpret_cast<const char*>(b));
5202     const auto* ptr = reinterpret_cast<const char*>(b);
5203     return input_adapter(ptr, ptr + length);
5204 }
5205 
5206 template<typename T, std::size_t N>
input_adapter(T (& array)[N])5207 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
5208 {
5209     return input_adapter(array, array + N);
5210 }
5211 
5212 // This class only handles inputs of input_buffer_adapter type.
5213 // It's required so that expressions like {ptr, len} can be implicitely casted
5214 // to the correct adapter.
5215 class span_input_adapter
5216 {
5217   public:
5218     template < typename CharT,
5219                typename std::enable_if <
5220                    std::is_pointer<CharT>::value&&
5221                    std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5222                    sizeof(typename std::remove_pointer<CharT>::type) == 1,
5223                    int >::type = 0 >
span_input_adapter(CharT b,std::size_t l)5224     span_input_adapter(CharT b, std::size_t l)
5225         : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5226 
5227     template<class IteratorType,
5228              typename std::enable_if<
5229                  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5230                  int>::type = 0>
span_input_adapter(IteratorType first,IteratorType last)5231     span_input_adapter(IteratorType first, IteratorType last)
5232         : ia(input_adapter(first, last)) {}
5233 
get()5234     contiguous_bytes_input_adapter&& get()
5235     {
5236         return std::move(ia);
5237     }
5238 
5239   private:
5240     contiguous_bytes_input_adapter ia;
5241 };
5242 }  // namespace detail
5243 }  // namespace nlohmann
5244 
5245 // #include <nlohmann/detail/input/json_sax.hpp>
5246 
5247 
5248 #include <cstddef>
5249 #include <string> // string
5250 #include <utility> // move
5251 #include <vector> // vector
5252 
5253 // #include <nlohmann/detail/exceptions.hpp>
5254 
5255 // #include <nlohmann/detail/macro_scope.hpp>
5256 
5257 
5258 namespace nlohmann
5259 {
5260 
5261 /*!
5262 @brief SAX interface
5263 
5264 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5265 Each function is called in different situations while the input is parsed. The
5266 boolean return value informs the parser whether to continue processing the
5267 input.
5268 */
5269 template<typename BasicJsonType>
5270 struct json_sax
5271 {
5272     using number_integer_t = typename BasicJsonType::number_integer_t;
5273     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5274     using number_float_t = typename BasicJsonType::number_float_t;
5275     using string_t = typename BasicJsonType::string_t;
5276     using binary_t = typename BasicJsonType::binary_t;
5277 
5278     /*!
5279     @brief a null value was read
5280     @return whether parsing should proceed
5281     */
5282     virtual bool null() = 0;
5283 
5284     /*!
5285     @brief a boolean value was read
5286     @param[in] val  boolean value
5287     @return whether parsing should proceed
5288     */
5289     virtual bool boolean(bool val) = 0;
5290 
5291     /*!
5292     @brief an integer number was read
5293     @param[in] val  integer value
5294     @return whether parsing should proceed
5295     */
5296     virtual bool number_integer(number_integer_t val) = 0;
5297 
5298     /*!
5299     @brief an unsigned integer number was read
5300     @param[in] val  unsigned integer value
5301     @return whether parsing should proceed
5302     */
5303     virtual bool number_unsigned(number_unsigned_t val) = 0;
5304 
5305     /*!
5306     @brief an floating-point number was read
5307     @param[in] val  floating-point value
5308     @param[in] s    raw token value
5309     @return whether parsing should proceed
5310     */
5311     virtual bool number_float(number_float_t val, const string_t& s) = 0;
5312 
5313     /*!
5314     @brief a string was read
5315     @param[in] val  string value
5316     @return whether parsing should proceed
5317     @note It is safe to move the passed string.
5318     */
5319     virtual bool string(string_t& val) = 0;
5320 
5321     /*!
5322     @brief a binary string was read
5323     @param[in] val  binary value
5324     @return whether parsing should proceed
5325     @note It is safe to move the passed binary.
5326     */
5327     virtual bool binary(binary_t& val) = 0;
5328 
5329     /*!
5330     @brief the beginning of an object was read
5331     @param[in] elements  number of object elements or -1 if unknown
5332     @return whether parsing should proceed
5333     @note binary formats may report the number of elements
5334     */
5335     virtual bool start_object(std::size_t elements) = 0;
5336 
5337     /*!
5338     @brief an object key was read
5339     @param[in] val  object key
5340     @return whether parsing should proceed
5341     @note It is safe to move the passed string.
5342     */
5343     virtual bool key(string_t& val) = 0;
5344 
5345     /*!
5346     @brief the end of an object was read
5347     @return whether parsing should proceed
5348     */
5349     virtual bool end_object() = 0;
5350 
5351     /*!
5352     @brief the beginning of an array was read
5353     @param[in] elements  number of array elements or -1 if unknown
5354     @return whether parsing should proceed
5355     @note binary formats may report the number of elements
5356     */
5357     virtual bool start_array(std::size_t elements) = 0;
5358 
5359     /*!
5360     @brief the end of an array was read
5361     @return whether parsing should proceed
5362     */
5363     virtual bool end_array() = 0;
5364 
5365     /*!
5366     @brief a parse error occurred
5367     @param[in] position    the position in the input where the error occurs
5368     @param[in] last_token  the last read token
5369     @param[in] ex          an exception object describing the error
5370     @return whether parsing should proceed (must return false)
5371     */
5372     virtual bool parse_error(std::size_t position,
5373                              const std::string& last_token,
5374                              const detail::exception& ex) = 0;
5375 
5376     virtual ~json_sax() = default;
5377 };
5378 
5379 
5380 namespace detail
5381 {
5382 /*!
5383 @brief SAX implementation to create a JSON value from SAX events
5384 
5385 This class implements the @ref json_sax interface and processes the SAX events
5386 to create a JSON value which makes it basically a DOM parser. The structure or
5387 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
5388 a pointer to the respective array or object for each recursion depth.
5389 
5390 After successful parsing, the value that is passed by reference to the
5391 constructor contains the parsed value.
5392 
5393 @tparam BasicJsonType  the JSON type
5394 */
5395 template<typename BasicJsonType>
5396 class json_sax_dom_parser
5397 {
5398   public:
5399     using number_integer_t = typename BasicJsonType::number_integer_t;
5400     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5401     using number_float_t = typename BasicJsonType::number_float_t;
5402     using string_t = typename BasicJsonType::string_t;
5403     using binary_t = typename BasicJsonType::binary_t;
5404 
5405     /*!
5406     @param[in, out] r  reference to a JSON value that is manipulated while
5407                        parsing
5408     @param[in] allow_exceptions_  whether parse errors yield exceptions
5409     */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)5410     explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5411         : root(r), allow_exceptions(allow_exceptions_)
5412     {}
5413 
5414     // make class move-only
5415     json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5416     json_sax_dom_parser(json_sax_dom_parser&&) = default;
5417     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5418     json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
5419     ~json_sax_dom_parser() = default;
5420 
null()5421     bool null()
5422     {
5423         handle_value(nullptr);
5424         return true;
5425     }
5426 
boolean(bool val)5427     bool boolean(bool val)
5428     {
5429         handle_value(val);
5430         return true;
5431     }
5432 
number_integer(number_integer_t val)5433     bool number_integer(number_integer_t val)
5434     {
5435         handle_value(val);
5436         return true;
5437     }
5438 
number_unsigned(number_unsigned_t val)5439     bool number_unsigned(number_unsigned_t val)
5440     {
5441         handle_value(val);
5442         return true;
5443     }
5444 
number_float(number_float_t val,const string_t &)5445     bool number_float(number_float_t val, const string_t& /*unused*/)
5446     {
5447         handle_value(val);
5448         return true;
5449     }
5450 
string(string_t & val)5451     bool string(string_t& val)
5452     {
5453         handle_value(val);
5454         return true;
5455     }
5456 
binary(binary_t & val)5457     bool binary(binary_t& val)
5458     {
5459         handle_value(std::move(val));
5460         return true;
5461     }
5462 
start_object(std::size_t len)5463     bool start_object(std::size_t len)
5464     {
5465         ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5466 
5467         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5468         {
5469             JSON_THROW(out_of_range::create(408,
5470                                             "excessive object size: " + std::to_string(len)));
5471         }
5472 
5473         return true;
5474     }
5475 
key(string_t & val)5476     bool key(string_t& val)
5477     {
5478         // add null at given key and store the reference for later
5479         object_element = &(ref_stack.back()->m_value.object->operator[](val));
5480         return true;
5481     }
5482 
end_object()5483     bool end_object()
5484     {
5485         ref_stack.pop_back();
5486         return true;
5487     }
5488 
start_array(std::size_t len)5489     bool start_array(std::size_t len)
5490     {
5491         ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5492 
5493         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5494         {
5495             JSON_THROW(out_of_range::create(408,
5496                                             "excessive array size: " + std::to_string(len)));
5497         }
5498 
5499         return true;
5500     }
5501 
end_array()5502     bool end_array()
5503     {
5504         ref_stack.pop_back();
5505         return true;
5506     }
5507 
5508     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)5509     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5510                      const Exception& ex)
5511     {
5512         errored = true;
5513         static_cast<void>(ex);
5514         if (allow_exceptions)
5515         {
5516             JSON_THROW(ex);
5517         }
5518         return false;
5519     }
5520 
is_errored() const5521     constexpr bool is_errored() const
5522     {
5523         return errored;
5524     }
5525 
5526   private:
5527     /*!
5528     @invariant If the ref stack is empty, then the passed value will be the new
5529                root.
5530     @invariant If the ref stack contains a value, then it is an array or an
5531                object to which we can add elements
5532     */
5533     template<typename Value>
5534     JSON_HEDLEY_RETURNS_NON_NULL
handle_value(Value && v)5535     BasicJsonType* handle_value(Value&& v)
5536     {
5537         if (ref_stack.empty())
5538         {
5539             root = BasicJsonType(std::forward<Value>(v));
5540             return &root;
5541         }
5542 
5543         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5544 
5545         if (ref_stack.back()->is_array())
5546         {
5547             ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
5548             return &(ref_stack.back()->m_value.array->back());
5549         }
5550 
5551         JSON_ASSERT(ref_stack.back()->is_object());
5552         JSON_ASSERT(object_element);
5553         *object_element = BasicJsonType(std::forward<Value>(v));
5554         return object_element;
5555     }
5556 
5557     /// the parsed JSON value
5558     BasicJsonType& root;
5559     /// stack to model hierarchy of values
5560     std::vector<BasicJsonType*> ref_stack {};
5561     /// helper to hold the reference for the next object element
5562     BasicJsonType* object_element = nullptr;
5563     /// whether a syntax error occurred
5564     bool errored = false;
5565     /// whether to throw exceptions in case of errors
5566     const bool allow_exceptions = true;
5567 };
5568 
5569 template<typename BasicJsonType>
5570 class json_sax_dom_callback_parser
5571 {
5572   public:
5573     using number_integer_t = typename BasicJsonType::number_integer_t;
5574     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5575     using number_float_t = typename BasicJsonType::number_float_t;
5576     using string_t = typename BasicJsonType::string_t;
5577     using binary_t = typename BasicJsonType::binary_t;
5578     using parser_callback_t = typename BasicJsonType::parser_callback_t;
5579     using parse_event_t = typename BasicJsonType::parse_event_t;
5580 
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)5581     json_sax_dom_callback_parser(BasicJsonType& r,
5582                                  const parser_callback_t cb,
5583                                  const bool allow_exceptions_ = true)
5584         : root(r), callback(cb), allow_exceptions(allow_exceptions_)
5585     {
5586         keep_stack.push_back(true);
5587     }
5588 
5589     // make class move-only
5590     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
5591     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
5592     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
5593     json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
5594     ~json_sax_dom_callback_parser() = default;
5595 
null()5596     bool null()
5597     {
5598         handle_value(nullptr);
5599         return true;
5600     }
5601 
boolean(bool val)5602     bool boolean(bool val)
5603     {
5604         handle_value(val);
5605         return true;
5606     }
5607 
number_integer(number_integer_t val)5608     bool number_integer(number_integer_t val)
5609     {
5610         handle_value(val);
5611         return true;
5612     }
5613 
number_unsigned(number_unsigned_t val)5614     bool number_unsigned(number_unsigned_t val)
5615     {
5616         handle_value(val);
5617         return true;
5618     }
5619 
number_float(number_float_t val,const string_t &)5620     bool number_float(number_float_t val, const string_t& /*unused*/)
5621     {
5622         handle_value(val);
5623         return true;
5624     }
5625 
string(string_t & val)5626     bool string(string_t& val)
5627     {
5628         handle_value(val);
5629         return true;
5630     }
5631 
binary(binary_t & val)5632     bool binary(binary_t& val)
5633     {
5634         handle_value(std::move(val));
5635         return true;
5636     }
5637 
start_object(std::size_t len)5638     bool start_object(std::size_t len)
5639     {
5640         // check callback for object start
5641         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
5642         keep_stack.push_back(keep);
5643 
5644         auto val = handle_value(BasicJsonType::value_t::object, true);
5645         ref_stack.push_back(val.second);
5646 
5647         // check object limit
5648         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5649         {
5650             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
5651         }
5652 
5653         return true;
5654     }
5655 
key(string_t & val)5656     bool key(string_t& val)
5657     {
5658         BasicJsonType k = BasicJsonType(val);
5659 
5660         // check callback for key
5661         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
5662         key_keep_stack.push_back(keep);
5663 
5664         // add discarded value at given key and store the reference for later
5665         if (keep && ref_stack.back())
5666         {
5667             object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
5668         }
5669 
5670         return true;
5671     }
5672 
end_object()5673     bool end_object()
5674     {
5675         if (ref_stack.back() && !callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
5676         {
5677             // discard object
5678             *ref_stack.back() = discarded;
5679         }
5680 
5681         JSON_ASSERT(!ref_stack.empty());
5682         JSON_ASSERT(!keep_stack.empty());
5683         ref_stack.pop_back();
5684         keep_stack.pop_back();
5685 
5686         if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
5687         {
5688             // remove discarded value
5689             for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
5690             {
5691                 if (it->is_discarded())
5692                 {
5693                     ref_stack.back()->erase(it);
5694                     break;
5695                 }
5696             }
5697         }
5698 
5699         return true;
5700     }
5701 
start_array(std::size_t len)5702     bool start_array(std::size_t len)
5703     {
5704         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
5705         keep_stack.push_back(keep);
5706 
5707         auto val = handle_value(BasicJsonType::value_t::array, true);
5708         ref_stack.push_back(val.second);
5709 
5710         // check array limit
5711         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
5712         {
5713             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
5714         }
5715 
5716         return true;
5717     }
5718 
end_array()5719     bool end_array()
5720     {
5721         bool keep = true;
5722 
5723         if (ref_stack.back())
5724         {
5725             keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
5726             if (!keep)
5727             {
5728                 // discard array
5729                 *ref_stack.back() = discarded;
5730             }
5731         }
5732 
5733         JSON_ASSERT(!ref_stack.empty());
5734         JSON_ASSERT(!keep_stack.empty());
5735         ref_stack.pop_back();
5736         keep_stack.pop_back();
5737 
5738         // remove discarded value
5739         if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
5740         {
5741             ref_stack.back()->m_value.array->pop_back();
5742         }
5743 
5744         return true;
5745     }
5746 
5747     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)5748     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5749                      const Exception& ex)
5750     {
5751         errored = true;
5752         static_cast<void>(ex);
5753         if (allow_exceptions)
5754         {
5755             JSON_THROW(ex);
5756         }
5757         return false;
5758     }
5759 
is_errored() const5760     constexpr bool is_errored() const
5761     {
5762         return errored;
5763     }
5764 
5765   private:
5766     /*!
5767     @param[in] v  value to add to the JSON value we build during parsing
5768     @param[in] skip_callback  whether we should skip calling the callback
5769                function; this is required after start_array() and
5770                start_object() SAX events, because otherwise we would call the
5771                callback function with an empty array or object, respectively.
5772 
5773     @invariant If the ref stack is empty, then the passed value will be the new
5774                root.
5775     @invariant If the ref stack contains a value, then it is an array or an
5776                object to which we can add elements
5777 
5778     @return pair of boolean (whether value should be kept) and pointer (to the
5779             passed value in the ref_stack hierarchy; nullptr if not kept)
5780     */
5781     template<typename Value>
handle_value(Value && v,const bool skip_callback=false)5782     std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
5783     {
5784         JSON_ASSERT(!keep_stack.empty());
5785 
5786         // do not handle this value if we know it would be added to a discarded
5787         // container
5788         if (!keep_stack.back())
5789         {
5790             return {false, nullptr};
5791         }
5792 
5793         // create value
5794         auto value = BasicJsonType(std::forward<Value>(v));
5795 
5796         // check callback
5797         const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
5798 
5799         // do not handle this value if we just learnt it shall be discarded
5800         if (!keep)
5801         {
5802             return {false, nullptr};
5803         }
5804 
5805         if (ref_stack.empty())
5806         {
5807             root = std::move(value);
5808             return {true, &root};
5809         }
5810 
5811         // skip this value if we already decided to skip the parent
5812         // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
5813         if (!ref_stack.back())
5814         {
5815             return {false, nullptr};
5816         }
5817 
5818         // we now only expect arrays and objects
5819         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5820 
5821         // array
5822         if (ref_stack.back()->is_array())
5823         {
5824             ref_stack.back()->m_value.array->push_back(std::move(value));
5825             return {true, &(ref_stack.back()->m_value.array->back())};
5826         }
5827 
5828         // object
5829         JSON_ASSERT(ref_stack.back()->is_object());
5830         // check if we should store an element for the current key
5831         JSON_ASSERT(!key_keep_stack.empty());
5832         const bool store_element = key_keep_stack.back();
5833         key_keep_stack.pop_back();
5834 
5835         if (!store_element)
5836         {
5837             return {false, nullptr};
5838         }
5839 
5840         JSON_ASSERT(object_element);
5841         *object_element = std::move(value);
5842         return {true, object_element};
5843     }
5844 
5845     /// the parsed JSON value
5846     BasicJsonType& root;
5847     /// stack to model hierarchy of values
5848     std::vector<BasicJsonType*> ref_stack {};
5849     /// stack to manage which values to keep
5850     std::vector<bool> keep_stack {};
5851     /// stack to manage which object keys to keep
5852     std::vector<bool> key_keep_stack {};
5853     /// helper to hold the reference for the next object element
5854     BasicJsonType* object_element = nullptr;
5855     /// whether a syntax error occurred
5856     bool errored = false;
5857     /// callback function
5858     const parser_callback_t callback = nullptr;
5859     /// whether to throw exceptions in case of errors
5860     const bool allow_exceptions = true;
5861     /// a discarded value for the callback
5862     BasicJsonType discarded = BasicJsonType::value_t::discarded;
5863 };
5864 
5865 template<typename BasicJsonType>
5866 class json_sax_acceptor
5867 {
5868   public:
5869     using number_integer_t = typename BasicJsonType::number_integer_t;
5870     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5871     using number_float_t = typename BasicJsonType::number_float_t;
5872     using string_t = typename BasicJsonType::string_t;
5873     using binary_t = typename BasicJsonType::binary_t;
5874 
null()5875     bool null()
5876     {
5877         return true;
5878     }
5879 
boolean(bool)5880     bool boolean(bool /*unused*/)
5881     {
5882         return true;
5883     }
5884 
number_integer(number_integer_t)5885     bool number_integer(number_integer_t /*unused*/)
5886     {
5887         return true;
5888     }
5889 
number_unsigned(number_unsigned_t)5890     bool number_unsigned(number_unsigned_t /*unused*/)
5891     {
5892         return true;
5893     }
5894 
number_float(number_float_t,const string_t &)5895     bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
5896     {
5897         return true;
5898     }
5899 
string(string_t &)5900     bool string(string_t& /*unused*/)
5901     {
5902         return true;
5903     }
5904 
binary(binary_t &)5905     bool binary(binary_t& /*unused*/)
5906     {
5907         return true;
5908     }
5909 
start_object(std::size_t=std::size_t (-1))5910     bool start_object(std::size_t /*unused*/ = std::size_t(-1))
5911     {
5912         return true;
5913     }
5914 
key(string_t &)5915     bool key(string_t& /*unused*/)
5916     {
5917         return true;
5918     }
5919 
end_object()5920     bool end_object()
5921     {
5922         return true;
5923     }
5924 
start_array(std::size_t=std::size_t (-1))5925     bool start_array(std::size_t /*unused*/ = std::size_t(-1))
5926     {
5927         return true;
5928     }
5929 
end_array()5930     bool end_array()
5931     {
5932         return true;
5933     }
5934 
parse_error(std::size_t,const std::string &,const detail::exception &)5935     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
5936     {
5937         return false;
5938     }
5939 };
5940 }  // namespace detail
5941 
5942 }  // namespace nlohmann
5943 
5944 // #include <nlohmann/detail/input/lexer.hpp>
5945 
5946 
5947 #include <array> // array
5948 #include <clocale> // localeconv
5949 #include <cstddef> // size_t
5950 #include <cstdio> // snprintf
5951 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5952 #include <initializer_list> // initializer_list
5953 #include <string> // char_traits, string
5954 #include <utility> // move
5955 #include <vector> // vector
5956 
5957 // #include <nlohmann/detail/input/input_adapters.hpp>
5958 
5959 // #include <nlohmann/detail/input/position_t.hpp>
5960 
5961 // #include <nlohmann/detail/macro_scope.hpp>
5962 
5963 
5964 namespace nlohmann
5965 {
5966 namespace detail
5967 {
5968 ///////////
5969 // lexer //
5970 ///////////
5971 
5972 template<typename BasicJsonType>
5973 class lexer_base
5974 {
5975   public:
5976     /// token types for the parser
5977     enum class token_type
5978     {
5979         uninitialized,    ///< indicating the scanner is uninitialized
5980         literal_true,     ///< the `true` literal
5981         literal_false,    ///< the `false` literal
5982         literal_null,     ///< the `null` literal
5983         value_string,     ///< a string -- use get_string() for actual value
5984         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
5985         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
5986         value_float,      ///< an floating point number -- use get_number_float() for actual value
5987         begin_array,      ///< the character for array begin `[`
5988         begin_object,     ///< the character for object begin `{`
5989         end_array,        ///< the character for array end `]`
5990         end_object,       ///< the character for object end `}`
5991         name_separator,   ///< the name separator `:`
5992         value_separator,  ///< the value separator `,`
5993         parse_error,      ///< indicating a parse error
5994         end_of_input,     ///< indicating the end of the input buffer
5995         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
5996     };
5997 
5998     /// return name of values of type token_type (only used for errors)
5999     JSON_HEDLEY_RETURNS_NON_NULL
6000     JSON_HEDLEY_CONST
token_type_name(const token_type t)6001     static const char* token_type_name(const token_type t) noexcept
6002     {
6003         switch (t)
6004         {
6005             case token_type::uninitialized:
6006                 return "<uninitialized>";
6007             case token_type::literal_true:
6008                 return "true literal";
6009             case token_type::literal_false:
6010                 return "false literal";
6011             case token_type::literal_null:
6012                 return "null literal";
6013             case token_type::value_string:
6014                 return "string literal";
6015             case token_type::value_unsigned:
6016             case token_type::value_integer:
6017             case token_type::value_float:
6018                 return "number literal";
6019             case token_type::begin_array:
6020                 return "'['";
6021             case token_type::begin_object:
6022                 return "'{'";
6023             case token_type::end_array:
6024                 return "']'";
6025             case token_type::end_object:
6026                 return "'}'";
6027             case token_type::name_separator:
6028                 return "':'";
6029             case token_type::value_separator:
6030                 return "','";
6031             case token_type::parse_error:
6032                 return "<parse error>";
6033             case token_type::end_of_input:
6034                 return "end of input";
6035             case token_type::literal_or_value:
6036                 return "'[', '{', or a literal";
6037             // LCOV_EXCL_START
6038             default: // catch non-enum values
6039                 return "unknown token";
6040                 // LCOV_EXCL_STOP
6041         }
6042     }
6043 };
6044 /*!
6045 @brief lexical analysis
6046 
6047 This class organizes the lexical analysis during JSON deserialization.
6048 */
6049 template<typename BasicJsonType, typename InputAdapterType>
6050 class lexer : public lexer_base<BasicJsonType>
6051 {
6052     using number_integer_t = typename BasicJsonType::number_integer_t;
6053     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6054     using number_float_t = typename BasicJsonType::number_float_t;
6055     using string_t = typename BasicJsonType::string_t;
6056     using char_type = typename InputAdapterType::char_type;
6057     using char_int_type = typename std::char_traits<char_type>::int_type;
6058 
6059   public:
6060     using token_type = typename lexer_base<BasicJsonType>::token_type;
6061 
lexer(InputAdapterType && adapter,bool ignore_comments_=false)6062     explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false)
6063         : ia(std::move(adapter))
6064         , ignore_comments(ignore_comments_)
6065         , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6066     {}
6067 
6068     // delete because of pointer members
6069     lexer(const lexer&) = delete;
6070     lexer(lexer&&) = default;
6071     lexer& operator=(lexer&) = delete;
6072     lexer& operator=(lexer&&) = default;
6073     ~lexer() = default;
6074 
6075   private:
6076     /////////////////////
6077     // locales
6078     /////////////////////
6079 
6080     /// return the locale-dependent decimal point
6081     JSON_HEDLEY_PURE
get_decimal_point()6082     static char get_decimal_point() noexcept
6083     {
6084         const auto* loc = localeconv();
6085         JSON_ASSERT(loc != nullptr);
6086         return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6087     }
6088 
6089     /////////////////////
6090     // scan functions
6091     /////////////////////
6092 
6093     /*!
6094     @brief get codepoint from 4 hex characters following `\u`
6095 
6096     For input "\u c1 c2 c3 c4" the codepoint is:
6097       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6098     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6099 
6100     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6101     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6102     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6103     between the ASCII value of the character and the desired integer value.
6104 
6105     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6106             non-hex character)
6107     */
get_codepoint()6108     int get_codepoint()
6109     {
6110         // this function only makes sense after reading `\u`
6111         JSON_ASSERT(current == 'u');
6112         int codepoint = 0;
6113 
6114         const auto factors = { 12u, 8u, 4u, 0u };
6115         for (const auto factor : factors)
6116         {
6117             get();
6118 
6119             if (current >= '0' && current <= '9')
6120             {
6121                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6122             }
6123             else if (current >= 'A' && current <= 'F')
6124             {
6125                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6126             }
6127             else if (current >= 'a' && current <= 'f')
6128             {
6129                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6130             }
6131             else
6132             {
6133                 return -1;
6134             }
6135         }
6136 
6137         JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6138         return codepoint;
6139     }
6140 
6141     /*!
6142     @brief check if the next byte(s) are inside a given range
6143 
6144     Adds the current byte and, for each passed range, reads a new byte and
6145     checks if it is inside the range. If a violation was detected, set up an
6146     error message and return false. Otherwise, return true.
6147 
6148     @param[in] ranges  list of integers; interpreted as list of pairs of
6149                        inclusive lower and upper bound, respectively
6150 
6151     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6152          1, 2, or 3 pairs. This precondition is enforced by an assertion.
6153 
6154     @return true if and only if no range violation was detected
6155     */
next_byte_in_range(std::initializer_list<char_int_type> ranges)6156     bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6157     {
6158         JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6159         add(current);
6160 
6161         for (auto range = ranges.begin(); range != ranges.end(); ++range)
6162         {
6163             get();
6164             if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6165             {
6166                 add(current);
6167             }
6168             else
6169             {
6170                 error_message = "invalid string: ill-formed UTF-8 byte";
6171                 return false;
6172             }
6173         }
6174 
6175         return true;
6176     }
6177 
6178     /*!
6179     @brief scan a string literal
6180 
6181     This function scans a string according to Sect. 7 of RFC 7159. While
6182     scanning, bytes are escaped and copied into buffer token_buffer. Then the
6183     function returns successfully, token_buffer is *not* null-terminated (as it
6184     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6185     string.
6186 
6187     @return token_type::value_string if string could be successfully scanned,
6188             token_type::parse_error otherwise
6189 
6190     @note In case of errors, variable error_message contains a textual
6191           description.
6192     */
scan_string()6193     token_type scan_string()
6194     {
6195         // reset token_buffer (ignore opening quote)
6196         reset();
6197 
6198         // we entered the function by reading an open quote
6199         JSON_ASSERT(current == '\"');
6200 
6201         while (true)
6202         {
6203             // get next character
6204             switch (get())
6205             {
6206                 // end of file while parsing string
6207                 case std::char_traits<char_type>::eof():
6208                 {
6209                     error_message = "invalid string: missing closing quote";
6210                     return token_type::parse_error;
6211                 }
6212 
6213                 // closing quote
6214                 case '\"':
6215                 {
6216                     return token_type::value_string;
6217                 }
6218 
6219                 // escapes
6220                 case '\\':
6221                 {
6222                     switch (get())
6223                     {
6224                         // quotation mark
6225                         case '\"':
6226                             add('\"');
6227                             break;
6228                         // reverse solidus
6229                         case '\\':
6230                             add('\\');
6231                             break;
6232                         // solidus
6233                         case '/':
6234                             add('/');
6235                             break;
6236                         // backspace
6237                         case 'b':
6238                             add('\b');
6239                             break;
6240                         // form feed
6241                         case 'f':
6242                             add('\f');
6243                             break;
6244                         // line feed
6245                         case 'n':
6246                             add('\n');
6247                             break;
6248                         // carriage return
6249                         case 'r':
6250                             add('\r');
6251                             break;
6252                         // tab
6253                         case 't':
6254                             add('\t');
6255                             break;
6256 
6257                         // unicode escapes
6258                         case 'u':
6259                         {
6260                             const int codepoint1 = get_codepoint();
6261                             int codepoint = codepoint1; // start with codepoint1
6262 
6263                             if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6264                             {
6265                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6266                                 return token_type::parse_error;
6267                             }
6268 
6269                             // check if code point is a high surrogate
6270                             if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6271                             {
6272                                 // expect next \uxxxx entry
6273                                 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6274                                 {
6275                                     const int codepoint2 = get_codepoint();
6276 
6277                                     if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6278                                     {
6279                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6280                                         return token_type::parse_error;
6281                                     }
6282 
6283                                     // check if codepoint2 is a low surrogate
6284                                     if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6285                                     {
6286                                         // overwrite codepoint
6287                                         codepoint = static_cast<int>(
6288                                                         // high surrogate occupies the most significant 22 bits
6289                                                         (static_cast<unsigned int>(codepoint1) << 10u)
6290                                                         // low surrogate occupies the least significant 15 bits
6291                                                         + static_cast<unsigned int>(codepoint2)
6292                                                         // there is still the 0xD800, 0xDC00 and 0x10000 noise
6293                                                         // in the result so we have to subtract with:
6294                                                         // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6295                                                         - 0x35FDC00u);
6296                                     }
6297                                     else
6298                                     {
6299                                         error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6300                                         return token_type::parse_error;
6301                                     }
6302                                 }
6303                                 else
6304                                 {
6305                                     error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6306                                     return token_type::parse_error;
6307                                 }
6308                             }
6309                             else
6310                             {
6311                                 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6312                                 {
6313                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6314                                     return token_type::parse_error;
6315                                 }
6316                             }
6317 
6318                             // result of the above calculation yields a proper codepoint
6319                             JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6320 
6321                             // translate codepoint into bytes
6322                             if (codepoint < 0x80)
6323                             {
6324                                 // 1-byte characters: 0xxxxxxx (ASCII)
6325                                 add(static_cast<char_int_type>(codepoint));
6326                             }
6327                             else if (codepoint <= 0x7FF)
6328                             {
6329                                 // 2-byte characters: 110xxxxx 10xxxxxx
6330                                 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6331                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6332                             }
6333                             else if (codepoint <= 0xFFFF)
6334                             {
6335                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6336                                 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6337                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6338                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6339                             }
6340                             else
6341                             {
6342                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6343                                 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6344                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6345                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6346                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6347                             }
6348 
6349                             break;
6350                         }
6351 
6352                         // other characters after escape
6353                         default:
6354                             error_message = "invalid string: forbidden character after backslash";
6355                             return token_type::parse_error;
6356                     }
6357 
6358                     break;
6359                 }
6360 
6361                 // invalid control characters
6362                 case 0x00:
6363                 {
6364                     error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6365                     return token_type::parse_error;
6366                 }
6367 
6368                 case 0x01:
6369                 {
6370                     error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6371                     return token_type::parse_error;
6372                 }
6373 
6374                 case 0x02:
6375                 {
6376                     error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6377                     return token_type::parse_error;
6378                 }
6379 
6380                 case 0x03:
6381                 {
6382                     error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6383                     return token_type::parse_error;
6384                 }
6385 
6386                 case 0x04:
6387                 {
6388                     error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6389                     return token_type::parse_error;
6390                 }
6391 
6392                 case 0x05:
6393                 {
6394                     error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6395                     return token_type::parse_error;
6396                 }
6397 
6398                 case 0x06:
6399                 {
6400                     error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6401                     return token_type::parse_error;
6402                 }
6403 
6404                 case 0x07:
6405                 {
6406                     error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6407                     return token_type::parse_error;
6408                 }
6409 
6410                 case 0x08:
6411                 {
6412                     error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6413                     return token_type::parse_error;
6414                 }
6415 
6416                 case 0x09:
6417                 {
6418                     error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6419                     return token_type::parse_error;
6420                 }
6421 
6422                 case 0x0A:
6423                 {
6424                     error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6425                     return token_type::parse_error;
6426                 }
6427 
6428                 case 0x0B:
6429                 {
6430                     error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6431                     return token_type::parse_error;
6432                 }
6433 
6434                 case 0x0C:
6435                 {
6436                     error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6437                     return token_type::parse_error;
6438                 }
6439 
6440                 case 0x0D:
6441                 {
6442                     error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6443                     return token_type::parse_error;
6444                 }
6445 
6446                 case 0x0E:
6447                 {
6448                     error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6449                     return token_type::parse_error;
6450                 }
6451 
6452                 case 0x0F:
6453                 {
6454                     error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6455                     return token_type::parse_error;
6456                 }
6457 
6458                 case 0x10:
6459                 {
6460                     error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6461                     return token_type::parse_error;
6462                 }
6463 
6464                 case 0x11:
6465                 {
6466                     error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6467                     return token_type::parse_error;
6468                 }
6469 
6470                 case 0x12:
6471                 {
6472                     error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6473                     return token_type::parse_error;
6474                 }
6475 
6476                 case 0x13:
6477                 {
6478                     error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6479                     return token_type::parse_error;
6480                 }
6481 
6482                 case 0x14:
6483                 {
6484                     error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6485                     return token_type::parse_error;
6486                 }
6487 
6488                 case 0x15:
6489                 {
6490                     error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6491                     return token_type::parse_error;
6492                 }
6493 
6494                 case 0x16:
6495                 {
6496                     error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6497                     return token_type::parse_error;
6498                 }
6499 
6500                 case 0x17:
6501                 {
6502                     error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6503                     return token_type::parse_error;
6504                 }
6505 
6506                 case 0x18:
6507                 {
6508                     error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6509                     return token_type::parse_error;
6510                 }
6511 
6512                 case 0x19:
6513                 {
6514                     error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6515                     return token_type::parse_error;
6516                 }
6517 
6518                 case 0x1A:
6519                 {
6520                     error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6521                     return token_type::parse_error;
6522                 }
6523 
6524                 case 0x1B:
6525                 {
6526                     error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6527                     return token_type::parse_error;
6528                 }
6529 
6530                 case 0x1C:
6531                 {
6532                     error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6533                     return token_type::parse_error;
6534                 }
6535 
6536                 case 0x1D:
6537                 {
6538                     error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6539                     return token_type::parse_error;
6540                 }
6541 
6542                 case 0x1E:
6543                 {
6544                     error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6545                     return token_type::parse_error;
6546                 }
6547 
6548                 case 0x1F:
6549                 {
6550                     error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6551                     return token_type::parse_error;
6552                 }
6553 
6554                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6555                 case 0x20:
6556                 case 0x21:
6557                 case 0x23:
6558                 case 0x24:
6559                 case 0x25:
6560                 case 0x26:
6561                 case 0x27:
6562                 case 0x28:
6563                 case 0x29:
6564                 case 0x2A:
6565                 case 0x2B:
6566                 case 0x2C:
6567                 case 0x2D:
6568                 case 0x2E:
6569                 case 0x2F:
6570                 case 0x30:
6571                 case 0x31:
6572                 case 0x32:
6573                 case 0x33:
6574                 case 0x34:
6575                 case 0x35:
6576                 case 0x36:
6577                 case 0x37:
6578                 case 0x38:
6579                 case 0x39:
6580                 case 0x3A:
6581                 case 0x3B:
6582                 case 0x3C:
6583                 case 0x3D:
6584                 case 0x3E:
6585                 case 0x3F:
6586                 case 0x40:
6587                 case 0x41:
6588                 case 0x42:
6589                 case 0x43:
6590                 case 0x44:
6591                 case 0x45:
6592                 case 0x46:
6593                 case 0x47:
6594                 case 0x48:
6595                 case 0x49:
6596                 case 0x4A:
6597                 case 0x4B:
6598                 case 0x4C:
6599                 case 0x4D:
6600                 case 0x4E:
6601                 case 0x4F:
6602                 case 0x50:
6603                 case 0x51:
6604                 case 0x52:
6605                 case 0x53:
6606                 case 0x54:
6607                 case 0x55:
6608                 case 0x56:
6609                 case 0x57:
6610                 case 0x58:
6611                 case 0x59:
6612                 case 0x5A:
6613                 case 0x5B:
6614                 case 0x5D:
6615                 case 0x5E:
6616                 case 0x5F:
6617                 case 0x60:
6618                 case 0x61:
6619                 case 0x62:
6620                 case 0x63:
6621                 case 0x64:
6622                 case 0x65:
6623                 case 0x66:
6624                 case 0x67:
6625                 case 0x68:
6626                 case 0x69:
6627                 case 0x6A:
6628                 case 0x6B:
6629                 case 0x6C:
6630                 case 0x6D:
6631                 case 0x6E:
6632                 case 0x6F:
6633                 case 0x70:
6634                 case 0x71:
6635                 case 0x72:
6636                 case 0x73:
6637                 case 0x74:
6638                 case 0x75:
6639                 case 0x76:
6640                 case 0x77:
6641                 case 0x78:
6642                 case 0x79:
6643                 case 0x7A:
6644                 case 0x7B:
6645                 case 0x7C:
6646                 case 0x7D:
6647                 case 0x7E:
6648                 case 0x7F:
6649                 {
6650                     add(current);
6651                     break;
6652                 }
6653 
6654                 // U+0080..U+07FF: bytes C2..DF 80..BF
6655                 case 0xC2:
6656                 case 0xC3:
6657                 case 0xC4:
6658                 case 0xC5:
6659                 case 0xC6:
6660                 case 0xC7:
6661                 case 0xC8:
6662                 case 0xC9:
6663                 case 0xCA:
6664                 case 0xCB:
6665                 case 0xCC:
6666                 case 0xCD:
6667                 case 0xCE:
6668                 case 0xCF:
6669                 case 0xD0:
6670                 case 0xD1:
6671                 case 0xD2:
6672                 case 0xD3:
6673                 case 0xD4:
6674                 case 0xD5:
6675                 case 0xD6:
6676                 case 0xD7:
6677                 case 0xD8:
6678                 case 0xD9:
6679                 case 0xDA:
6680                 case 0xDB:
6681                 case 0xDC:
6682                 case 0xDD:
6683                 case 0xDE:
6684                 case 0xDF:
6685                 {
6686                     if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
6687                     {
6688                         return token_type::parse_error;
6689                     }
6690                     break;
6691                 }
6692 
6693                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6694                 case 0xE0:
6695                 {
6696                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6697                     {
6698                         return token_type::parse_error;
6699                     }
6700                     break;
6701                 }
6702 
6703                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6704                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6705                 case 0xE1:
6706                 case 0xE2:
6707                 case 0xE3:
6708                 case 0xE4:
6709                 case 0xE5:
6710                 case 0xE6:
6711                 case 0xE7:
6712                 case 0xE8:
6713                 case 0xE9:
6714                 case 0xEA:
6715                 case 0xEB:
6716                 case 0xEC:
6717                 case 0xEE:
6718                 case 0xEF:
6719                 {
6720                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6721                     {
6722                         return token_type::parse_error;
6723                     }
6724                     break;
6725                 }
6726 
6727                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6728                 case 0xED:
6729                 {
6730                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6731                     {
6732                         return token_type::parse_error;
6733                     }
6734                     break;
6735                 }
6736 
6737                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6738                 case 0xF0:
6739                 {
6740                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6741                     {
6742                         return token_type::parse_error;
6743                     }
6744                     break;
6745                 }
6746 
6747                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6748                 case 0xF1:
6749                 case 0xF2:
6750                 case 0xF3:
6751                 {
6752                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6753                     {
6754                         return token_type::parse_error;
6755                     }
6756                     break;
6757                 }
6758 
6759                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6760                 case 0xF4:
6761                 {
6762                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6763                     {
6764                         return token_type::parse_error;
6765                     }
6766                     break;
6767                 }
6768 
6769                 // remaining bytes (80..C1 and F5..FF) are ill-formed
6770                 default:
6771                 {
6772                     error_message = "invalid string: ill-formed UTF-8 byte";
6773                     return token_type::parse_error;
6774                 }
6775             }
6776         }
6777     }
6778 
6779     /*!
6780      * @brief scan a comment
6781      * @return whether comment could be scanned successfully
6782      */
scan_comment()6783     bool scan_comment()
6784     {
6785         switch (get())
6786         {
6787             // single-line comments skip input until a newline or EOF is read
6788             case '/':
6789             {
6790                 while (true)
6791                 {
6792                     switch (get())
6793                     {
6794                         case '\n':
6795                         case '\r':
6796                         case std::char_traits<char_type>::eof():
6797                         case '\0':
6798                             return true;
6799 
6800                         default:
6801                             break;
6802                     }
6803                 }
6804             }
6805 
6806             // multi-line comments skip input until */ is read
6807             case '*':
6808             {
6809                 while (true)
6810                 {
6811                     switch (get())
6812                     {
6813                         case std::char_traits<char_type>::eof():
6814                         case '\0':
6815                         {
6816                             error_message = "invalid comment; missing closing '*/'";
6817                             return false;
6818                         }
6819 
6820                         case '*':
6821                         {
6822                             switch (get())
6823                             {
6824                                 case '/':
6825                                     return true;
6826 
6827                                 default:
6828                                 {
6829                                     unget();
6830                                     continue;
6831                                 }
6832                             }
6833                         }
6834 
6835                         default:
6836                             continue;
6837                     }
6838                 }
6839             }
6840 
6841             // unexpected character after reading '/'
6842             default:
6843             {
6844                 error_message = "invalid comment; expecting '/' or '*' after '/'";
6845                 return false;
6846             }
6847         }
6848     }
6849 
6850     JSON_HEDLEY_NON_NULL(2)
strtof(float & f,const char * str,char ** endptr)6851     static void strtof(float& f, const char* str, char** endptr) noexcept
6852     {
6853         f = std::strtof(str, endptr);
6854     }
6855 
6856     JSON_HEDLEY_NON_NULL(2)
strtof(double & f,const char * str,char ** endptr)6857     static void strtof(double& f, const char* str, char** endptr) noexcept
6858     {
6859         f = std::strtod(str, endptr);
6860     }
6861 
6862     JSON_HEDLEY_NON_NULL(2)
strtof(long double & f,const char * str,char ** endptr)6863     static void strtof(long double& f, const char* str, char** endptr) noexcept
6864     {
6865         f = std::strtold(str, endptr);
6866     }
6867 
6868     /*!
6869     @brief scan a number literal
6870 
6871     This function scans a string according to Sect. 6 of RFC 7159.
6872 
6873     The function is realized with a deterministic finite state machine derived
6874     from the grammar described in RFC 7159. Starting in state "init", the
6875     input is read and used to determined the next state. Only state "done"
6876     accepts the number. State "error" is a trap state to model errors. In the
6877     table below, "anything" means any character but the ones listed before.
6878 
6879     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
6880     ---------|----------|----------|----------|---------|---------|----------|-----------
6881     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
6882     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
6883     zero     | done     | done     | exponent | done    | done    | decimal1 | done
6884     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
6885     decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
6886     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
6887     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
6888     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
6889     any2     | any2     | any2     | done     | done    | done    | done     | done
6890 
6891     The state machine is realized with one label per state (prefixed with
6892     "scan_number_") and `goto` statements between them. The state machine
6893     contains cycles, but any cycle can be left when EOF is read. Therefore,
6894     the function is guaranteed to terminate.
6895 
6896     During scanning, the read bytes are stored in token_buffer. This string is
6897     then converted to a signed integer, an unsigned integer, or a
6898     floating-point number.
6899 
6900     @return token_type::value_unsigned, token_type::value_integer, or
6901             token_type::value_float if number could be successfully scanned,
6902             token_type::parse_error otherwise
6903 
6904     @note The scanner is independent of the current locale. Internally, the
6905           locale's decimal point is used instead of `.` to work with the
6906           locale-dependent converters.
6907     */
scan_number()6908     token_type scan_number()  // lgtm [cpp/use-of-goto]
6909     {
6910         // reset token_buffer to store the number's bytes
6911         reset();
6912 
6913         // the type of the parsed number; initially set to unsigned; will be
6914         // changed if minus sign, decimal point or exponent is read
6915         token_type number_type = token_type::value_unsigned;
6916 
6917         // state (init): we just found out we need to scan a number
6918         switch (current)
6919         {
6920             case '-':
6921             {
6922                 add(current);
6923                 goto scan_number_minus;
6924             }
6925 
6926             case '0':
6927             {
6928                 add(current);
6929                 goto scan_number_zero;
6930             }
6931 
6932             case '1':
6933             case '2':
6934             case '3':
6935             case '4':
6936             case '5':
6937             case '6':
6938             case '7':
6939             case '8':
6940             case '9':
6941             {
6942                 add(current);
6943                 goto scan_number_any1;
6944             }
6945 
6946             // all other characters are rejected outside scan_number()
6947             default:            // LCOV_EXCL_LINE
6948                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
6949         }
6950 
6951 scan_number_minus:
6952         // state: we just parsed a leading minus sign
6953         number_type = token_type::value_integer;
6954         switch (get())
6955         {
6956             case '0':
6957             {
6958                 add(current);
6959                 goto scan_number_zero;
6960             }
6961 
6962             case '1':
6963             case '2':
6964             case '3':
6965             case '4':
6966             case '5':
6967             case '6':
6968             case '7':
6969             case '8':
6970             case '9':
6971             {
6972                 add(current);
6973                 goto scan_number_any1;
6974             }
6975 
6976             default:
6977             {
6978                 error_message = "invalid number; expected digit after '-'";
6979                 return token_type::parse_error;
6980             }
6981         }
6982 
6983 scan_number_zero:
6984         // state: we just parse a zero (maybe with a leading minus sign)
6985         switch (get())
6986         {
6987             case '.':
6988             {
6989                 add(decimal_point_char);
6990                 goto scan_number_decimal1;
6991             }
6992 
6993             case 'e':
6994             case 'E':
6995             {
6996                 add(current);
6997                 goto scan_number_exponent;
6998             }
6999 
7000             default:
7001                 goto scan_number_done;
7002         }
7003 
7004 scan_number_any1:
7005         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7006         switch (get())
7007         {
7008             case '0':
7009             case '1':
7010             case '2':
7011             case '3':
7012             case '4':
7013             case '5':
7014             case '6':
7015             case '7':
7016             case '8':
7017             case '9':
7018             {
7019                 add(current);
7020                 goto scan_number_any1;
7021             }
7022 
7023             case '.':
7024             {
7025                 add(decimal_point_char);
7026                 goto scan_number_decimal1;
7027             }
7028 
7029             case 'e':
7030             case 'E':
7031             {
7032                 add(current);
7033                 goto scan_number_exponent;
7034             }
7035 
7036             default:
7037                 goto scan_number_done;
7038         }
7039 
7040 scan_number_decimal1:
7041         // state: we just parsed a decimal point
7042         number_type = token_type::value_float;
7043         switch (get())
7044         {
7045             case '0':
7046             case '1':
7047             case '2':
7048             case '3':
7049             case '4':
7050             case '5':
7051             case '6':
7052             case '7':
7053             case '8':
7054             case '9':
7055             {
7056                 add(current);
7057                 goto scan_number_decimal2;
7058             }
7059 
7060             default:
7061             {
7062                 error_message = "invalid number; expected digit after '.'";
7063                 return token_type::parse_error;
7064             }
7065         }
7066 
7067 scan_number_decimal2:
7068         // we just parsed at least one number after a decimal point
7069         switch (get())
7070         {
7071             case '0':
7072             case '1':
7073             case '2':
7074             case '3':
7075             case '4':
7076             case '5':
7077             case '6':
7078             case '7':
7079             case '8':
7080             case '9':
7081             {
7082                 add(current);
7083                 goto scan_number_decimal2;
7084             }
7085 
7086             case 'e':
7087             case 'E':
7088             {
7089                 add(current);
7090                 goto scan_number_exponent;
7091             }
7092 
7093             default:
7094                 goto scan_number_done;
7095         }
7096 
7097 scan_number_exponent:
7098         // we just parsed an exponent
7099         number_type = token_type::value_float;
7100         switch (get())
7101         {
7102             case '+':
7103             case '-':
7104             {
7105                 add(current);
7106                 goto scan_number_sign;
7107             }
7108 
7109             case '0':
7110             case '1':
7111             case '2':
7112             case '3':
7113             case '4':
7114             case '5':
7115             case '6':
7116             case '7':
7117             case '8':
7118             case '9':
7119             {
7120                 add(current);
7121                 goto scan_number_any2;
7122             }
7123 
7124             default:
7125             {
7126                 error_message =
7127                     "invalid number; expected '+', '-', or digit after exponent";
7128                 return token_type::parse_error;
7129             }
7130         }
7131 
7132 scan_number_sign:
7133         // we just parsed an exponent sign
7134         switch (get())
7135         {
7136             case '0':
7137             case '1':
7138             case '2':
7139             case '3':
7140             case '4':
7141             case '5':
7142             case '6':
7143             case '7':
7144             case '8':
7145             case '9':
7146             {
7147                 add(current);
7148                 goto scan_number_any2;
7149             }
7150 
7151             default:
7152             {
7153                 error_message = "invalid number; expected digit after exponent sign";
7154                 return token_type::parse_error;
7155             }
7156         }
7157 
7158 scan_number_any2:
7159         // we just parsed a number after the exponent or exponent sign
7160         switch (get())
7161         {
7162             case '0':
7163             case '1':
7164             case '2':
7165             case '3':
7166             case '4':
7167             case '5':
7168             case '6':
7169             case '7':
7170             case '8':
7171             case '9':
7172             {
7173                 add(current);
7174                 goto scan_number_any2;
7175             }
7176 
7177             default:
7178                 goto scan_number_done;
7179         }
7180 
7181 scan_number_done:
7182         // unget the character after the number (we only read it to know that
7183         // we are done scanning a number)
7184         unget();
7185 
7186         char* endptr = nullptr;
7187         errno = 0;
7188 
7189         // try to parse integers first and fall back to floats
7190         if (number_type == token_type::value_unsigned)
7191         {
7192             const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7193 
7194             // we checked the number format before
7195             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7196 
7197             if (errno == 0)
7198             {
7199                 value_unsigned = static_cast<number_unsigned_t>(x);
7200                 if (value_unsigned == x)
7201                 {
7202                     return token_type::value_unsigned;
7203                 }
7204             }
7205         }
7206         else if (number_type == token_type::value_integer)
7207         {
7208             const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7209 
7210             // we checked the number format before
7211             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7212 
7213             if (errno == 0)
7214             {
7215                 value_integer = static_cast<number_integer_t>(x);
7216                 if (value_integer == x)
7217                 {
7218                     return token_type::value_integer;
7219                 }
7220             }
7221         }
7222 
7223         // this code is reached if we parse a floating-point number or if an
7224         // integer conversion above failed
7225         strtof(value_float, token_buffer.data(), &endptr);
7226 
7227         // we checked the number format before
7228         JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7229 
7230         return token_type::value_float;
7231     }
7232 
7233     /*!
7234     @param[in] literal_text  the literal text to expect
7235     @param[in] length        the length of the passed literal text
7236     @param[in] return_type   the token type to return on success
7237     */
7238     JSON_HEDLEY_NON_NULL(2)
scan_literal(const char_type * literal_text,const std::size_t length,token_type return_type)7239     token_type scan_literal(const char_type* literal_text, const std::size_t length,
7240                             token_type return_type)
7241     {
7242         JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7243         for (std::size_t i = 1; i < length; ++i)
7244         {
7245             if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7246             {
7247                 error_message = "invalid literal";
7248                 return token_type::parse_error;
7249             }
7250         }
7251         return return_type;
7252     }
7253 
7254     /////////////////////
7255     // input management
7256     /////////////////////
7257 
7258     /// reset token_buffer; current character is beginning of token
reset()7259     void reset() noexcept
7260     {
7261         token_buffer.clear();
7262         token_string.clear();
7263         token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7264     }
7265 
7266     /*
7267     @brief get next character from the input
7268 
7269     This function provides the interface to the used input adapter. It does
7270     not throw in case the input reached EOF, but returns a
7271     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
7272     for use in error messages.
7273 
7274     @return character read from the input
7275     */
get()7276     char_int_type get()
7277     {
7278         ++position.chars_read_total;
7279         ++position.chars_read_current_line;
7280 
7281         if (next_unget)
7282         {
7283             // just reset the next_unget variable and work with current
7284             next_unget = false;
7285         }
7286         else
7287         {
7288             current = ia.get_character();
7289         }
7290 
7291         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7292         {
7293             token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7294         }
7295 
7296         if (current == '\n')
7297         {
7298             ++position.lines_read;
7299             position.chars_read_current_line = 0;
7300         }
7301 
7302         return current;
7303     }
7304 
7305     /*!
7306     @brief unget current character (read it again on next get)
7307 
7308     We implement unget by setting variable next_unget to true. The input is not
7309     changed - we just simulate ungetting by modifying chars_read_total,
7310     chars_read_current_line, and token_string. The next call to get() will
7311     behave as if the unget character is read again.
7312     */
unget()7313     void unget()
7314     {
7315         next_unget = true;
7316 
7317         --position.chars_read_total;
7318 
7319         // in case we "unget" a newline, we have to also decrement the lines_read
7320         if (position.chars_read_current_line == 0)
7321         {
7322             if (position.lines_read > 0)
7323             {
7324                 --position.lines_read;
7325             }
7326         }
7327         else
7328         {
7329             --position.chars_read_current_line;
7330         }
7331 
7332         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7333         {
7334             JSON_ASSERT(!token_string.empty());
7335             token_string.pop_back();
7336         }
7337     }
7338 
7339     /// add a character to token_buffer
add(char_int_type c)7340     void add(char_int_type c)
7341     {
7342         token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7343     }
7344 
7345   public:
7346     /////////////////////
7347     // value getters
7348     /////////////////////
7349 
7350     /// return integer value
get_number_integer() const7351     constexpr number_integer_t get_number_integer() const noexcept
7352     {
7353         return value_integer;
7354     }
7355 
7356     /// return unsigned integer value
get_number_unsigned() const7357     constexpr number_unsigned_t get_number_unsigned() const noexcept
7358     {
7359         return value_unsigned;
7360     }
7361 
7362     /// return floating-point value
get_number_float() const7363     constexpr number_float_t get_number_float() const noexcept
7364     {
7365         return value_float;
7366     }
7367 
7368     /// return current string value (implicitly resets the token; useful only once)
get_string()7369     string_t& get_string()
7370     {
7371         return token_buffer;
7372     }
7373 
7374     /////////////////////
7375     // diagnostics
7376     /////////////////////
7377 
7378     /// return position of last read token
get_position() const7379     constexpr position_t get_position() const noexcept
7380     {
7381         return position;
7382     }
7383 
7384     /// return the last read token (for errors only).  Will never contain EOF
7385     /// (an arbitrary value that is not a valid char value, often -1), because
7386     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
get_token_string() const7387     std::string get_token_string() const
7388     {
7389         // escape control characters
7390         std::string result;
7391         for (const auto c : token_string)
7392         {
7393             if (static_cast<unsigned char>(c) <= '\x1F')
7394             {
7395                 // escape control characters
7396                 std::array<char, 9> cs{{}};
7397                 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
7398                 result += cs.data();
7399             }
7400             else
7401             {
7402                 // add character as is
7403                 result.push_back(static_cast<std::string::value_type>(c));
7404             }
7405         }
7406 
7407         return result;
7408     }
7409 
7410     /// return syntax error message
7411     JSON_HEDLEY_RETURNS_NON_NULL
get_error_message() const7412     constexpr const char* get_error_message() const noexcept
7413     {
7414         return error_message;
7415     }
7416 
7417     /////////////////////
7418     // actual scanner
7419     /////////////////////
7420 
7421     /*!
7422     @brief skip the UTF-8 byte order mark
7423     @return true iff there is no BOM or the correct BOM has been skipped
7424     */
skip_bom()7425     bool skip_bom()
7426     {
7427         if (get() == 0xEF)
7428         {
7429             // check if we completely parse the BOM
7430             return get() == 0xBB && get() == 0xBF;
7431         }
7432 
7433         // the first character is not the beginning of the BOM; unget it to
7434         // process is later
7435         unget();
7436         return true;
7437     }
7438 
skip_whitespace()7439     void skip_whitespace()
7440     {
7441         do
7442         {
7443             get();
7444         }
7445         while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7446     }
7447 
scan()7448     token_type scan()
7449     {
7450         // initially, skip the BOM
7451         if (position.chars_read_total == 0 && !skip_bom())
7452         {
7453             error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7454             return token_type::parse_error;
7455         }
7456 
7457         // read next character and ignore whitespace
7458         skip_whitespace();
7459 
7460         // ignore comments
7461         while (ignore_comments && current == '/')
7462         {
7463             if (!scan_comment())
7464             {
7465                 return token_type::parse_error;
7466             }
7467 
7468             // skip following whitespace
7469             skip_whitespace();
7470         }
7471 
7472         switch (current)
7473         {
7474             // structural characters
7475             case '[':
7476                 return token_type::begin_array;
7477             case ']':
7478                 return token_type::end_array;
7479             case '{':
7480                 return token_type::begin_object;
7481             case '}':
7482                 return token_type::end_object;
7483             case ':':
7484                 return token_type::name_separator;
7485             case ',':
7486                 return token_type::value_separator;
7487 
7488             // literals
7489             case 't':
7490             {
7491                 std::array<char_type, 4> true_literal = {{'t', 'r', 'u', 'e'}};
7492                 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7493             }
7494             case 'f':
7495             {
7496                 std::array<char_type, 5> false_literal = {{'f', 'a', 'l', 's', 'e'}};
7497                 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7498             }
7499             case 'n':
7500             {
7501                 std::array<char_type, 4> null_literal = {{'n', 'u', 'l', 'l'}};
7502                 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7503             }
7504 
7505             // string
7506             case '\"':
7507                 return scan_string();
7508 
7509             // number
7510             case '-':
7511             case '0':
7512             case '1':
7513             case '2':
7514             case '3':
7515             case '4':
7516             case '5':
7517             case '6':
7518             case '7':
7519             case '8':
7520             case '9':
7521                 return scan_number();
7522 
7523             // end of input (the null byte is needed when parsing from
7524             // string literals)
7525             case '\0':
7526             case std::char_traits<char_type>::eof():
7527                 return token_type::end_of_input;
7528 
7529             // error
7530             default:
7531                 error_message = "invalid literal";
7532                 return token_type::parse_error;
7533         }
7534     }
7535 
7536   private:
7537     /// input adapter
7538     InputAdapterType ia;
7539 
7540     /// whether comments should be ignored (true) or signaled as errors (false)
7541     const bool ignore_comments = false;
7542 
7543     /// the current character
7544     char_int_type current = std::char_traits<char_type>::eof();
7545 
7546     /// whether the next get() call should just return current
7547     bool next_unget = false;
7548 
7549     /// the start position of the current token
7550     position_t position {};
7551 
7552     /// raw input token string (for error messages)
7553     std::vector<char_type> token_string {};
7554 
7555     /// buffer for variable-length tokens (numbers, strings)
7556     string_t token_buffer {};
7557 
7558     /// a description of occurred lexer errors
7559     const char* error_message = "";
7560 
7561     // number values
7562     number_integer_t value_integer = 0;
7563     number_unsigned_t value_unsigned = 0;
7564     number_float_t value_float = 0;
7565 
7566     /// the decimal point
7567     const char_int_type decimal_point_char = '.';
7568 };
7569 }  // namespace detail
7570 }  // namespace nlohmann
7571 
7572 // #include <nlohmann/detail/macro_scope.hpp>
7573 
7574 // #include <nlohmann/detail/meta/is_sax.hpp>
7575 
7576 
7577 #include <cstdint> // size_t
7578 #include <utility> // declval
7579 #include <string> // string
7580 
7581 // #include <nlohmann/detail/meta/detected.hpp>
7582 
7583 // #include <nlohmann/detail/meta/type_traits.hpp>
7584 
7585 
7586 namespace nlohmann
7587 {
7588 namespace detail
7589 {
7590 template<typename T>
7591 using null_function_t = decltype(std::declval<T&>().null());
7592 
7593 template<typename T>
7594 using boolean_function_t =
7595     decltype(std::declval<T&>().boolean(std::declval<bool>()));
7596 
7597 template<typename T, typename Integer>
7598 using number_integer_function_t =
7599     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
7600 
7601 template<typename T, typename Unsigned>
7602 using number_unsigned_function_t =
7603     decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
7604 
7605 template<typename T, typename Float, typename String>
7606 using number_float_function_t = decltype(std::declval<T&>().number_float(
7607                                     std::declval<Float>(), std::declval<const String&>()));
7608 
7609 template<typename T, typename String>
7610 using string_function_t =
7611     decltype(std::declval<T&>().string(std::declval<String&>()));
7612 
7613 template<typename T, typename Binary>
7614 using binary_function_t =
7615     decltype(std::declval<T&>().binary(std::declval<Binary&>()));
7616 
7617 template<typename T>
7618 using start_object_function_t =
7619     decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
7620 
7621 template<typename T, typename String>
7622 using key_function_t =
7623     decltype(std::declval<T&>().key(std::declval<String&>()));
7624 
7625 template<typename T>
7626 using end_object_function_t = decltype(std::declval<T&>().end_object());
7627 
7628 template<typename T>
7629 using start_array_function_t =
7630     decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
7631 
7632 template<typename T>
7633 using end_array_function_t = decltype(std::declval<T&>().end_array());
7634 
7635 template<typename T, typename Exception>
7636 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
7637         std::declval<std::size_t>(), std::declval<const std::string&>(),
7638         std::declval<const Exception&>()));
7639 
7640 template<typename SAX, typename BasicJsonType>
7641 struct is_sax
7642 {
7643   private:
7644     static_assert(is_basic_json<BasicJsonType>::value,
7645                   "BasicJsonType must be of type basic_json<...>");
7646 
7647     using number_integer_t = typename BasicJsonType::number_integer_t;
7648     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7649     using number_float_t = typename BasicJsonType::number_float_t;
7650     using string_t = typename BasicJsonType::string_t;
7651     using binary_t = typename BasicJsonType::binary_t;
7652     using exception_t = typename BasicJsonType::exception;
7653 
7654   public:
7655     static constexpr bool value =
7656         is_detected_exact<bool, null_function_t, SAX>::value &&
7657         is_detected_exact<bool, boolean_function_t, SAX>::value &&
7658         is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
7659         is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
7660         is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
7661         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
7662         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
7663         is_detected_exact<bool, start_object_function_t, SAX>::value &&
7664         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
7665         is_detected_exact<bool, end_object_function_t, SAX>::value &&
7666         is_detected_exact<bool, start_array_function_t, SAX>::value &&
7667         is_detected_exact<bool, end_array_function_t, SAX>::value &&
7668         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
7669 };
7670 
7671 template<typename SAX, typename BasicJsonType>
7672 struct is_sax_static_asserts
7673 {
7674   private:
7675     static_assert(is_basic_json<BasicJsonType>::value,
7676                   "BasicJsonType must be of type basic_json<...>");
7677 
7678     using number_integer_t = typename BasicJsonType::number_integer_t;
7679     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7680     using number_float_t = typename BasicJsonType::number_float_t;
7681     using string_t = typename BasicJsonType::string_t;
7682     using binary_t = typename BasicJsonType::binary_t;
7683     using exception_t = typename BasicJsonType::exception;
7684 
7685   public:
7686     static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
7687                   "Missing/invalid function: bool null()");
7688     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7689                   "Missing/invalid function: bool boolean(bool)");
7690     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
7691                   "Missing/invalid function: bool boolean(bool)");
7692     static_assert(
7693         is_detected_exact<bool, number_integer_function_t, SAX,
7694         number_integer_t>::value,
7695         "Missing/invalid function: bool number_integer(number_integer_t)");
7696     static_assert(
7697         is_detected_exact<bool, number_unsigned_function_t, SAX,
7698         number_unsigned_t>::value,
7699         "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
7700     static_assert(is_detected_exact<bool, number_float_function_t, SAX,
7701                   number_float_t, string_t>::value,
7702                   "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
7703     static_assert(
7704         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
7705         "Missing/invalid function: bool string(string_t&)");
7706     static_assert(
7707         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
7708         "Missing/invalid function: bool binary(binary_t&)");
7709     static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
7710                   "Missing/invalid function: bool start_object(std::size_t)");
7711     static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
7712                   "Missing/invalid function: bool key(string_t&)");
7713     static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
7714                   "Missing/invalid function: bool end_object()");
7715     static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
7716                   "Missing/invalid function: bool start_array(std::size_t)");
7717     static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
7718                   "Missing/invalid function: bool end_array()");
7719     static_assert(
7720         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
7721         "Missing/invalid function: bool parse_error(std::size_t, const "
7722         "std::string&, const exception&)");
7723 };
7724 }  // namespace detail
7725 }  // namespace nlohmann
7726 
7727 // #include <nlohmann/detail/value_t.hpp>
7728 
7729 
7730 namespace nlohmann
7731 {
7732 namespace detail
7733 {
7734 
7735 /// how to treat CBOR tags
7736 enum class cbor_tag_handler_t
7737 {
7738     error,  ///< throw a parse_error exception in case of a tag
7739     ignore   ///< ignore tags
7740 };
7741 
7742 /*!
7743 @brief determine system byte order
7744 
7745 @return true if and only if system's byte order is little endian
7746 
7747 @note from https://stackoverflow.com/a/1001328/266378
7748 */
little_endianess(int num=1)7749 static inline bool little_endianess(int num = 1) noexcept
7750 {
7751     return *reinterpret_cast<char*>(&num) == 1;
7752 }
7753 
7754 
7755 ///////////////////
7756 // binary reader //
7757 ///////////////////
7758 
7759 /*!
7760 @brief deserialization of CBOR, MessagePack, and UBJSON values
7761 */
7762 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
7763 class binary_reader
7764 {
7765     using number_integer_t = typename BasicJsonType::number_integer_t;
7766     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7767     using number_float_t = typename BasicJsonType::number_float_t;
7768     using string_t = typename BasicJsonType::string_t;
7769     using binary_t = typename BasicJsonType::binary_t;
7770     using json_sax_t = SAX;
7771     using char_type = typename InputAdapterType::char_type;
7772     using char_int_type = typename std::char_traits<char_type>::int_type;
7773 
7774   public:
7775     /*!
7776     @brief create a binary reader
7777 
7778     @param[in] adapter  input adapter to read from
7779     */
binary_reader(InputAdapterType && adapter)7780     explicit binary_reader(InputAdapterType&& adapter) : ia(std::move(adapter))
7781     {
7782         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7783     }
7784 
7785     // make class move-only
7786     binary_reader(const binary_reader&) = delete;
7787     binary_reader(binary_reader&&) = default;
7788     binary_reader& operator=(const binary_reader&) = delete;
7789     binary_reader& operator=(binary_reader&&) = default;
7790     ~binary_reader() = default;
7791 
7792     /*!
7793     @param[in] format  the binary format to parse
7794     @param[in] sax_    a SAX event processor
7795     @param[in] strict  whether to expect the input to be consumed completed
7796     @param[in] tag_handler  how to treat CBOR tags
7797 
7798     @return
7799     */
7800     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)7801     bool sax_parse(const input_format_t format,
7802                    json_sax_t* sax_,
7803                    const bool strict = true,
7804                    const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
7805     {
7806         sax = sax_;
7807         bool result = false;
7808 
7809         switch (format)
7810         {
7811             case input_format_t::bson:
7812                 result = parse_bson_internal();
7813                 break;
7814 
7815             case input_format_t::cbor:
7816                 result = parse_cbor_internal(true, tag_handler);
7817                 break;
7818 
7819             case input_format_t::msgpack:
7820                 result = parse_msgpack_internal();
7821                 break;
7822 
7823             case input_format_t::ubjson:
7824                 result = parse_ubjson_internal();
7825                 break;
7826 
7827             default:            // LCOV_EXCL_LINE
7828                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
7829         }
7830 
7831         // strict mode: next byte must be EOF
7832         if (result && strict)
7833         {
7834             if (format == input_format_t::ubjson)
7835             {
7836                 get_ignore_noop();
7837             }
7838             else
7839             {
7840                 get();
7841             }
7842 
7843             if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
7844             {
7845                 return sax->parse_error(chars_read, get_token_string(),
7846                                         parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
7847             }
7848         }
7849 
7850         return result;
7851     }
7852 
7853   private:
7854     //////////
7855     // BSON //
7856     //////////
7857 
7858     /*!
7859     @brief Reads in a BSON-object and passes it to the SAX-parser.
7860     @return whether a valid BSON-value was passed to the SAX parser
7861     */
parse_bson_internal()7862     bool parse_bson_internal()
7863     {
7864         std::int32_t document_size{};
7865         get_number<std::int32_t, true>(input_format_t::bson, document_size);
7866 
7867         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
7868         {
7869             return false;
7870         }
7871 
7872         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
7873         {
7874             return false;
7875         }
7876 
7877         return sax->end_object();
7878     }
7879 
7880     /*!
7881     @brief Parses a C-style string from the BSON input.
7882     @param[in, out] result  A reference to the string variable where the read
7883                             string is to be stored.
7884     @return `true` if the \x00-byte indicating the end of the string was
7885              encountered before the EOF; false` indicates an unexpected EOF.
7886     */
get_bson_cstr(string_t & result)7887     bool get_bson_cstr(string_t& result)
7888     {
7889         auto out = std::back_inserter(result);
7890         while (true)
7891         {
7892             get();
7893             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
7894             {
7895                 return false;
7896             }
7897             if (current == 0x00)
7898             {
7899                 return true;
7900             }
7901             *out++ = static_cast<typename string_t::value_type>(current);
7902         }
7903     }
7904 
7905     /*!
7906     @brief Parses a zero-terminated string of length @a len from the BSON
7907            input.
7908     @param[in] len  The length (including the zero-byte at the end) of the
7909                     string to be read.
7910     @param[in, out] result  A reference to the string variable where the read
7911                             string is to be stored.
7912     @tparam NumberType The type of the length @a len
7913     @pre len >= 1
7914     @return `true` if the string was successfully parsed
7915     */
7916     template<typename NumberType>
get_bson_string(const NumberType len,string_t & result)7917     bool get_bson_string(const NumberType len, string_t& result)
7918     {
7919         if (JSON_HEDLEY_UNLIKELY(len < 1))
7920         {
7921             auto last_token = get_token_string();
7922             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string")));
7923         }
7924 
7925         return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
7926     }
7927 
7928     /*!
7929     @brief Parses a byte array input of length @a len from the BSON input.
7930     @param[in] len  The length of the byte array to be read.
7931     @param[in, out] result  A reference to the binary variable where the read
7932                             array is to be stored.
7933     @tparam NumberType The type of the length @a len
7934     @pre len >= 0
7935     @return `true` if the byte array was successfully parsed
7936     */
7937     template<typename NumberType>
get_bson_binary(const NumberType len,binary_t & result)7938     bool get_bson_binary(const NumberType len, binary_t& result)
7939     {
7940         if (JSON_HEDLEY_UNLIKELY(len < 0))
7941         {
7942             auto last_token = get_token_string();
7943             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary")));
7944         }
7945 
7946         // All BSON binary values have a subtype
7947         std::uint8_t subtype{};
7948         get_number<std::uint8_t>(input_format_t::bson, subtype);
7949         result.set_subtype(subtype);
7950 
7951         return get_binary(input_format_t::bson, len, result);
7952     }
7953 
7954     /*!
7955     @brief Read a BSON document element of the given @a element_type.
7956     @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
7957     @param[in] element_type_parse_position The position in the input stream,
7958                where the `element_type` was read.
7959     @warning Not all BSON element types are supported yet. An unsupported
7960              @a element_type will give rise to a parse_error.114:
7961              Unsupported BSON record type 0x...
7962     @return whether a valid BSON-object/array was passed to the SAX parser
7963     */
parse_bson_element_internal(const char_int_type element_type,const std::size_t element_type_parse_position)7964     bool parse_bson_element_internal(const char_int_type element_type,
7965                                      const std::size_t element_type_parse_position)
7966     {
7967         switch (element_type)
7968         {
7969             case 0x01: // double
7970             {
7971                 double number{};
7972                 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
7973             }
7974 
7975             case 0x02: // string
7976             {
7977                 std::int32_t len{};
7978                 string_t value;
7979                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
7980             }
7981 
7982             case 0x03: // object
7983             {
7984                 return parse_bson_internal();
7985             }
7986 
7987             case 0x04: // array
7988             {
7989                 return parse_bson_array();
7990             }
7991 
7992             case 0x05: // binary
7993             {
7994                 std::int32_t len{};
7995                 binary_t value;
7996                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
7997             }
7998 
7999             case 0x08: // boolean
8000             {
8001                 return sax->boolean(get() != 0);
8002             }
8003 
8004             case 0x0A: // null
8005             {
8006                 return sax->null();
8007             }
8008 
8009             case 0x10: // int32
8010             {
8011                 std::int32_t value{};
8012                 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8013             }
8014 
8015             case 0x12: // int64
8016             {
8017                 std::int64_t value{};
8018                 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8019             }
8020 
8021             default: // anything else not supported (yet)
8022             {
8023                 std::array<char, 3> cr{{}};
8024                 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
8025                 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data())));
8026             }
8027         }
8028     }
8029 
8030     /*!
8031     @brief Read a BSON element list (as specified in the BSON-spec)
8032 
8033     The same binary layout is used for objects and arrays, hence it must be
8034     indicated with the argument @a is_array which one is expected
8035     (true --> array, false --> object).
8036 
8037     @param[in] is_array Determines if the element list being read is to be
8038                         treated as an object (@a is_array == false), or as an
8039                         array (@a is_array == true).
8040     @return whether a valid BSON-object/array was passed to the SAX parser
8041     */
parse_bson_element_list(const bool is_array)8042     bool parse_bson_element_list(const bool is_array)
8043     {
8044         string_t key;
8045 
8046         while (auto element_type = get())
8047         {
8048             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8049             {
8050                 return false;
8051             }
8052 
8053             const std::size_t element_type_parse_position = chars_read;
8054             if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8055             {
8056                 return false;
8057             }
8058 
8059             if (!is_array && !sax->key(key))
8060             {
8061                 return false;
8062             }
8063 
8064             if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8065             {
8066                 return false;
8067             }
8068 
8069             // get_bson_cstr only appends
8070             key.clear();
8071         }
8072 
8073         return true;
8074     }
8075 
8076     /*!
8077     @brief Reads an array from the BSON input and passes it to the SAX-parser.
8078     @return whether a valid BSON-array was passed to the SAX parser
8079     */
parse_bson_array()8080     bool parse_bson_array()
8081     {
8082         std::int32_t document_size{};
8083         get_number<std::int32_t, true>(input_format_t::bson, document_size);
8084 
8085         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8086         {
8087             return false;
8088         }
8089 
8090         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8091         {
8092             return false;
8093         }
8094 
8095         return sax->end_array();
8096     }
8097 
8098     //////////
8099     // CBOR //
8100     //////////
8101 
8102     /*!
8103     @param[in] get_char  whether a new character should be retrieved from the
8104                          input (true) or whether the last read character should
8105                          be considered instead (false)
8106     @param[in] tag_handler how CBOR tags should be treated
8107 
8108     @return whether a valid CBOR value was passed to the SAX parser
8109     */
parse_cbor_internal(const bool get_char,const cbor_tag_handler_t tag_handler)8110     bool parse_cbor_internal(const bool get_char,
8111                              const cbor_tag_handler_t tag_handler)
8112     {
8113         switch (get_char ? get() : current)
8114         {
8115             // EOF
8116             case std::char_traits<char_type>::eof():
8117                 return unexpect_eof(input_format_t::cbor, "value");
8118 
8119             // Integer 0x00..0x17 (0..23)
8120             case 0x00:
8121             case 0x01:
8122             case 0x02:
8123             case 0x03:
8124             case 0x04:
8125             case 0x05:
8126             case 0x06:
8127             case 0x07:
8128             case 0x08:
8129             case 0x09:
8130             case 0x0A:
8131             case 0x0B:
8132             case 0x0C:
8133             case 0x0D:
8134             case 0x0E:
8135             case 0x0F:
8136             case 0x10:
8137             case 0x11:
8138             case 0x12:
8139             case 0x13:
8140             case 0x14:
8141             case 0x15:
8142             case 0x16:
8143             case 0x17:
8144                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8145 
8146             case 0x18: // Unsigned integer (one-byte uint8_t follows)
8147             {
8148                 std::uint8_t number{};
8149                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8150             }
8151 
8152             case 0x19: // Unsigned integer (two-byte uint16_t follows)
8153             {
8154                 std::uint16_t number{};
8155                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8156             }
8157 
8158             case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8159             {
8160                 std::uint32_t number{};
8161                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8162             }
8163 
8164             case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8165             {
8166                 std::uint64_t number{};
8167                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8168             }
8169 
8170             // Negative integer -1-0x00..-1-0x17 (-1..-24)
8171             case 0x20:
8172             case 0x21:
8173             case 0x22:
8174             case 0x23:
8175             case 0x24:
8176             case 0x25:
8177             case 0x26:
8178             case 0x27:
8179             case 0x28:
8180             case 0x29:
8181             case 0x2A:
8182             case 0x2B:
8183             case 0x2C:
8184             case 0x2D:
8185             case 0x2E:
8186             case 0x2F:
8187             case 0x30:
8188             case 0x31:
8189             case 0x32:
8190             case 0x33:
8191             case 0x34:
8192             case 0x35:
8193             case 0x36:
8194             case 0x37:
8195                 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8196 
8197             case 0x38: // Negative integer (one-byte uint8_t follows)
8198             {
8199                 std::uint8_t number{};
8200                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8201             }
8202 
8203             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8204             {
8205                 std::uint16_t number{};
8206                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8207             }
8208 
8209             case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8210             {
8211                 std::uint32_t number{};
8212                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8213             }
8214 
8215             case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8216             {
8217                 std::uint64_t number{};
8218                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8219                         - static_cast<number_integer_t>(number));
8220             }
8221 
8222             // Binary data (0x00..0x17 bytes follow)
8223             case 0x40:
8224             case 0x41:
8225             case 0x42:
8226             case 0x43:
8227             case 0x44:
8228             case 0x45:
8229             case 0x46:
8230             case 0x47:
8231             case 0x48:
8232             case 0x49:
8233             case 0x4A:
8234             case 0x4B:
8235             case 0x4C:
8236             case 0x4D:
8237             case 0x4E:
8238             case 0x4F:
8239             case 0x50:
8240             case 0x51:
8241             case 0x52:
8242             case 0x53:
8243             case 0x54:
8244             case 0x55:
8245             case 0x56:
8246             case 0x57:
8247             case 0x58: // Binary data (one-byte uint8_t for n follows)
8248             case 0x59: // Binary data (two-byte uint16_t for n follow)
8249             case 0x5A: // Binary data (four-byte uint32_t for n follow)
8250             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8251             case 0x5F: // Binary data (indefinite length)
8252             {
8253                 binary_t b;
8254                 return get_cbor_binary(b) && sax->binary(b);
8255             }
8256 
8257             // UTF-8 string (0x00..0x17 bytes follow)
8258             case 0x60:
8259             case 0x61:
8260             case 0x62:
8261             case 0x63:
8262             case 0x64:
8263             case 0x65:
8264             case 0x66:
8265             case 0x67:
8266             case 0x68:
8267             case 0x69:
8268             case 0x6A:
8269             case 0x6B:
8270             case 0x6C:
8271             case 0x6D:
8272             case 0x6E:
8273             case 0x6F:
8274             case 0x70:
8275             case 0x71:
8276             case 0x72:
8277             case 0x73:
8278             case 0x74:
8279             case 0x75:
8280             case 0x76:
8281             case 0x77:
8282             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8283             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8284             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8285             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8286             case 0x7F: // UTF-8 string (indefinite length)
8287             {
8288                 string_t s;
8289                 return get_cbor_string(s) && sax->string(s);
8290             }
8291 
8292             // array (0x00..0x17 data items follow)
8293             case 0x80:
8294             case 0x81:
8295             case 0x82:
8296             case 0x83:
8297             case 0x84:
8298             case 0x85:
8299             case 0x86:
8300             case 0x87:
8301             case 0x88:
8302             case 0x89:
8303             case 0x8A:
8304             case 0x8B:
8305             case 0x8C:
8306             case 0x8D:
8307             case 0x8E:
8308             case 0x8F:
8309             case 0x90:
8310             case 0x91:
8311             case 0x92:
8312             case 0x93:
8313             case 0x94:
8314             case 0x95:
8315             case 0x96:
8316             case 0x97:
8317                 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8318 
8319             case 0x98: // array (one-byte uint8_t for n follows)
8320             {
8321                 std::uint8_t len{};
8322                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8323             }
8324 
8325             case 0x99: // array (two-byte uint16_t for n follow)
8326             {
8327                 std::uint16_t len{};
8328                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8329             }
8330 
8331             case 0x9A: // array (four-byte uint32_t for n follow)
8332             {
8333                 std::uint32_t len{};
8334                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8335             }
8336 
8337             case 0x9B: // array (eight-byte uint64_t for n follow)
8338             {
8339                 std::uint64_t len{};
8340                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8341             }
8342 
8343             case 0x9F: // array (indefinite length)
8344                 return get_cbor_array(std::size_t(-1), tag_handler);
8345 
8346             // map (0x00..0x17 pairs of data items follow)
8347             case 0xA0:
8348             case 0xA1:
8349             case 0xA2:
8350             case 0xA3:
8351             case 0xA4:
8352             case 0xA5:
8353             case 0xA6:
8354             case 0xA7:
8355             case 0xA8:
8356             case 0xA9:
8357             case 0xAA:
8358             case 0xAB:
8359             case 0xAC:
8360             case 0xAD:
8361             case 0xAE:
8362             case 0xAF:
8363             case 0xB0:
8364             case 0xB1:
8365             case 0xB2:
8366             case 0xB3:
8367             case 0xB4:
8368             case 0xB5:
8369             case 0xB6:
8370             case 0xB7:
8371                 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8372 
8373             case 0xB8: // map (one-byte uint8_t for n follows)
8374             {
8375                 std::uint8_t len{};
8376                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8377             }
8378 
8379             case 0xB9: // map (two-byte uint16_t for n follow)
8380             {
8381                 std::uint16_t len{};
8382                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8383             }
8384 
8385             case 0xBA: // map (four-byte uint32_t for n follow)
8386             {
8387                 std::uint32_t len{};
8388                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8389             }
8390 
8391             case 0xBB: // map (eight-byte uint64_t for n follow)
8392             {
8393                 std::uint64_t len{};
8394                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8395             }
8396 
8397             case 0xBF: // map (indefinite length)
8398                 return get_cbor_object(std::size_t(-1), tag_handler);
8399 
8400             case 0xC6: // tagged item
8401             case 0xC7:
8402             case 0xC8:
8403             case 0xC9:
8404             case 0xCA:
8405             case 0xCB:
8406             case 0xCC:
8407             case 0xCD:
8408             case 0xCE:
8409             case 0xCF:
8410             case 0xD0:
8411             case 0xD1:
8412             case 0xD2:
8413             case 0xD3:
8414             case 0xD4:
8415             case 0xD8: // tagged item (1 bytes follow)
8416             case 0xD9: // tagged item (2 bytes follow)
8417             case 0xDA: // tagged item (4 bytes follow)
8418             case 0xDB: // tagged item (8 bytes follow)
8419             {
8420                 switch (tag_handler)
8421                 {
8422                     case cbor_tag_handler_t::error:
8423                     {
8424                         auto last_token = get_token_string();
8425                         return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
8426                     }
8427 
8428                     case cbor_tag_handler_t::ignore:
8429                     {
8430                         switch (current)
8431                         {
8432                             case 0xD8:
8433                             {
8434                                 std::uint8_t len{};
8435                                 get_number(input_format_t::cbor, len);
8436                                 break;
8437                             }
8438                             case 0xD9:
8439                             {
8440                                 std::uint16_t len{};
8441                                 get_number(input_format_t::cbor, len);
8442                                 break;
8443                             }
8444                             case 0xDA:
8445                             {
8446                                 std::uint32_t len{};
8447                                 get_number(input_format_t::cbor, len);
8448                                 break;
8449                             }
8450                             case 0xDB:
8451                             {
8452                                 std::uint64_t len{};
8453                                 get_number(input_format_t::cbor, len);
8454                                 break;
8455                             }
8456                             default:
8457                                 break;
8458                         }
8459                         return parse_cbor_internal(true, tag_handler);
8460                     }
8461 
8462                     default:                 // LCOV_EXCL_LINE
8463                         JSON_ASSERT(false);  // LCOV_EXCL_LINE
8464                         return false;        // LCOV_EXCL_LINE
8465                 }
8466             }
8467 
8468             case 0xF4: // false
8469                 return sax->boolean(false);
8470 
8471             case 0xF5: // true
8472                 return sax->boolean(true);
8473 
8474             case 0xF6: // null
8475                 return sax->null();
8476 
8477             case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8478             {
8479                 const auto byte1_raw = get();
8480                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8481                 {
8482                     return false;
8483                 }
8484                 const auto byte2_raw = get();
8485                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
8486                 {
8487                     return false;
8488                 }
8489 
8490                 const auto byte1 = static_cast<unsigned char>(byte1_raw);
8491                 const auto byte2 = static_cast<unsigned char>(byte2_raw);
8492 
8493                 // code from RFC 7049, Appendix D, Figure 3:
8494                 // As half-precision floating-point numbers were only added
8495                 // to IEEE 754 in 2008, today's programming platforms often
8496                 // still only have limited support for them. It is very
8497                 // easy to include at least decoding support for them even
8498                 // without such support. An example of a small decoder for
8499                 // half-precision floating-point numbers in the C language
8500                 // is shown in Fig. 3.
8501                 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
8502                 const double val = [&half]
8503                 {
8504                     const int exp = (half >> 10u) & 0x1Fu;
8505                     const unsigned int mant = half & 0x3FFu;
8506                     JSON_ASSERT(0 <= exp&& exp <= 32);
8507                     JSON_ASSERT(mant <= 1024);
8508                     switch (exp)
8509                     {
8510                         case 0:
8511                             return std::ldexp(mant, -24);
8512                         case 31:
8513                             return (mant == 0)
8514                             ? std::numeric_limits<double>::infinity()
8515                             : std::numeric_limits<double>::quiet_NaN();
8516                         default:
8517                             return std::ldexp(mant + 1024, exp - 25);
8518                     }
8519                 }();
8520                 return sax->number_float((half & 0x8000u) != 0
8521                                          ? static_cast<number_float_t>(-val)
8522                                          : static_cast<number_float_t>(val), "");
8523             }
8524 
8525             case 0xFA: // Single-Precision Float (four-byte IEEE 754)
8526             {
8527                 float number{};
8528                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8529             }
8530 
8531             case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
8532             {
8533                 double number{};
8534                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
8535             }
8536 
8537             default: // anything else (0xFF is handled inside the other types)
8538             {
8539                 auto last_token = get_token_string();
8540                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
8541             }
8542         }
8543     }
8544 
8545     /*!
8546     @brief reads a CBOR string
8547 
8548     This function first reads starting bytes to determine the expected
8549     string length and then copies this number of bytes into a string.
8550     Additionally, CBOR's strings with indefinite lengths are supported.
8551 
8552     @param[out] result  created string
8553 
8554     @return whether string creation completed
8555     */
get_cbor_string(string_t & result)8556     bool get_cbor_string(string_t& result)
8557     {
8558         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
8559         {
8560             return false;
8561         }
8562 
8563         switch (current)
8564         {
8565             // UTF-8 string (0x00..0x17 bytes follow)
8566             case 0x60:
8567             case 0x61:
8568             case 0x62:
8569             case 0x63:
8570             case 0x64:
8571             case 0x65:
8572             case 0x66:
8573             case 0x67:
8574             case 0x68:
8575             case 0x69:
8576             case 0x6A:
8577             case 0x6B:
8578             case 0x6C:
8579             case 0x6D:
8580             case 0x6E:
8581             case 0x6F:
8582             case 0x70:
8583             case 0x71:
8584             case 0x72:
8585             case 0x73:
8586             case 0x74:
8587             case 0x75:
8588             case 0x76:
8589             case 0x77:
8590             {
8591                 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8592             }
8593 
8594             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8595             {
8596                 std::uint8_t len{};
8597                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8598             }
8599 
8600             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8601             {
8602                 std::uint16_t len{};
8603                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8604             }
8605 
8606             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8607             {
8608                 std::uint32_t len{};
8609                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8610             }
8611 
8612             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8613             {
8614                 std::uint64_t len{};
8615                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
8616             }
8617 
8618             case 0x7F: // UTF-8 string (indefinite length)
8619             {
8620                 while (get() != 0xFF)
8621                 {
8622                     string_t chunk;
8623                     if (!get_cbor_string(chunk))
8624                     {
8625                         return false;
8626                     }
8627                     result.append(chunk);
8628                 }
8629                 return true;
8630             }
8631 
8632             default:
8633             {
8634                 auto last_token = get_token_string();
8635                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
8636             }
8637         }
8638     }
8639 
8640     /*!
8641     @brief reads a CBOR byte array
8642 
8643     This function first reads starting bytes to determine the expected
8644     byte array length and then copies this number of bytes into the byte array.
8645     Additionally, CBOR's byte arrays with indefinite lengths are supported.
8646 
8647     @param[out] result  created byte array
8648 
8649     @return whether byte array creation completed
8650     */
get_cbor_binary(binary_t & result)8651     bool get_cbor_binary(binary_t& result)
8652     {
8653         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
8654         {
8655             return false;
8656         }
8657 
8658         switch (current)
8659         {
8660             // Binary data (0x00..0x17 bytes follow)
8661             case 0x40:
8662             case 0x41:
8663             case 0x42:
8664             case 0x43:
8665             case 0x44:
8666             case 0x45:
8667             case 0x46:
8668             case 0x47:
8669             case 0x48:
8670             case 0x49:
8671             case 0x4A:
8672             case 0x4B:
8673             case 0x4C:
8674             case 0x4D:
8675             case 0x4E:
8676             case 0x4F:
8677             case 0x50:
8678             case 0x51:
8679             case 0x52:
8680             case 0x53:
8681             case 0x54:
8682             case 0x55:
8683             case 0x56:
8684             case 0x57:
8685             {
8686                 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
8687             }
8688 
8689             case 0x58: // Binary data (one-byte uint8_t for n follows)
8690             {
8691                 std::uint8_t len{};
8692                 return get_number(input_format_t::cbor, len) &&
8693                        get_binary(input_format_t::cbor, len, result);
8694             }
8695 
8696             case 0x59: // Binary data (two-byte uint16_t for n follow)
8697             {
8698                 std::uint16_t len{};
8699                 return get_number(input_format_t::cbor, len) &&
8700                        get_binary(input_format_t::cbor, len, result);
8701             }
8702 
8703             case 0x5A: // Binary data (four-byte uint32_t for n follow)
8704             {
8705                 std::uint32_t len{};
8706                 return get_number(input_format_t::cbor, len) &&
8707                        get_binary(input_format_t::cbor, len, result);
8708             }
8709 
8710             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8711             {
8712                 std::uint64_t len{};
8713                 return get_number(input_format_t::cbor, len) &&
8714                        get_binary(input_format_t::cbor, len, result);
8715             }
8716 
8717             case 0x5F: // Binary data (indefinite length)
8718             {
8719                 while (get() != 0xFF)
8720                 {
8721                     binary_t chunk;
8722                     if (!get_cbor_binary(chunk))
8723                     {
8724                         return false;
8725                     }
8726                     result.insert(result.end(), chunk.begin(), chunk.end());
8727                 }
8728                 return true;
8729             }
8730 
8731             default:
8732             {
8733                 auto last_token = get_token_string();
8734                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary")));
8735             }
8736         }
8737     }
8738 
8739     /*!
8740     @param[in] len  the length of the array or std::size_t(-1) for an
8741                     array of indefinite size
8742     @param[in] tag_handler how CBOR tags should be treated
8743     @return whether array creation completed
8744     */
get_cbor_array(const std::size_t len,const cbor_tag_handler_t tag_handler)8745     bool get_cbor_array(const std::size_t len,
8746                         const cbor_tag_handler_t tag_handler)
8747     {
8748         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
8749         {
8750             return false;
8751         }
8752 
8753         if (len != std::size_t(-1))
8754         {
8755             for (std::size_t i = 0; i < len; ++i)
8756             {
8757                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8758                 {
8759                     return false;
8760                 }
8761             }
8762         }
8763         else
8764         {
8765             while (get() != 0xFF)
8766             {
8767                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
8768                 {
8769                     return false;
8770                 }
8771             }
8772         }
8773 
8774         return sax->end_array();
8775     }
8776 
8777     /*!
8778     @param[in] len  the length of the object or std::size_t(-1) for an
8779                     object of indefinite size
8780     @param[in] tag_handler how CBOR tags should be treated
8781     @return whether object creation completed
8782     */
get_cbor_object(const std::size_t len,const cbor_tag_handler_t tag_handler)8783     bool get_cbor_object(const std::size_t len,
8784                          const cbor_tag_handler_t tag_handler)
8785     {
8786         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
8787         {
8788             return false;
8789         }
8790 
8791         string_t key;
8792         if (len != std::size_t(-1))
8793         {
8794             for (std::size_t i = 0; i < len; ++i)
8795             {
8796                 get();
8797                 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8798                 {
8799                     return false;
8800                 }
8801 
8802                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8803                 {
8804                     return false;
8805                 }
8806                 key.clear();
8807             }
8808         }
8809         else
8810         {
8811             while (get() != 0xFF)
8812             {
8813                 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
8814                 {
8815                     return false;
8816                 }
8817 
8818                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
8819                 {
8820                     return false;
8821                 }
8822                 key.clear();
8823             }
8824         }
8825 
8826         return sax->end_object();
8827     }
8828 
8829     /////////////
8830     // MsgPack //
8831     /////////////
8832 
8833     /*!
8834     @return whether a valid MessagePack value was passed to the SAX parser
8835     */
parse_msgpack_internal()8836     bool parse_msgpack_internal()
8837     {
8838         switch (get())
8839         {
8840             // EOF
8841             case std::char_traits<char_type>::eof():
8842                 return unexpect_eof(input_format_t::msgpack, "value");
8843 
8844             // positive fixint
8845             case 0x00:
8846             case 0x01:
8847             case 0x02:
8848             case 0x03:
8849             case 0x04:
8850             case 0x05:
8851             case 0x06:
8852             case 0x07:
8853             case 0x08:
8854             case 0x09:
8855             case 0x0A:
8856             case 0x0B:
8857             case 0x0C:
8858             case 0x0D:
8859             case 0x0E:
8860             case 0x0F:
8861             case 0x10:
8862             case 0x11:
8863             case 0x12:
8864             case 0x13:
8865             case 0x14:
8866             case 0x15:
8867             case 0x16:
8868             case 0x17:
8869             case 0x18:
8870             case 0x19:
8871             case 0x1A:
8872             case 0x1B:
8873             case 0x1C:
8874             case 0x1D:
8875             case 0x1E:
8876             case 0x1F:
8877             case 0x20:
8878             case 0x21:
8879             case 0x22:
8880             case 0x23:
8881             case 0x24:
8882             case 0x25:
8883             case 0x26:
8884             case 0x27:
8885             case 0x28:
8886             case 0x29:
8887             case 0x2A:
8888             case 0x2B:
8889             case 0x2C:
8890             case 0x2D:
8891             case 0x2E:
8892             case 0x2F:
8893             case 0x30:
8894             case 0x31:
8895             case 0x32:
8896             case 0x33:
8897             case 0x34:
8898             case 0x35:
8899             case 0x36:
8900             case 0x37:
8901             case 0x38:
8902             case 0x39:
8903             case 0x3A:
8904             case 0x3B:
8905             case 0x3C:
8906             case 0x3D:
8907             case 0x3E:
8908             case 0x3F:
8909             case 0x40:
8910             case 0x41:
8911             case 0x42:
8912             case 0x43:
8913             case 0x44:
8914             case 0x45:
8915             case 0x46:
8916             case 0x47:
8917             case 0x48:
8918             case 0x49:
8919             case 0x4A:
8920             case 0x4B:
8921             case 0x4C:
8922             case 0x4D:
8923             case 0x4E:
8924             case 0x4F:
8925             case 0x50:
8926             case 0x51:
8927             case 0x52:
8928             case 0x53:
8929             case 0x54:
8930             case 0x55:
8931             case 0x56:
8932             case 0x57:
8933             case 0x58:
8934             case 0x59:
8935             case 0x5A:
8936             case 0x5B:
8937             case 0x5C:
8938             case 0x5D:
8939             case 0x5E:
8940             case 0x5F:
8941             case 0x60:
8942             case 0x61:
8943             case 0x62:
8944             case 0x63:
8945             case 0x64:
8946             case 0x65:
8947             case 0x66:
8948             case 0x67:
8949             case 0x68:
8950             case 0x69:
8951             case 0x6A:
8952             case 0x6B:
8953             case 0x6C:
8954             case 0x6D:
8955             case 0x6E:
8956             case 0x6F:
8957             case 0x70:
8958             case 0x71:
8959             case 0x72:
8960             case 0x73:
8961             case 0x74:
8962             case 0x75:
8963             case 0x76:
8964             case 0x77:
8965             case 0x78:
8966             case 0x79:
8967             case 0x7A:
8968             case 0x7B:
8969             case 0x7C:
8970             case 0x7D:
8971             case 0x7E:
8972             case 0x7F:
8973                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8974 
8975             // fixmap
8976             case 0x80:
8977             case 0x81:
8978             case 0x82:
8979             case 0x83:
8980             case 0x84:
8981             case 0x85:
8982             case 0x86:
8983             case 0x87:
8984             case 0x88:
8985             case 0x89:
8986             case 0x8A:
8987             case 0x8B:
8988             case 0x8C:
8989             case 0x8D:
8990             case 0x8E:
8991             case 0x8F:
8992                 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
8993 
8994             // fixarray
8995             case 0x90:
8996             case 0x91:
8997             case 0x92:
8998             case 0x93:
8999             case 0x94:
9000             case 0x95:
9001             case 0x96:
9002             case 0x97:
9003             case 0x98:
9004             case 0x99:
9005             case 0x9A:
9006             case 0x9B:
9007             case 0x9C:
9008             case 0x9D:
9009             case 0x9E:
9010             case 0x9F:
9011                 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9012 
9013             // fixstr
9014             case 0xA0:
9015             case 0xA1:
9016             case 0xA2:
9017             case 0xA3:
9018             case 0xA4:
9019             case 0xA5:
9020             case 0xA6:
9021             case 0xA7:
9022             case 0xA8:
9023             case 0xA9:
9024             case 0xAA:
9025             case 0xAB:
9026             case 0xAC:
9027             case 0xAD:
9028             case 0xAE:
9029             case 0xAF:
9030             case 0xB0:
9031             case 0xB1:
9032             case 0xB2:
9033             case 0xB3:
9034             case 0xB4:
9035             case 0xB5:
9036             case 0xB6:
9037             case 0xB7:
9038             case 0xB8:
9039             case 0xB9:
9040             case 0xBA:
9041             case 0xBB:
9042             case 0xBC:
9043             case 0xBD:
9044             case 0xBE:
9045             case 0xBF:
9046             case 0xD9: // str 8
9047             case 0xDA: // str 16
9048             case 0xDB: // str 32
9049             {
9050                 string_t s;
9051                 return get_msgpack_string(s) && sax->string(s);
9052             }
9053 
9054             case 0xC0: // nil
9055                 return sax->null();
9056 
9057             case 0xC2: // false
9058                 return sax->boolean(false);
9059 
9060             case 0xC3: // true
9061                 return sax->boolean(true);
9062 
9063             case 0xC4: // bin 8
9064             case 0xC5: // bin 16
9065             case 0xC6: // bin 32
9066             case 0xC7: // ext 8
9067             case 0xC8: // ext 16
9068             case 0xC9: // ext 32
9069             case 0xD4: // fixext 1
9070             case 0xD5: // fixext 2
9071             case 0xD6: // fixext 4
9072             case 0xD7: // fixext 8
9073             case 0xD8: // fixext 16
9074             {
9075                 binary_t b;
9076                 return get_msgpack_binary(b) && sax->binary(b);
9077             }
9078 
9079             case 0xCA: // float 32
9080             {
9081                 float number{};
9082                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9083             }
9084 
9085             case 0xCB: // float 64
9086             {
9087                 double number{};
9088                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9089             }
9090 
9091             case 0xCC: // uint 8
9092             {
9093                 std::uint8_t number{};
9094                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9095             }
9096 
9097             case 0xCD: // uint 16
9098             {
9099                 std::uint16_t number{};
9100                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9101             }
9102 
9103             case 0xCE: // uint 32
9104             {
9105                 std::uint32_t number{};
9106                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9107             }
9108 
9109             case 0xCF: // uint 64
9110             {
9111                 std::uint64_t number{};
9112                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9113             }
9114 
9115             case 0xD0: // int 8
9116             {
9117                 std::int8_t number{};
9118                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9119             }
9120 
9121             case 0xD1: // int 16
9122             {
9123                 std::int16_t number{};
9124                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9125             }
9126 
9127             case 0xD2: // int 32
9128             {
9129                 std::int32_t number{};
9130                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9131             }
9132 
9133             case 0xD3: // int 64
9134             {
9135                 std::int64_t number{};
9136                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9137             }
9138 
9139             case 0xDC: // array 16
9140             {
9141                 std::uint16_t len{};
9142                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9143             }
9144 
9145             case 0xDD: // array 32
9146             {
9147                 std::uint32_t len{};
9148                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9149             }
9150 
9151             case 0xDE: // map 16
9152             {
9153                 std::uint16_t len{};
9154                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9155             }
9156 
9157             case 0xDF: // map 32
9158             {
9159                 std::uint32_t len{};
9160                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9161             }
9162 
9163             // negative fixint
9164             case 0xE0:
9165             case 0xE1:
9166             case 0xE2:
9167             case 0xE3:
9168             case 0xE4:
9169             case 0xE5:
9170             case 0xE6:
9171             case 0xE7:
9172             case 0xE8:
9173             case 0xE9:
9174             case 0xEA:
9175             case 0xEB:
9176             case 0xEC:
9177             case 0xED:
9178             case 0xEE:
9179             case 0xEF:
9180             case 0xF0:
9181             case 0xF1:
9182             case 0xF2:
9183             case 0xF3:
9184             case 0xF4:
9185             case 0xF5:
9186             case 0xF6:
9187             case 0xF7:
9188             case 0xF8:
9189             case 0xF9:
9190             case 0xFA:
9191             case 0xFB:
9192             case 0xFC:
9193             case 0xFD:
9194             case 0xFE:
9195             case 0xFF:
9196                 return sax->number_integer(static_cast<std::int8_t>(current));
9197 
9198             default: // anything else
9199             {
9200                 auto last_token = get_token_string();
9201                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
9202             }
9203         }
9204     }
9205 
9206     /*!
9207     @brief reads a MessagePack string
9208 
9209     This function first reads starting bytes to determine the expected
9210     string length and then copies this number of bytes into a string.
9211 
9212     @param[out] result  created string
9213 
9214     @return whether string creation completed
9215     */
get_msgpack_string(string_t & result)9216     bool get_msgpack_string(string_t& result)
9217     {
9218         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9219         {
9220             return false;
9221         }
9222 
9223         switch (current)
9224         {
9225             // fixstr
9226             case 0xA0:
9227             case 0xA1:
9228             case 0xA2:
9229             case 0xA3:
9230             case 0xA4:
9231             case 0xA5:
9232             case 0xA6:
9233             case 0xA7:
9234             case 0xA8:
9235             case 0xA9:
9236             case 0xAA:
9237             case 0xAB:
9238             case 0xAC:
9239             case 0xAD:
9240             case 0xAE:
9241             case 0xAF:
9242             case 0xB0:
9243             case 0xB1:
9244             case 0xB2:
9245             case 0xB3:
9246             case 0xB4:
9247             case 0xB5:
9248             case 0xB6:
9249             case 0xB7:
9250             case 0xB8:
9251             case 0xB9:
9252             case 0xBA:
9253             case 0xBB:
9254             case 0xBC:
9255             case 0xBD:
9256             case 0xBE:
9257             case 0xBF:
9258             {
9259                 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9260             }
9261 
9262             case 0xD9: // str 8
9263             {
9264                 std::uint8_t len{};
9265                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9266             }
9267 
9268             case 0xDA: // str 16
9269             {
9270                 std::uint16_t len{};
9271                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9272             }
9273 
9274             case 0xDB: // str 32
9275             {
9276                 std::uint32_t len{};
9277                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9278             }
9279 
9280             default:
9281             {
9282                 auto last_token = get_token_string();
9283                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
9284             }
9285         }
9286     }
9287 
9288     /*!
9289     @brief reads a MessagePack byte array
9290 
9291     This function first reads starting bytes to determine the expected
9292     byte array length and then copies this number of bytes into a byte array.
9293 
9294     @param[out] result  created byte array
9295 
9296     @return whether byte array creation completed
9297     */
get_msgpack_binary(binary_t & result)9298     bool get_msgpack_binary(binary_t& result)
9299     {
9300         // helper function to set the subtype
9301         auto assign_and_return_true = [&result](std::int8_t subtype)
9302         {
9303             result.set_subtype(static_cast<std::uint8_t>(subtype));
9304             return true;
9305         };
9306 
9307         switch (current)
9308         {
9309             case 0xC4: // bin 8
9310             {
9311                 std::uint8_t len{};
9312                 return get_number(input_format_t::msgpack, len) &&
9313                        get_binary(input_format_t::msgpack, len, result);
9314             }
9315 
9316             case 0xC5: // bin 16
9317             {
9318                 std::uint16_t len{};
9319                 return get_number(input_format_t::msgpack, len) &&
9320                        get_binary(input_format_t::msgpack, len, result);
9321             }
9322 
9323             case 0xC6: // bin 32
9324             {
9325                 std::uint32_t len{};
9326                 return get_number(input_format_t::msgpack, len) &&
9327                        get_binary(input_format_t::msgpack, len, result);
9328             }
9329 
9330             case 0xC7: // ext 8
9331             {
9332                 std::uint8_t len{};
9333                 std::int8_t subtype{};
9334                 return get_number(input_format_t::msgpack, len) &&
9335                        get_number(input_format_t::msgpack, subtype) &&
9336                        get_binary(input_format_t::msgpack, len, result) &&
9337                        assign_and_return_true(subtype);
9338             }
9339 
9340             case 0xC8: // ext 16
9341             {
9342                 std::uint16_t len{};
9343                 std::int8_t subtype{};
9344                 return get_number(input_format_t::msgpack, len) &&
9345                        get_number(input_format_t::msgpack, subtype) &&
9346                        get_binary(input_format_t::msgpack, len, result) &&
9347                        assign_and_return_true(subtype);
9348             }
9349 
9350             case 0xC9: // ext 32
9351             {
9352                 std::uint32_t len{};
9353                 std::int8_t subtype{};
9354                 return get_number(input_format_t::msgpack, len) &&
9355                        get_number(input_format_t::msgpack, subtype) &&
9356                        get_binary(input_format_t::msgpack, len, result) &&
9357                        assign_and_return_true(subtype);
9358             }
9359 
9360             case 0xD4: // fixext 1
9361             {
9362                 std::int8_t subtype{};
9363                 return get_number(input_format_t::msgpack, subtype) &&
9364                        get_binary(input_format_t::msgpack, 1, result) &&
9365                        assign_and_return_true(subtype);
9366             }
9367 
9368             case 0xD5: // fixext 2
9369             {
9370                 std::int8_t subtype{};
9371                 return get_number(input_format_t::msgpack, subtype) &&
9372                        get_binary(input_format_t::msgpack, 2, result) &&
9373                        assign_and_return_true(subtype);
9374             }
9375 
9376             case 0xD6: // fixext 4
9377             {
9378                 std::int8_t subtype{};
9379                 return get_number(input_format_t::msgpack, subtype) &&
9380                        get_binary(input_format_t::msgpack, 4, result) &&
9381                        assign_and_return_true(subtype);
9382             }
9383 
9384             case 0xD7: // fixext 8
9385             {
9386                 std::int8_t subtype{};
9387                 return get_number(input_format_t::msgpack, subtype) &&
9388                        get_binary(input_format_t::msgpack, 8, result) &&
9389                        assign_and_return_true(subtype);
9390             }
9391 
9392             case 0xD8: // fixext 16
9393             {
9394                 std::int8_t subtype{};
9395                 return get_number(input_format_t::msgpack, subtype) &&
9396                        get_binary(input_format_t::msgpack, 16, result) &&
9397                        assign_and_return_true(subtype);
9398             }
9399 
9400             default:           // LCOV_EXCL_LINE
9401                 return false;  // LCOV_EXCL_LINE
9402         }
9403     }
9404 
9405     /*!
9406     @param[in] len  the length of the array
9407     @return whether array creation completed
9408     */
get_msgpack_array(const std::size_t len)9409     bool get_msgpack_array(const std::size_t len)
9410     {
9411         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9412         {
9413             return false;
9414         }
9415 
9416         for (std::size_t i = 0; i < len; ++i)
9417         {
9418             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9419             {
9420                 return false;
9421             }
9422         }
9423 
9424         return sax->end_array();
9425     }
9426 
9427     /*!
9428     @param[in] len  the length of the object
9429     @return whether object creation completed
9430     */
get_msgpack_object(const std::size_t len)9431     bool get_msgpack_object(const std::size_t len)
9432     {
9433         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9434         {
9435             return false;
9436         }
9437 
9438         string_t key;
9439         for (std::size_t i = 0; i < len; ++i)
9440         {
9441             get();
9442             if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
9443             {
9444                 return false;
9445             }
9446 
9447             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
9448             {
9449                 return false;
9450             }
9451             key.clear();
9452         }
9453 
9454         return sax->end_object();
9455     }
9456 
9457     ////////////
9458     // UBJSON //
9459     ////////////
9460 
9461     /*!
9462     @param[in] get_char  whether a new character should be retrieved from the
9463                          input (true, default) or whether the last read
9464                          character should be considered instead
9465 
9466     @return whether a valid UBJSON value was passed to the SAX parser
9467     */
parse_ubjson_internal(const bool get_char=true)9468     bool parse_ubjson_internal(const bool get_char = true)
9469     {
9470         return get_ubjson_value(get_char ? get_ignore_noop() : current);
9471     }
9472 
9473     /*!
9474     @brief reads a UBJSON string
9475 
9476     This function is either called after reading the 'S' byte explicitly
9477     indicating a string, or in case of an object key where the 'S' byte can be
9478     left out.
9479 
9480     @param[out] result   created string
9481     @param[in] get_char  whether a new character should be retrieved from the
9482                          input (true, default) or whether the last read
9483                          character should be considered instead
9484 
9485     @return whether string creation completed
9486     */
get_ubjson_string(string_t & result,const bool get_char=true)9487     bool get_ubjson_string(string_t& result, const bool get_char = true)
9488     {
9489         if (get_char)
9490         {
9491             get();  // TODO(niels): may we ignore N here?
9492         }
9493 
9494         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9495         {
9496             return false;
9497         }
9498 
9499         switch (current)
9500         {
9501             case 'U':
9502             {
9503                 std::uint8_t len{};
9504                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9505             }
9506 
9507             case 'i':
9508             {
9509                 std::int8_t len{};
9510                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9511             }
9512 
9513             case 'I':
9514             {
9515                 std::int16_t len{};
9516                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9517             }
9518 
9519             case 'l':
9520             {
9521                 std::int32_t len{};
9522                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9523             }
9524 
9525             case 'L':
9526             {
9527                 std::int64_t len{};
9528                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
9529             }
9530 
9531             default:
9532                 auto last_token = get_token_string();
9533                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
9534         }
9535     }
9536 
9537     /*!
9538     @param[out] result  determined size
9539     @return whether size determination completed
9540     */
get_ubjson_size_value(std::size_t & result)9541     bool get_ubjson_size_value(std::size_t& result)
9542     {
9543         switch (get_ignore_noop())
9544         {
9545             case 'U':
9546             {
9547                 std::uint8_t number{};
9548                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9549                 {
9550                     return false;
9551                 }
9552                 result = static_cast<std::size_t>(number);
9553                 return true;
9554             }
9555 
9556             case 'i':
9557             {
9558                 std::int8_t number{};
9559                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9560                 {
9561                     return false;
9562                 }
9563                 result = static_cast<std::size_t>(number);
9564                 return true;
9565             }
9566 
9567             case 'I':
9568             {
9569                 std::int16_t number{};
9570                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9571                 {
9572                     return false;
9573                 }
9574                 result = static_cast<std::size_t>(number);
9575                 return true;
9576             }
9577 
9578             case 'l':
9579             {
9580                 std::int32_t number{};
9581                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9582                 {
9583                     return false;
9584                 }
9585                 result = static_cast<std::size_t>(number);
9586                 return true;
9587             }
9588 
9589             case 'L':
9590             {
9591                 std::int64_t number{};
9592                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
9593                 {
9594                     return false;
9595                 }
9596                 result = static_cast<std::size_t>(number);
9597                 return true;
9598             }
9599 
9600             default:
9601             {
9602                 auto last_token = get_token_string();
9603                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
9604             }
9605         }
9606     }
9607 
9608     /*!
9609     @brief determine the type and size for a container
9610 
9611     In the optimized UBJSON format, a type and a size can be provided to allow
9612     for a more compact representation.
9613 
9614     @param[out] result  pair of the size and the type
9615 
9616     @return whether pair creation completed
9617     */
get_ubjson_size_type(std::pair<std::size_t,char_int_type> & result)9618     bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
9619     {
9620         result.first = string_t::npos; // size
9621         result.second = 0; // type
9622 
9623         get_ignore_noop();
9624 
9625         if (current == '$')
9626         {
9627             result.second = get();  // must not ignore 'N', because 'N' maybe the type
9628             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
9629             {
9630                 return false;
9631             }
9632 
9633             get_ignore_noop();
9634             if (JSON_HEDLEY_UNLIKELY(current != '#'))
9635             {
9636                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
9637                 {
9638                     return false;
9639                 }
9640                 auto last_token = get_token_string();
9641                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
9642             }
9643 
9644             return get_ubjson_size_value(result.first);
9645         }
9646 
9647         if (current == '#')
9648         {
9649             return get_ubjson_size_value(result.first);
9650         }
9651 
9652         return true;
9653     }
9654 
9655     /*!
9656     @param prefix  the previously read or set type prefix
9657     @return whether value creation completed
9658     */
get_ubjson_value(const char_int_type prefix)9659     bool get_ubjson_value(const char_int_type prefix)
9660     {
9661         switch (prefix)
9662         {
9663             case std::char_traits<char_type>::eof():  // EOF
9664                 return unexpect_eof(input_format_t::ubjson, "value");
9665 
9666             case 'T':  // true
9667                 return sax->boolean(true);
9668             case 'F':  // false
9669                 return sax->boolean(false);
9670 
9671             case 'Z':  // null
9672                 return sax->null();
9673 
9674             case 'U':
9675             {
9676                 std::uint8_t number{};
9677                 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
9678             }
9679 
9680             case 'i':
9681             {
9682                 std::int8_t number{};
9683                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9684             }
9685 
9686             case 'I':
9687             {
9688                 std::int16_t number{};
9689                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9690             }
9691 
9692             case 'l':
9693             {
9694                 std::int32_t number{};
9695                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9696             }
9697 
9698             case 'L':
9699             {
9700                 std::int64_t number{};
9701                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
9702             }
9703 
9704             case 'd':
9705             {
9706                 float number{};
9707                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9708             }
9709 
9710             case 'D':
9711             {
9712                 double number{};
9713                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
9714             }
9715 
9716             case 'H':
9717             {
9718                 return get_ubjson_high_precision_number();
9719             }
9720 
9721             case 'C':  // char
9722             {
9723                 get();
9724                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
9725                 {
9726                     return false;
9727                 }
9728                 if (JSON_HEDLEY_UNLIKELY(current > 127))
9729                 {
9730                     auto last_token = get_token_string();
9731                     return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
9732                 }
9733                 string_t s(1, static_cast<typename string_t::value_type>(current));
9734                 return sax->string(s);
9735             }
9736 
9737             case 'S':  // string
9738             {
9739                 string_t s;
9740                 return get_ubjson_string(s) && sax->string(s);
9741             }
9742 
9743             case '[':  // array
9744                 return get_ubjson_array();
9745 
9746             case '{':  // object
9747                 return get_ubjson_object();
9748 
9749             default: // anything else
9750             {
9751                 auto last_token = get_token_string();
9752                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
9753             }
9754         }
9755     }
9756 
9757     /*!
9758     @return whether array creation completed
9759     */
get_ubjson_array()9760     bool get_ubjson_array()
9761     {
9762         std::pair<std::size_t, char_int_type> size_and_type;
9763         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9764         {
9765             return false;
9766         }
9767 
9768         if (size_and_type.first != string_t::npos)
9769         {
9770             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
9771             {
9772                 return false;
9773             }
9774 
9775             if (size_and_type.second != 0)
9776             {
9777                 if (size_and_type.second != 'N')
9778                 {
9779                     for (std::size_t i = 0; i < size_and_type.first; ++i)
9780                     {
9781                         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9782                         {
9783                             return false;
9784                         }
9785                     }
9786                 }
9787             }
9788             else
9789             {
9790                 for (std::size_t i = 0; i < size_and_type.first; ++i)
9791                 {
9792                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9793                     {
9794                         return false;
9795                     }
9796                 }
9797             }
9798         }
9799         else
9800         {
9801             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
9802             {
9803                 return false;
9804             }
9805 
9806             while (current != ']')
9807             {
9808                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
9809                 {
9810                     return false;
9811                 }
9812                 get_ignore_noop();
9813             }
9814         }
9815 
9816         return sax->end_array();
9817     }
9818 
9819     /*!
9820     @return whether object creation completed
9821     */
get_ubjson_object()9822     bool get_ubjson_object()
9823     {
9824         std::pair<std::size_t, char_int_type> size_and_type;
9825         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
9826         {
9827             return false;
9828         }
9829 
9830         string_t key;
9831         if (size_and_type.first != string_t::npos)
9832         {
9833             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
9834             {
9835                 return false;
9836             }
9837 
9838             if (size_and_type.second != 0)
9839             {
9840                 for (std::size_t i = 0; i < size_and_type.first; ++i)
9841                 {
9842                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9843                     {
9844                         return false;
9845                     }
9846                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
9847                     {
9848                         return false;
9849                     }
9850                     key.clear();
9851                 }
9852             }
9853             else
9854             {
9855                 for (std::size_t i = 0; i < size_and_type.first; ++i)
9856                 {
9857                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
9858                     {
9859                         return false;
9860                     }
9861                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9862                     {
9863                         return false;
9864                     }
9865                     key.clear();
9866                 }
9867             }
9868         }
9869         else
9870         {
9871             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
9872             {
9873                 return false;
9874             }
9875 
9876             while (current != '}')
9877             {
9878                 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
9879                 {
9880                     return false;
9881                 }
9882                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
9883                 {
9884                     return false;
9885                 }
9886                 get_ignore_noop();
9887                 key.clear();
9888             }
9889         }
9890 
9891         return sax->end_object();
9892     }
9893 
9894     // Note, no reader for UBJSON binary types is implemented because they do
9895     // not exist
9896 
get_ubjson_high_precision_number()9897     bool get_ubjson_high_precision_number()
9898     {
9899         // get size of following number string
9900         std::size_t size{};
9901         auto res = get_ubjson_size_value(size);
9902         if (JSON_HEDLEY_UNLIKELY(!res))
9903         {
9904             return res;
9905         }
9906 
9907         // get number string
9908         std::vector<char> number_vector;
9909         for (std::size_t i = 0; i < size; ++i)
9910         {
9911             get();
9912             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
9913             {
9914                 return false;
9915             }
9916             number_vector.push_back(static_cast<char>(current));
9917         }
9918 
9919         // parse number string
9920         auto number_ia = detail::input_adapter(std::forward<decltype(number_vector)>(number_vector));
9921         auto number_lexer = detail::lexer<BasicJsonType, decltype(number_ia)>(std::move(number_ia), false);
9922         const auto result_number = number_lexer.scan();
9923         const auto number_string = number_lexer.get_token_string();
9924         const auto result_remainder = number_lexer.scan();
9925 
9926         using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
9927 
9928         if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
9929         {
9930             return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9931         }
9932 
9933         switch (result_number)
9934         {
9935             case token_type::value_integer:
9936                 return sax->number_integer(number_lexer.get_number_integer());
9937             case token_type::value_unsigned:
9938                 return sax->number_unsigned(number_lexer.get_number_unsigned());
9939             case token_type::value_float:
9940                 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
9941             default:
9942                 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number")));
9943         }
9944     }
9945 
9946     ///////////////////////
9947     // Utility functions //
9948     ///////////////////////
9949 
9950     /*!
9951     @brief get next character from the input
9952 
9953     This function provides the interface to the used input adapter. It does
9954     not throw in case the input reached EOF, but returns a -'ve valued
9955     `std::char_traits<char_type>::eof()` in that case.
9956 
9957     @return character read from the input
9958     */
get()9959     char_int_type get()
9960     {
9961         ++chars_read;
9962         return current = ia.get_character();
9963     }
9964 
9965     /*!
9966     @return character read from the input after ignoring all 'N' entries
9967     */
get_ignore_noop()9968     char_int_type get_ignore_noop()
9969     {
9970         do
9971         {
9972             get();
9973         }
9974         while (current == 'N');
9975 
9976         return current;
9977     }
9978 
9979     /*
9980     @brief read a number from the input
9981 
9982     @tparam NumberType the type of the number
9983     @param[in] format   the current format (for diagnostics)
9984     @param[out] result  number of type @a NumberType
9985 
9986     @return whether conversion completed
9987 
9988     @note This function needs to respect the system's endianess, because
9989           bytes in CBOR, MessagePack, and UBJSON are stored in network order
9990           (big endian) and therefore need reordering on little endian systems.
9991     */
9992     template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)9993     bool get_number(const input_format_t format, NumberType& result)
9994     {
9995         // step 1: read input into array with system's byte order
9996         std::array<std::uint8_t, sizeof(NumberType)> vec;
9997         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
9998         {
9999             get();
10000             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10001             {
10002                 return false;
10003             }
10004 
10005             // reverse byte order prior to conversion if necessary
10006             if (is_little_endian != InputIsLittleEndian)
10007             {
10008                 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10009             }
10010             else
10011             {
10012                 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10013             }
10014         }
10015 
10016         // step 2: convert array into number of type T and return
10017         std::memcpy(&result, vec.data(), sizeof(NumberType));
10018         return true;
10019     }
10020 
10021     /*!
10022     @brief create a string by reading characters from the input
10023 
10024     @tparam NumberType the type of the number
10025     @param[in] format the current format (for diagnostics)
10026     @param[in] len number of characters to read
10027     @param[out] result string created by reading @a len bytes
10028 
10029     @return whether string creation completed
10030 
10031     @note We can not reserve @a len bytes for the result, because @a len
10032           may be too large. Usually, @ref unexpect_eof() detects the end of
10033           the input before we run out of string memory.
10034     */
10035     template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)10036     bool get_string(const input_format_t format,
10037                     const NumberType len,
10038                     string_t& result)
10039     {
10040         bool success = true;
10041         for (NumberType i = 0; i < len; i++)
10042         {
10043             get();
10044             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10045             {
10046                 success = false;
10047                 break;
10048             }
10049             result.push_back(static_cast<typename string_t::value_type>(current));
10050         };
10051         return success;
10052     }
10053 
10054     /*!
10055     @brief create a byte array by reading bytes from the input
10056 
10057     @tparam NumberType the type of the number
10058     @param[in] format the current format (for diagnostics)
10059     @param[in] len number of bytes to read
10060     @param[out] result byte array created by reading @a len bytes
10061 
10062     @return whether byte array creation completed
10063 
10064     @note We can not reserve @a len bytes for the result, because @a len
10065           may be too large. Usually, @ref unexpect_eof() detects the end of
10066           the input before we run out of memory.
10067     */
10068     template<typename NumberType>
get_binary(const input_format_t format,const NumberType len,binary_t & result)10069     bool get_binary(const input_format_t format,
10070                     const NumberType len,
10071                     binary_t& result)
10072     {
10073         bool success = true;
10074         for (NumberType i = 0; i < len; i++)
10075         {
10076             get();
10077             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10078             {
10079                 success = false;
10080                 break;
10081             }
10082             result.push_back(static_cast<std::uint8_t>(current));
10083         }
10084         return success;
10085     }
10086 
10087     /*!
10088     @param[in] format   the current format (for diagnostics)
10089     @param[in] context  further context information (for diagnostics)
10090     @return whether the last read character is not EOF
10091     */
10092     JSON_HEDLEY_NON_NULL(3)
unexpect_eof(const input_format_t format,const char * context) const10093     bool unexpect_eof(const input_format_t format, const char* context) const
10094     {
10095         if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10096         {
10097             return sax->parse_error(chars_read, "<end of file>",
10098                                     parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
10099         }
10100         return true;
10101     }
10102 
10103     /*!
10104     @return a string representation of the last read byte
10105     */
get_token_string() const10106     std::string get_token_string() const
10107     {
10108         std::array<char, 3> cr{{}};
10109         (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
10110         return std::string{cr.data()};
10111     }
10112 
10113     /*!
10114     @param[in] format   the current format
10115     @param[in] detail   a detailed error message
10116     @param[in] context  further context information
10117     @return a message string to use in the parse_error exceptions
10118     */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const10119     std::string exception_message(const input_format_t format,
10120                                   const std::string& detail,
10121                                   const std::string& context) const
10122     {
10123         std::string error_msg = "syntax error while parsing ";
10124 
10125         switch (format)
10126         {
10127             case input_format_t::cbor:
10128                 error_msg += "CBOR";
10129                 break;
10130 
10131             case input_format_t::msgpack:
10132                 error_msg += "MessagePack";
10133                 break;
10134 
10135             case input_format_t::ubjson:
10136                 error_msg += "UBJSON";
10137                 break;
10138 
10139             case input_format_t::bson:
10140                 error_msg += "BSON";
10141                 break;
10142 
10143             default:            // LCOV_EXCL_LINE
10144                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
10145         }
10146 
10147         return error_msg + " " + context + ": " + detail;
10148     }
10149 
10150   private:
10151     /// input adapter
10152     InputAdapterType ia;
10153 
10154     /// the current character
10155     char_int_type current = std::char_traits<char_type>::eof();
10156 
10157     /// the number of characters read
10158     std::size_t chars_read = 0;
10159 
10160     /// whether we can assume little endianess
10161     const bool is_little_endian = little_endianess();
10162 
10163     /// the SAX parser
10164     json_sax_t* sax = nullptr;
10165 };
10166 }  // namespace detail
10167 }  // namespace nlohmann
10168 
10169 // #include <nlohmann/detail/input/input_adapters.hpp>
10170 
10171 // #include <nlohmann/detail/input/lexer.hpp>
10172 
10173 // #include <nlohmann/detail/input/parser.hpp>
10174 
10175 
10176 #include <cmath> // isfinite
10177 #include <cstdint> // uint8_t
10178 #include <functional> // function
10179 #include <string> // string
10180 #include <utility> // move
10181 #include <vector> // vector
10182 
10183 // #include <nlohmann/detail/exceptions.hpp>
10184 
10185 // #include <nlohmann/detail/input/input_adapters.hpp>
10186 
10187 // #include <nlohmann/detail/input/json_sax.hpp>
10188 
10189 // #include <nlohmann/detail/input/lexer.hpp>
10190 
10191 // #include <nlohmann/detail/macro_scope.hpp>
10192 
10193 // #include <nlohmann/detail/meta/is_sax.hpp>
10194 
10195 // #include <nlohmann/detail/value_t.hpp>
10196 
10197 
10198 namespace nlohmann
10199 {
10200 namespace detail
10201 {
10202 ////////////
10203 // parser //
10204 ////////////
10205 
10206 enum class parse_event_t : uint8_t
10207 {
10208     /// the parser read `{` and started to process a JSON object
10209     object_start,
10210     /// the parser read `}` and finished processing a JSON object
10211     object_end,
10212     /// the parser read `[` and started to process a JSON array
10213     array_start,
10214     /// the parser read `]` and finished processing a JSON array
10215     array_end,
10216     /// the parser read a key of a value in an object
10217     key,
10218     /// the parser finished reading a JSON value
10219     value
10220 };
10221 
10222 template<typename BasicJsonType>
10223 using parser_callback_t =
10224     std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
10225 
10226 /*!
10227 @brief syntax analysis
10228 
10229 This class implements a recursive descent parser.
10230 */
10231 template<typename BasicJsonType, typename InputAdapterType>
10232 class parser
10233 {
10234     using number_integer_t = typename BasicJsonType::number_integer_t;
10235     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10236     using number_float_t = typename BasicJsonType::number_float_t;
10237     using string_t = typename BasicJsonType::string_t;
10238     using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10239     using token_type = typename lexer_t::token_type;
10240 
10241   public:
10242     /// 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)10243     explicit parser(InputAdapterType&& adapter,
10244                     const parser_callback_t<BasicJsonType> cb = nullptr,
10245                     const bool allow_exceptions_ = true,
10246                     const bool skip_comments = false)
10247         : callback(cb)
10248         , m_lexer(std::move(adapter), skip_comments)
10249         , allow_exceptions(allow_exceptions_)
10250     {
10251         // read first token
10252         get_token();
10253     }
10254 
10255     /*!
10256     @brief public parser interface
10257 
10258     @param[in] strict      whether to expect the last token to be EOF
10259     @param[in,out] result  parsed JSON value
10260 
10261     @throw parse_error.101 in case of an unexpected token
10262     @throw parse_error.102 if to_unicode fails or surrogate error
10263     @throw parse_error.103 if to_unicode fails
10264     */
parse(const bool strict,BasicJsonType & result)10265     void parse(const bool strict, BasicJsonType& result)
10266     {
10267         if (callback)
10268         {
10269             json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10270             sax_parse_internal(&sdp);
10271             result.assert_invariant();
10272 
10273             // in strict mode, input must be completely read
10274             if (strict && (get_token() != token_type::end_of_input))
10275             {
10276                 sdp.parse_error(m_lexer.get_position(),
10277                                 m_lexer.get_token_string(),
10278                                 parse_error::create(101, m_lexer.get_position(),
10279                                                     exception_message(token_type::end_of_input, "value")));
10280             }
10281 
10282             // in case of an error, return discarded value
10283             if (sdp.is_errored())
10284             {
10285                 result = value_t::discarded;
10286                 return;
10287             }
10288 
10289             // set top-level value to null if it was discarded by the callback
10290             // function
10291             if (result.is_discarded())
10292             {
10293                 result = nullptr;
10294             }
10295         }
10296         else
10297         {
10298             json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10299             sax_parse_internal(&sdp);
10300             result.assert_invariant();
10301 
10302             // in strict mode, input must be completely read
10303             if (strict && (get_token() != token_type::end_of_input))
10304             {
10305                 sdp.parse_error(m_lexer.get_position(),
10306                                 m_lexer.get_token_string(),
10307                                 parse_error::create(101, m_lexer.get_position(),
10308                                                     exception_message(token_type::end_of_input, "value")));
10309             }
10310 
10311             // in case of an error, return discarded value
10312             if (sdp.is_errored())
10313             {
10314                 result = value_t::discarded;
10315                 return;
10316             }
10317         }
10318     }
10319 
10320     /*!
10321     @brief public accept interface
10322 
10323     @param[in] strict  whether to expect the last token to be EOF
10324     @return whether the input is a proper JSON text
10325     */
accept(const bool strict=true)10326     bool accept(const bool strict = true)
10327     {
10328         json_sax_acceptor<BasicJsonType> sax_acceptor;
10329         return sax_parse(&sax_acceptor, strict);
10330     }
10331 
10332     template<typename SAX>
10333     JSON_HEDLEY_NON_NULL(2)
sax_parse(SAX * sax,const bool strict=true)10334     bool sax_parse(SAX* sax, const bool strict = true)
10335     {
10336         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10337         const bool result = sax_parse_internal(sax);
10338 
10339         // strict mode: next byte must be EOF
10340         if (result && strict && (get_token() != token_type::end_of_input))
10341         {
10342             return sax->parse_error(m_lexer.get_position(),
10343                                     m_lexer.get_token_string(),
10344                                     parse_error::create(101, m_lexer.get_position(),
10345                                             exception_message(token_type::end_of_input, "value")));
10346         }
10347 
10348         return result;
10349     }
10350 
10351   private:
10352     template<typename SAX>
10353     JSON_HEDLEY_NON_NULL(2)
sax_parse_internal(SAX * sax)10354     bool sax_parse_internal(SAX* sax)
10355     {
10356         // stack to remember the hierarchy of structured values we are parsing
10357         // true = array; false = object
10358         std::vector<bool> states;
10359         // value to avoid a goto (see comment where set to true)
10360         bool skip_to_state_evaluation = false;
10361 
10362         while (true)
10363         {
10364             if (!skip_to_state_evaluation)
10365             {
10366                 // invariant: get_token() was called before each iteration
10367                 switch (last_token)
10368                 {
10369                     case token_type::begin_object:
10370                     {
10371                         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10372                         {
10373                             return false;
10374                         }
10375 
10376                         // closing } -> we are done
10377                         if (get_token() == token_type::end_object)
10378                         {
10379                             if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10380                             {
10381                                 return false;
10382                             }
10383                             break;
10384                         }
10385 
10386                         // parse key
10387                         if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10388                         {
10389                             return sax->parse_error(m_lexer.get_position(),
10390                                                     m_lexer.get_token_string(),
10391                                                     parse_error::create(101, m_lexer.get_position(),
10392                                                             exception_message(token_type::value_string, "object key")));
10393                         }
10394                         if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10395                         {
10396                             return false;
10397                         }
10398 
10399                         // parse separator (:)
10400                         if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10401                         {
10402                             return sax->parse_error(m_lexer.get_position(),
10403                                                     m_lexer.get_token_string(),
10404                                                     parse_error::create(101, m_lexer.get_position(),
10405                                                             exception_message(token_type::name_separator, "object separator")));
10406                         }
10407 
10408                         // remember we are now inside an object
10409                         states.push_back(false);
10410 
10411                         // parse values
10412                         get_token();
10413                         continue;
10414                     }
10415 
10416                     case token_type::begin_array:
10417                     {
10418                         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10419                         {
10420                             return false;
10421                         }
10422 
10423                         // closing ] -> we are done
10424                         if (get_token() == token_type::end_array)
10425                         {
10426                             if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10427                             {
10428                                 return false;
10429                             }
10430                             break;
10431                         }
10432 
10433                         // remember we are now inside an array
10434                         states.push_back(true);
10435 
10436                         // parse values (no need to call get_token)
10437                         continue;
10438                     }
10439 
10440                     case token_type::value_float:
10441                     {
10442                         const auto res = m_lexer.get_number_float();
10443 
10444                         if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10445                         {
10446                             return sax->parse_error(m_lexer.get_position(),
10447                                                     m_lexer.get_token_string(),
10448                                                     out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
10449                         }
10450 
10451                         if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10452                         {
10453                             return false;
10454                         }
10455 
10456                         break;
10457                     }
10458 
10459                     case token_type::literal_false:
10460                     {
10461                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10462                         {
10463                             return false;
10464                         }
10465                         break;
10466                     }
10467 
10468                     case token_type::literal_null:
10469                     {
10470                         if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10471                         {
10472                             return false;
10473                         }
10474                         break;
10475                     }
10476 
10477                     case token_type::literal_true:
10478                     {
10479                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
10480                         {
10481                             return false;
10482                         }
10483                         break;
10484                     }
10485 
10486                     case token_type::value_integer:
10487                     {
10488                         if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
10489                         {
10490                             return false;
10491                         }
10492                         break;
10493                     }
10494 
10495                     case token_type::value_string:
10496                     {
10497                         if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
10498                         {
10499                             return false;
10500                         }
10501                         break;
10502                     }
10503 
10504                     case token_type::value_unsigned:
10505                     {
10506                         if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
10507                         {
10508                             return false;
10509                         }
10510                         break;
10511                     }
10512 
10513                     case token_type::parse_error:
10514                     {
10515                         // using "uninitialized" to avoid "expected" message
10516                         return sax->parse_error(m_lexer.get_position(),
10517                                                 m_lexer.get_token_string(),
10518                                                 parse_error::create(101, m_lexer.get_position(),
10519                                                         exception_message(token_type::uninitialized, "value")));
10520                     }
10521 
10522                     default: // the last token was unexpected
10523                     {
10524                         return sax->parse_error(m_lexer.get_position(),
10525                                                 m_lexer.get_token_string(),
10526                                                 parse_error::create(101, m_lexer.get_position(),
10527                                                         exception_message(token_type::literal_or_value, "value")));
10528                     }
10529                 }
10530             }
10531             else
10532             {
10533                 skip_to_state_evaluation = false;
10534             }
10535 
10536             // we reached this line after we successfully parsed a value
10537             if (states.empty())
10538             {
10539                 // empty stack: we reached the end of the hierarchy: done
10540                 return true;
10541             }
10542 
10543             if (states.back())  // array
10544             {
10545                 // comma -> next value
10546                 if (get_token() == token_type::value_separator)
10547                 {
10548                     // parse a new value
10549                     get_token();
10550                     continue;
10551                 }
10552 
10553                 // closing ]
10554                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
10555                 {
10556                     if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10557                     {
10558                         return false;
10559                     }
10560 
10561                     // We are done with this array. Before we can parse a
10562                     // new value, we need to evaluate the new state first.
10563                     // By setting skip_to_state_evaluation to false, we
10564                     // are effectively jumping to the beginning of this if.
10565                     JSON_ASSERT(!states.empty());
10566                     states.pop_back();
10567                     skip_to_state_evaluation = true;
10568                     continue;
10569                 }
10570 
10571                 return sax->parse_error(m_lexer.get_position(),
10572                                         m_lexer.get_token_string(),
10573                                         parse_error::create(101, m_lexer.get_position(),
10574                                                 exception_message(token_type::end_array, "array")));
10575             }
10576             else  // object
10577             {
10578                 // comma -> next value
10579                 if (get_token() == token_type::value_separator)
10580                 {
10581                     // parse key
10582                     if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
10583                     {
10584                         return sax->parse_error(m_lexer.get_position(),
10585                                                 m_lexer.get_token_string(),
10586                                                 parse_error::create(101, m_lexer.get_position(),
10587                                                         exception_message(token_type::value_string, "object key")));
10588                     }
10589 
10590                     if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10591                     {
10592                         return false;
10593                     }
10594 
10595                     // parse separator (:)
10596                     if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10597                     {
10598                         return sax->parse_error(m_lexer.get_position(),
10599                                                 m_lexer.get_token_string(),
10600                                                 parse_error::create(101, m_lexer.get_position(),
10601                                                         exception_message(token_type::name_separator, "object separator")));
10602                     }
10603 
10604                     // parse values
10605                     get_token();
10606                     continue;
10607                 }
10608 
10609                 // closing }
10610                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
10611                 {
10612                     if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10613                     {
10614                         return false;
10615                     }
10616 
10617                     // We are done with this object. Before we can parse a
10618                     // new value, we need to evaluate the new state first.
10619                     // By setting skip_to_state_evaluation to false, we
10620                     // are effectively jumping to the beginning of this if.
10621                     JSON_ASSERT(!states.empty());
10622                     states.pop_back();
10623                     skip_to_state_evaluation = true;
10624                     continue;
10625                 }
10626 
10627                 return sax->parse_error(m_lexer.get_position(),
10628                                         m_lexer.get_token_string(),
10629                                         parse_error::create(101, m_lexer.get_position(),
10630                                                 exception_message(token_type::end_object, "object")));
10631             }
10632         }
10633     }
10634 
10635     /// get next token from lexer
get_token()10636     token_type get_token()
10637     {
10638         return last_token = m_lexer.scan();
10639     }
10640 
exception_message(const token_type expected,const std::string & context)10641     std::string exception_message(const token_type expected, const std::string& context)
10642     {
10643         std::string error_msg = "syntax error ";
10644 
10645         if (!context.empty())
10646         {
10647             error_msg += "while parsing " + context + " ";
10648         }
10649 
10650         error_msg += "- ";
10651 
10652         if (last_token == token_type::parse_error)
10653         {
10654             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
10655                          m_lexer.get_token_string() + "'";
10656         }
10657         else
10658         {
10659             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
10660         }
10661 
10662         if (expected != token_type::uninitialized)
10663         {
10664             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
10665         }
10666 
10667         return error_msg;
10668     }
10669 
10670   private:
10671     /// callback function
10672     const parser_callback_t<BasicJsonType> callback = nullptr;
10673     /// the type of the last read token
10674     token_type last_token = token_type::uninitialized;
10675     /// the lexer
10676     lexer_t m_lexer;
10677     /// whether to throw exceptions in case of errors
10678     const bool allow_exceptions = true;
10679 };
10680 }  // namespace detail
10681 }  // namespace nlohmann
10682 
10683 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10684 
10685 
10686 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10687 
10688 
10689 #include <cstddef> // ptrdiff_t
10690 #include <limits>  // numeric_limits
10691 
10692 namespace nlohmann
10693 {
10694 namespace detail
10695 {
10696 /*
10697 @brief an iterator for primitive JSON types
10698 
10699 This class models an iterator for primitive JSON types (boolean, number,
10700 string). It's only purpose is to allow the iterator/const_iterator classes
10701 to "iterate" over primitive values. Internally, the iterator is modeled by
10702 a `difference_type` variable. Value begin_value (`0`) models the begin,
10703 end_value (`1`) models past the end.
10704 */
10705 class primitive_iterator_t
10706 {
10707   private:
10708     using difference_type = std::ptrdiff_t;
10709     static constexpr difference_type begin_value = 0;
10710     static constexpr difference_type end_value = begin_value + 1;
10711 
10712   JSON_PRIVATE_UNLESS_TESTED:
10713     /// iterator as signed integer type
10714     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
10715 
10716   public:
get_value() const10717     constexpr difference_type get_value() const noexcept
10718     {
10719         return m_it;
10720     }
10721 
10722     /// set iterator to a defined beginning
set_begin()10723     void set_begin() noexcept
10724     {
10725         m_it = begin_value;
10726     }
10727 
10728     /// set iterator to a defined past the end
set_end()10729     void set_end() noexcept
10730     {
10731         m_it = end_value;
10732     }
10733 
10734     /// return whether the iterator can be dereferenced
is_begin() const10735     constexpr bool is_begin() const noexcept
10736     {
10737         return m_it == begin_value;
10738     }
10739 
10740     /// return whether the iterator is at end
is_end() const10741     constexpr bool is_end() const noexcept
10742     {
10743         return m_it == end_value;
10744     }
10745 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)10746     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10747     {
10748         return lhs.m_it == rhs.m_it;
10749     }
10750 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)10751     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10752     {
10753         return lhs.m_it < rhs.m_it;
10754     }
10755 
operator +(difference_type n)10756     primitive_iterator_t operator+(difference_type n) noexcept
10757     {
10758         auto result = *this;
10759         result += n;
10760         return result;
10761     }
10762 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)10763     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
10764     {
10765         return lhs.m_it - rhs.m_it;
10766     }
10767 
operator ++()10768     primitive_iterator_t& operator++() noexcept
10769     {
10770         ++m_it;
10771         return *this;
10772     }
10773 
operator ++(int)10774     primitive_iterator_t const operator++(int) noexcept
10775     {
10776         auto result = *this;
10777         ++m_it;
10778         return result;
10779     }
10780 
operator --()10781     primitive_iterator_t& operator--() noexcept
10782     {
10783         --m_it;
10784         return *this;
10785     }
10786 
operator --(int)10787     primitive_iterator_t const operator--(int) noexcept
10788     {
10789         auto result = *this;
10790         --m_it;
10791         return result;
10792     }
10793 
operator +=(difference_type n)10794     primitive_iterator_t& operator+=(difference_type n) noexcept
10795     {
10796         m_it += n;
10797         return *this;
10798     }
10799 
operator -=(difference_type n)10800     primitive_iterator_t& operator-=(difference_type n) noexcept
10801     {
10802         m_it -= n;
10803         return *this;
10804     }
10805 };
10806 }  // namespace detail
10807 }  // namespace nlohmann
10808 
10809 
10810 namespace nlohmann
10811 {
10812 namespace detail
10813 {
10814 /*!
10815 @brief an iterator value
10816 
10817 @note This structure could easily be a union, but MSVC currently does not allow
10818 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
10819 */
10820 template<typename BasicJsonType> struct internal_iterator
10821 {
10822     /// iterator for JSON objects
10823     typename BasicJsonType::object_t::iterator object_iterator {};
10824     /// iterator for JSON arrays
10825     typename BasicJsonType::array_t::iterator array_iterator {};
10826     /// generic iterator for all other types
10827     primitive_iterator_t primitive_iterator {};
10828 };
10829 }  // namespace detail
10830 }  // namespace nlohmann
10831 
10832 // #include <nlohmann/detail/iterators/iter_impl.hpp>
10833 
10834 
10835 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
10836 #include <type_traits> // conditional, is_const, remove_const
10837 
10838 // #include <nlohmann/detail/exceptions.hpp>
10839 
10840 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
10841 
10842 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
10843 
10844 // #include <nlohmann/detail/macro_scope.hpp>
10845 
10846 // #include <nlohmann/detail/meta/cpp_future.hpp>
10847 
10848 // #include <nlohmann/detail/meta/type_traits.hpp>
10849 
10850 // #include <nlohmann/detail/value_t.hpp>
10851 
10852 
10853 namespace nlohmann
10854 {
10855 namespace detail
10856 {
10857 // forward declare, to be able to friend it later on
10858 template<typename IteratorType> class iteration_proxy;
10859 template<typename IteratorType> class iteration_proxy_value;
10860 
10861 /*!
10862 @brief a template for a bidirectional iterator for the @ref basic_json class
10863 This class implements a both iterators (iterator and const_iterator) for the
10864 @ref basic_json class.
10865 @note An iterator is called *initialized* when a pointer to a JSON value has
10866       been set (e.g., by a constructor or a copy assignment). If the iterator is
10867       default-constructed, it is *uninitialized* and most methods are undefined.
10868       **The library uses assertions to detect calls on uninitialized iterators.**
10869 @requirement The class satisfies the following concept requirements:
10870 -
10871 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
10872   The iterator that can be moved can be moved in both directions (i.e.
10873   incremented and decremented).
10874 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
10875        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
10876 */
10877 template<typename BasicJsonType>
10878 class iter_impl
10879 {
10880     /// allow basic_json to access private members
10881     friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
10882     friend BasicJsonType;
10883     friend iteration_proxy<iter_impl>;
10884     friend iteration_proxy_value<iter_impl>;
10885 
10886     using object_t = typename BasicJsonType::object_t;
10887     using array_t = typename BasicJsonType::array_t;
10888     // make sure BasicJsonType is basic_json or const basic_json
10889     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
10890                   "iter_impl only accepts (const) basic_json");
10891 
10892   public:
10893 
10894     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
10895     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
10896     /// A user-defined iterator should provide publicly accessible typedefs named
10897     /// iterator_category, value_type, difference_type, pointer, and reference.
10898     /// Note that value_type is required to be non-const, even for constant iterators.
10899     using iterator_category = std::bidirectional_iterator_tag;
10900 
10901     /// the type of the values when the iterator is dereferenced
10902     using value_type = typename BasicJsonType::value_type;
10903     /// a type to represent differences between iterators
10904     using difference_type = typename BasicJsonType::difference_type;
10905     /// defines a pointer to the type iterated over (value_type)
10906     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
10907           typename BasicJsonType::const_pointer,
10908           typename BasicJsonType::pointer>::type;
10909     /// defines a reference to the type iterated over (value_type)
10910     using reference =
10911         typename std::conditional<std::is_const<BasicJsonType>::value,
10912         typename BasicJsonType::const_reference,
10913         typename BasicJsonType::reference>::type;
10914 
10915     /// default constructor
10916     iter_impl() = default;
10917 
10918     /*!
10919     @brief constructor for a given JSON instance
10920     @param[in] object  pointer to a JSON object for this iterator
10921     @pre object != nullptr
10922     @post The iterator is initialized; i.e. `m_object != nullptr`.
10923     */
iter_impl(pointer object)10924     explicit iter_impl(pointer object) noexcept : m_object(object)
10925     {
10926         JSON_ASSERT(m_object != nullptr);
10927 
10928         switch (m_object->m_type)
10929         {
10930             case value_t::object:
10931             {
10932                 m_it.object_iterator = typename object_t::iterator();
10933                 break;
10934             }
10935 
10936             case value_t::array:
10937             {
10938                 m_it.array_iterator = typename array_t::iterator();
10939                 break;
10940             }
10941 
10942             default:
10943             {
10944                 m_it.primitive_iterator = primitive_iterator_t();
10945                 break;
10946             }
10947         }
10948     }
10949 
10950     /*!
10951     @note The conventional copy constructor and copy assignment are implicitly
10952           defined. Combined with the following converting constructor and
10953           assignment, they support: (1) copy from iterator to iterator, (2)
10954           copy from const iterator to const iterator, and (3) conversion from
10955           iterator to const iterator. However conversion from const iterator
10956           to iterator is not defined.
10957     */
10958 
10959     /*!
10960     @brief const copy constructor
10961     @param[in] other const iterator to copy from
10962     @note This copy constructor had to be defined explicitly to circumvent a bug
10963           occurring on msvc v19.0 compiler (VS 2015) debug build. For more
10964           information refer to: https://github.com/nlohmann/json/issues/1608
10965     */
iter_impl(const iter_impl<const BasicJsonType> & other)10966     iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
10967         : m_object(other.m_object), m_it(other.m_it)
10968     {}
10969 
10970     /*!
10971     @brief converting assignment
10972     @param[in] other const iterator to copy from
10973     @return const/non-const iterator
10974     @note It is not checked whether @a other is initialized.
10975     */
operator =(const iter_impl<const BasicJsonType> & other)10976     iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
10977     {
10978         m_object = other.m_object;
10979         m_it = other.m_it;
10980         return *this;
10981     }
10982 
10983     /*!
10984     @brief converting constructor
10985     @param[in] other  non-const iterator to copy from
10986     @note It is not checked whether @a other is initialized.
10987     */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)10988     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10989         : m_object(other.m_object), m_it(other.m_it)
10990     {}
10991 
10992     /*!
10993     @brief converting assignment
10994     @param[in] other  non-const iterator to copy from
10995     @return const/non-const iterator
10996     @note It is not checked whether @a other is initialized.
10997     */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)10998     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
10999     {
11000         m_object = other.m_object;
11001         m_it = other.m_it;
11002         return *this;
11003     }
11004 
11005   JSON_PRIVATE_UNLESS_TESTED:
11006     /*!
11007     @brief set the iterator to the first value
11008     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11009     */
11010     void set_begin() noexcept
11011     {
11012         JSON_ASSERT(m_object != nullptr);
11013 
11014         switch (m_object->m_type)
11015         {
11016             case value_t::object:
11017             {
11018                 m_it.object_iterator = m_object->m_value.object->begin();
11019                 break;
11020             }
11021 
11022             case value_t::array:
11023             {
11024                 m_it.array_iterator = m_object->m_value.array->begin();
11025                 break;
11026             }
11027 
11028             case value_t::null:
11029             {
11030                 // set to end so begin()==end() is true: null is empty
11031                 m_it.primitive_iterator.set_end();
11032                 break;
11033             }
11034 
11035             default:
11036             {
11037                 m_it.primitive_iterator.set_begin();
11038                 break;
11039             }
11040         }
11041     }
11042 
11043     /*!
11044     @brief set the iterator past the last value
11045     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11046     */
set_end()11047     void set_end() noexcept
11048     {
11049         JSON_ASSERT(m_object != nullptr);
11050 
11051         switch (m_object->m_type)
11052         {
11053             case value_t::object:
11054             {
11055                 m_it.object_iterator = m_object->m_value.object->end();
11056                 break;
11057             }
11058 
11059             case value_t::array:
11060             {
11061                 m_it.array_iterator = m_object->m_value.array->end();
11062                 break;
11063             }
11064 
11065             default:
11066             {
11067                 m_it.primitive_iterator.set_end();
11068                 break;
11069             }
11070         }
11071     }
11072 
11073   public:
11074     /*!
11075     @brief return a reference to the value pointed to by the iterator
11076     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11077     */
operator *() const11078     reference operator*() const
11079     {
11080         JSON_ASSERT(m_object != nullptr);
11081 
11082         switch (m_object->m_type)
11083         {
11084             case value_t::object:
11085             {
11086                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11087                 return m_it.object_iterator->second;
11088             }
11089 
11090             case value_t::array:
11091             {
11092                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11093                 return *m_it.array_iterator;
11094             }
11095 
11096             case value_t::null:
11097                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11098 
11099             default:
11100             {
11101                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11102                 {
11103                     return *m_object;
11104                 }
11105 
11106                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11107             }
11108         }
11109     }
11110 
11111     /*!
11112     @brief dereference the iterator
11113     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11114     */
operator ->() const11115     pointer operator->() const
11116     {
11117         JSON_ASSERT(m_object != nullptr);
11118 
11119         switch (m_object->m_type)
11120         {
11121             case value_t::object:
11122             {
11123                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11124                 return &(m_it.object_iterator->second);
11125             }
11126 
11127             case value_t::array:
11128             {
11129                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11130                 return &*m_it.array_iterator;
11131             }
11132 
11133             default:
11134             {
11135                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11136                 {
11137                     return m_object;
11138                 }
11139 
11140                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11141             }
11142         }
11143     }
11144 
11145     /*!
11146     @brief post-increment (it++)
11147     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11148     */
operator ++(int)11149     iter_impl const operator++(int)
11150     {
11151         auto result = *this;
11152         ++(*this);
11153         return result;
11154     }
11155 
11156     /*!
11157     @brief pre-increment (++it)
11158     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11159     */
operator ++()11160     iter_impl& operator++()
11161     {
11162         JSON_ASSERT(m_object != nullptr);
11163 
11164         switch (m_object->m_type)
11165         {
11166             case value_t::object:
11167             {
11168                 std::advance(m_it.object_iterator, 1);
11169                 break;
11170             }
11171 
11172             case value_t::array:
11173             {
11174                 std::advance(m_it.array_iterator, 1);
11175                 break;
11176             }
11177 
11178             default:
11179             {
11180                 ++m_it.primitive_iterator;
11181                 break;
11182             }
11183         }
11184 
11185         return *this;
11186     }
11187 
11188     /*!
11189     @brief post-decrement (it--)
11190     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11191     */
operator --(int)11192     iter_impl const operator--(int)
11193     {
11194         auto result = *this;
11195         --(*this);
11196         return result;
11197     }
11198 
11199     /*!
11200     @brief pre-decrement (--it)
11201     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11202     */
operator --()11203     iter_impl& operator--()
11204     {
11205         JSON_ASSERT(m_object != nullptr);
11206 
11207         switch (m_object->m_type)
11208         {
11209             case value_t::object:
11210             {
11211                 std::advance(m_it.object_iterator, -1);
11212                 break;
11213             }
11214 
11215             case value_t::array:
11216             {
11217                 std::advance(m_it.array_iterator, -1);
11218                 break;
11219             }
11220 
11221             default:
11222             {
11223                 --m_it.primitive_iterator;
11224                 break;
11225             }
11226         }
11227 
11228         return *this;
11229     }
11230 
11231     /*!
11232     @brief  comparison: equal
11233     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11234     */
operator ==(const iter_impl & other) const11235     bool operator==(const iter_impl& other) const
11236     {
11237         // if objects are not the same, the comparison is undefined
11238         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11239         {
11240             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11241         }
11242 
11243         JSON_ASSERT(m_object != nullptr);
11244 
11245         switch (m_object->m_type)
11246         {
11247             case value_t::object:
11248                 return (m_it.object_iterator == other.m_it.object_iterator);
11249 
11250             case value_t::array:
11251                 return (m_it.array_iterator == other.m_it.array_iterator);
11252 
11253             default:
11254                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11255         }
11256     }
11257 
11258     /*!
11259     @brief  comparison: not equal
11260     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11261     */
operator !=(const iter_impl & other) const11262     bool operator!=(const iter_impl& other) const
11263     {
11264         return !operator==(other);
11265     }
11266 
11267     /*!
11268     @brief  comparison: smaller
11269     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11270     */
operator <(const iter_impl & other) const11271     bool operator<(const iter_impl& other) const
11272     {
11273         // if objects are not the same, the comparison is undefined
11274         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11275         {
11276             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
11277         }
11278 
11279         JSON_ASSERT(m_object != nullptr);
11280 
11281         switch (m_object->m_type)
11282         {
11283             case value_t::object:
11284                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
11285 
11286             case value_t::array:
11287                 return (m_it.array_iterator < other.m_it.array_iterator);
11288 
11289             default:
11290                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
11291         }
11292     }
11293 
11294     /*!
11295     @brief  comparison: less than or equal
11296     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11297     */
operator <=(const iter_impl & other) const11298     bool operator<=(const iter_impl& other) const
11299     {
11300         return !other.operator < (*this);
11301     }
11302 
11303     /*!
11304     @brief  comparison: greater than
11305     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11306     */
operator >(const iter_impl & other) const11307     bool operator>(const iter_impl& other) const
11308     {
11309         return !operator<=(other);
11310     }
11311 
11312     /*!
11313     @brief  comparison: greater than or equal
11314     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11315     */
operator >=(const iter_impl & other) const11316     bool operator>=(const iter_impl& other) const
11317     {
11318         return !operator<(other);
11319     }
11320 
11321     /*!
11322     @brief  add to iterator
11323     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11324     */
operator +=(difference_type i)11325     iter_impl& operator+=(difference_type i)
11326     {
11327         JSON_ASSERT(m_object != nullptr);
11328 
11329         switch (m_object->m_type)
11330         {
11331             case value_t::object:
11332                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11333 
11334             case value_t::array:
11335             {
11336                 std::advance(m_it.array_iterator, i);
11337                 break;
11338             }
11339 
11340             default:
11341             {
11342                 m_it.primitive_iterator += i;
11343                 break;
11344             }
11345         }
11346 
11347         return *this;
11348     }
11349 
11350     /*!
11351     @brief  subtract from iterator
11352     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11353     */
operator -=(difference_type i)11354     iter_impl& operator-=(difference_type i)
11355     {
11356         return operator+=(-i);
11357     }
11358 
11359     /*!
11360     @brief  add to iterator
11361     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11362     */
operator +(difference_type i) const11363     iter_impl operator+(difference_type i) const
11364     {
11365         auto result = *this;
11366         result += i;
11367         return result;
11368     }
11369 
11370     /*!
11371     @brief  addition of distance and iterator
11372     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11373     */
operator +(difference_type i,const iter_impl & it)11374     friend iter_impl operator+(difference_type i, const iter_impl& it)
11375     {
11376         auto result = it;
11377         result += i;
11378         return result;
11379     }
11380 
11381     /*!
11382     @brief  subtract from iterator
11383     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11384     */
operator -(difference_type i) const11385     iter_impl operator-(difference_type i) const
11386     {
11387         auto result = *this;
11388         result -= i;
11389         return result;
11390     }
11391 
11392     /*!
11393     @brief  return difference
11394     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11395     */
operator -(const iter_impl & other) const11396     difference_type operator-(const iter_impl& other) const
11397     {
11398         JSON_ASSERT(m_object != nullptr);
11399 
11400         switch (m_object->m_type)
11401         {
11402             case value_t::object:
11403                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
11404 
11405             case value_t::array:
11406                 return m_it.array_iterator - other.m_it.array_iterator;
11407 
11408             default:
11409                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
11410         }
11411     }
11412 
11413     /*!
11414     @brief  access to successor
11415     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11416     */
operator [](difference_type n) const11417     reference operator[](difference_type n) const
11418     {
11419         JSON_ASSERT(m_object != nullptr);
11420 
11421         switch (m_object->m_type)
11422         {
11423             case value_t::object:
11424                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
11425 
11426             case value_t::array:
11427                 return *std::next(m_it.array_iterator, n);
11428 
11429             case value_t::null:
11430                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11431 
11432             default:
11433             {
11434                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
11435                 {
11436                     return *m_object;
11437                 }
11438 
11439                 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
11440             }
11441         }
11442     }
11443 
11444     /*!
11445     @brief  return the key of an object iterator
11446     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11447     */
key() const11448     const typename object_t::key_type& key() const
11449     {
11450         JSON_ASSERT(m_object != nullptr);
11451 
11452         if (JSON_HEDLEY_LIKELY(m_object->is_object()))
11453         {
11454             return m_it.object_iterator->first;
11455         }
11456 
11457         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
11458     }
11459 
11460     /*!
11461     @brief  return the value of an iterator
11462     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11463     */
value() const11464     reference value() const
11465     {
11466         return operator*();
11467     }
11468 
11469   JSON_PRIVATE_UNLESS_TESTED:
11470     /// associated JSON instance
11471     pointer m_object = nullptr;
11472     /// the actual iterator of the associated instance
11473     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
11474 };
11475 } // namespace detail
11476 } // namespace nlohmann
11477 
11478 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
11479 
11480 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
11481 
11482 
11483 #include <cstddef> // ptrdiff_t
11484 #include <iterator> // reverse_iterator
11485 #include <utility> // declval
11486 
11487 namespace nlohmann
11488 {
11489 namespace detail
11490 {
11491 //////////////////////
11492 // reverse_iterator //
11493 //////////////////////
11494 
11495 /*!
11496 @brief a template for a reverse iterator class
11497 
11498 @tparam Base the base iterator type to reverse. Valid types are @ref
11499 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
11500 create @ref const_reverse_iterator).
11501 
11502 @requirement The class satisfies the following concept requirements:
11503 -
11504 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11505   The iterator that can be moved can be moved in both directions (i.e.
11506   incremented and decremented).
11507 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
11508   It is possible to write to the pointed-to element (only if @a Base is
11509   @ref iterator).
11510 
11511 @since version 1.0.0
11512 */
11513 template<typename Base>
11514 class json_reverse_iterator : public std::reverse_iterator<Base>
11515 {
11516   public:
11517     using difference_type = std::ptrdiff_t;
11518     /// shortcut to the reverse iterator adapter
11519     using base_iterator = std::reverse_iterator<Base>;
11520     /// the reference type for the pointed-to element
11521     using reference = typename Base::reference;
11522 
11523     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)11524     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
11525         : base_iterator(it) {}
11526 
11527     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)11528     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
11529 
11530     /// post-increment (it++)
operator ++(int)11531     json_reverse_iterator const operator++(int)
11532     {
11533         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
11534     }
11535 
11536     /// pre-increment (++it)
operator ++()11537     json_reverse_iterator& operator++()
11538     {
11539         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
11540     }
11541 
11542     /// post-decrement (it--)
operator --(int)11543     json_reverse_iterator const operator--(int)
11544     {
11545         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
11546     }
11547 
11548     /// pre-decrement (--it)
operator --()11549     json_reverse_iterator& operator--()
11550     {
11551         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
11552     }
11553 
11554     /// add to iterator
operator +=(difference_type i)11555     json_reverse_iterator& operator+=(difference_type i)
11556     {
11557         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
11558     }
11559 
11560     /// add to iterator
operator +(difference_type i) const11561     json_reverse_iterator operator+(difference_type i) const
11562     {
11563         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
11564     }
11565 
11566     /// subtract from iterator
operator -(difference_type i) const11567     json_reverse_iterator operator-(difference_type i) const
11568     {
11569         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
11570     }
11571 
11572     /// return difference
operator -(const json_reverse_iterator & other) const11573     difference_type operator-(const json_reverse_iterator& other) const
11574     {
11575         return base_iterator(*this) - base_iterator(other);
11576     }
11577 
11578     /// access to successor
operator [](difference_type n) const11579     reference operator[](difference_type n) const
11580     {
11581         return *(this->operator+(n));
11582     }
11583 
11584     /// return the key of an object iterator
key() const11585     auto key() const -> decltype(std::declval<Base>().key())
11586     {
11587         auto it = --this->base();
11588         return it.key();
11589     }
11590 
11591     /// return the value of an iterator
value() const11592     reference value() const
11593     {
11594         auto it = --this->base();
11595         return it.operator * ();
11596     }
11597 };
11598 }  // namespace detail
11599 }  // namespace nlohmann
11600 
11601 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11602 
11603 // #include <nlohmann/detail/json_pointer.hpp>
11604 
11605 
11606 #include <algorithm> // all_of
11607 #include <cctype> // isdigit
11608 #include <limits> // max
11609 #include <numeric> // accumulate
11610 #include <string> // string
11611 #include <utility> // move
11612 #include <vector> // vector
11613 
11614 // #include <nlohmann/detail/exceptions.hpp>
11615 
11616 // #include <nlohmann/detail/macro_scope.hpp>
11617 
11618 // #include <nlohmann/detail/value_t.hpp>
11619 
11620 
11621 namespace nlohmann
11622 {
11623 template<typename BasicJsonType>
11624 class json_pointer
11625 {
11626     // allow basic_json to access private members
11627     NLOHMANN_BASIC_JSON_TPL_DECLARATION
11628     friend class basic_json;
11629 
11630   public:
11631     /*!
11632     @brief create JSON pointer
11633 
11634     Create a JSON pointer according to the syntax described in
11635     [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
11636 
11637     @param[in] s  string representing the JSON pointer; if omitted, the empty
11638                   string is assumed which references the whole JSON value
11639 
11640     @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
11641                            not begin with a slash (`/`); see example below
11642 
11643     @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
11644     not followed by `0` (representing `~`) or `1` (representing `/`); see
11645     example below
11646 
11647     @liveexample{The example shows the construction several valid JSON pointers
11648     as well as the exceptional behavior.,json_pointer}
11649 
11650     @since version 2.0.0
11651     */
json_pointer(const std::string & s="")11652     explicit json_pointer(const std::string& s = "")
11653         : reference_tokens(split(s))
11654     {}
11655 
11656     /*!
11657     @brief return a string representation of the JSON pointer
11658 
11659     @invariant For each JSON pointer `ptr`, it holds:
11660     @code {.cpp}
11661     ptr == json_pointer(ptr.to_string());
11662     @endcode
11663 
11664     @return a string representation of the JSON pointer
11665 
11666     @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
11667 
11668     @since version 2.0.0
11669     */
to_string() const11670     std::string to_string() const
11671     {
11672         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
11673                                std::string{},
11674                                [](const std::string & a, const std::string & b)
11675         {
11676             return a + "/" + escape(b);
11677         });
11678     }
11679 
11680     /// @copydoc to_string()
operator std::string() const11681     operator std::string() const
11682     {
11683         return to_string();
11684     }
11685 
11686     /*!
11687     @brief append another JSON pointer at the end of this JSON pointer
11688 
11689     @param[in] ptr  JSON pointer to append
11690     @return JSON pointer with @a ptr appended
11691 
11692     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11693 
11694     @complexity Linear in the length of @a ptr.
11695 
11696     @sa @ref operator/=(std::string) to append a reference token
11697     @sa @ref operator/=(std::size_t) to append an array index
11698     @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
11699 
11700     @since version 3.6.0
11701     */
operator /=(const json_pointer & ptr)11702     json_pointer& operator/=(const json_pointer& ptr)
11703     {
11704         reference_tokens.insert(reference_tokens.end(),
11705                                 ptr.reference_tokens.begin(),
11706                                 ptr.reference_tokens.end());
11707         return *this;
11708     }
11709 
11710     /*!
11711     @brief append an unescaped reference token at the end of this JSON pointer
11712 
11713     @param[in] token  reference token to append
11714     @return JSON pointer with @a token appended without escaping @a token
11715 
11716     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11717 
11718     @complexity Amortized constant.
11719 
11720     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11721     @sa @ref operator/=(std::size_t) to append an array index
11722     @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
11723 
11724     @since version 3.6.0
11725     */
operator /=(std::string token)11726     json_pointer& operator/=(std::string token)
11727     {
11728         push_back(std::move(token));
11729         return *this;
11730     }
11731 
11732     /*!
11733     @brief append an array index at the end of this JSON pointer
11734 
11735     @param[in] array_idx  array index to append
11736     @return JSON pointer with @a array_idx appended
11737 
11738     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
11739 
11740     @complexity Amortized constant.
11741 
11742     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11743     @sa @ref operator/=(std::string) to append a reference token
11744     @sa @ref operator/(const json_pointer&, std::string) for a binary operator
11745 
11746     @since version 3.6.0
11747     */
operator /=(std::size_t array_idx)11748     json_pointer& operator/=(std::size_t array_idx)
11749     {
11750         return *this /= std::to_string(array_idx);
11751     }
11752 
11753     /*!
11754     @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
11755 
11756     @param[in] lhs  JSON pointer
11757     @param[in] rhs  JSON pointer
11758     @return a new JSON pointer with @a rhs appended to @a lhs
11759 
11760     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11761 
11762     @complexity Linear in the length of @a lhs and @a rhs.
11763 
11764     @sa @ref operator/=(const json_pointer&) to append a JSON pointer
11765 
11766     @since version 3.6.0
11767     */
operator /(const json_pointer & lhs,const json_pointer & rhs)11768     friend json_pointer operator/(const json_pointer& lhs,
11769                                   const json_pointer& rhs)
11770     {
11771         return json_pointer(lhs) /= rhs;
11772     }
11773 
11774     /*!
11775     @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
11776 
11777     @param[in] ptr  JSON pointer
11778     @param[in] token  reference token
11779     @return a new JSON pointer with unescaped @a token appended to @a ptr
11780 
11781     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11782 
11783     @complexity Linear in the length of @a ptr.
11784 
11785     @sa @ref operator/=(std::string) to append a reference token
11786 
11787     @since version 3.6.0
11788     */
operator /(const json_pointer & ptr,std::string token)11789     friend json_pointer operator/(const json_pointer& ptr, std::string token)
11790     {
11791         return json_pointer(ptr) /= std::move(token);
11792     }
11793 
11794     /*!
11795     @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
11796 
11797     @param[in] ptr  JSON pointer
11798     @param[in] array_idx  array index
11799     @return a new JSON pointer with @a array_idx appended to @a ptr
11800 
11801     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
11802 
11803     @complexity Linear in the length of @a ptr.
11804 
11805     @sa @ref operator/=(std::size_t) to append an array index
11806 
11807     @since version 3.6.0
11808     */
operator /(const json_pointer & ptr,std::size_t array_idx)11809     friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
11810     {
11811         return json_pointer(ptr) /= array_idx;
11812     }
11813 
11814     /*!
11815     @brief returns the parent of this JSON pointer
11816 
11817     @return parent of this JSON pointer; in case this JSON pointer is the root,
11818             the root itself is returned
11819 
11820     @complexity Linear in the length of the JSON pointer.
11821 
11822     @liveexample{The example shows the result of `parent_pointer` for different
11823     JSON Pointers.,json_pointer__parent_pointer}
11824 
11825     @since version 3.6.0
11826     */
parent_pointer() const11827     json_pointer parent_pointer() const
11828     {
11829         if (empty())
11830         {
11831             return *this;
11832         }
11833 
11834         json_pointer res = *this;
11835         res.pop_back();
11836         return res;
11837     }
11838 
11839     /*!
11840     @brief remove last reference token
11841 
11842     @pre not `empty()`
11843 
11844     @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
11845 
11846     @complexity Constant.
11847 
11848     @throw out_of_range.405 if JSON pointer has no parent
11849 
11850     @since version 3.6.0
11851     */
pop_back()11852     void pop_back()
11853     {
11854         if (JSON_HEDLEY_UNLIKELY(empty()))
11855         {
11856             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11857         }
11858 
11859         reference_tokens.pop_back();
11860     }
11861 
11862     /*!
11863     @brief return last reference token
11864 
11865     @pre not `empty()`
11866     @return last reference token
11867 
11868     @liveexample{The example shows the usage of `back`.,json_pointer__back}
11869 
11870     @complexity Constant.
11871 
11872     @throw out_of_range.405 if JSON pointer has no parent
11873 
11874     @since version 3.6.0
11875     */
back() const11876     const std::string& back() const
11877     {
11878         if (JSON_HEDLEY_UNLIKELY(empty()))
11879         {
11880             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11881         }
11882 
11883         return reference_tokens.back();
11884     }
11885 
11886     /*!
11887     @brief append an unescaped token at the end of the reference pointer
11888 
11889     @param[in] token  token to add
11890 
11891     @complexity Amortized constant.
11892 
11893     @liveexample{The example shows the result of `push_back` for different
11894     JSON Pointers.,json_pointer__push_back}
11895 
11896     @since version 3.6.0
11897     */
push_back(const std::string & token)11898     void push_back(const std::string& token)
11899     {
11900         reference_tokens.push_back(token);
11901     }
11902 
11903     /// @copydoc push_back(const std::string&)
push_back(std::string && token)11904     void push_back(std::string&& token)
11905     {
11906         reference_tokens.push_back(std::move(token));
11907     }
11908 
11909     /*!
11910     @brief return whether pointer points to the root document
11911 
11912     @return true iff the JSON pointer points to the root document
11913 
11914     @complexity Constant.
11915 
11916     @exceptionsafety No-throw guarantee: this function never throws exceptions.
11917 
11918     @liveexample{The example shows the result of `empty` for different JSON
11919     Pointers.,json_pointer__empty}
11920 
11921     @since version 3.6.0
11922     */
empty() const11923     bool empty() const noexcept
11924     {
11925         return reference_tokens.empty();
11926     }
11927 
11928   private:
11929     /*!
11930     @param[in] s  reference token to be converted into an array index
11931 
11932     @return integer representation of @a s
11933 
11934     @throw parse_error.106  if an array index begins with '0'
11935     @throw parse_error.109  if an array index begins not with a digit
11936     @throw out_of_range.404 if string @a s could not be converted to an integer
11937     @throw out_of_range.410 if an array index exceeds size_type
11938     */
array_index(const std::string & s)11939     static typename BasicJsonType::size_type array_index(const std::string& s)
11940     {
11941         using size_type = typename BasicJsonType::size_type;
11942 
11943         // error condition (cf. RFC 6901, Sect. 4)
11944         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
11945         {
11946             JSON_THROW(detail::parse_error::create(106, 0,
11947                                                    "array index '" + s +
11948                                                    "' must not begin with '0'"));
11949         }
11950 
11951         // error condition (cf. RFC 6901, Sect. 4)
11952         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
11953         {
11954             JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number"));
11955         }
11956 
11957         std::size_t processed_chars = 0;
11958         unsigned long long res = 0;
11959         JSON_TRY
11960         {
11961             res = std::stoull(s, &processed_chars);
11962         }
11963         JSON_CATCH(std::out_of_range&)
11964         {
11965             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11966         }
11967 
11968         // check if the string was completely read
11969         if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
11970         {
11971             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
11972         }
11973 
11974         // only triggered on special platforms (like 32bit), see also
11975         // https://github.com/nlohmann/json/pull/2203
11976         if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))
11977         {
11978             JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type")); // LCOV_EXCL_LINE
11979         }
11980 
11981         return static_cast<size_type>(res);
11982     }
11983 
11984   JSON_PRIVATE_UNLESS_TESTED:
11985     json_pointer top() const
11986     {
11987         if (JSON_HEDLEY_UNLIKELY(empty()))
11988         {
11989             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
11990         }
11991 
11992         json_pointer result = *this;
11993         result.reference_tokens = {reference_tokens[0]};
11994         return result;
11995     }
11996 
11997   private:
11998     /*!
11999     @brief create and return a reference to the pointed to value
12000 
12001     @complexity Linear in the number of reference tokens.
12002 
12003     @throw parse_error.109 if array index is not a number
12004     @throw type_error.313 if value cannot be unflattened
12005     */
get_and_create(BasicJsonType & j) const12006     BasicJsonType& get_and_create(BasicJsonType& j) const
12007     {
12008         auto result = &j;
12009 
12010         // in case no reference tokens exist, return a reference to the JSON value
12011         // j which will be overwritten by a primitive value
12012         for (const auto& reference_token : reference_tokens)
12013         {
12014             switch (result->type())
12015             {
12016                 case detail::value_t::null:
12017                 {
12018                     if (reference_token == "0")
12019                     {
12020                         // start a new array if reference token is 0
12021                         result = &result->operator[](0);
12022                     }
12023                     else
12024                     {
12025                         // start a new object otherwise
12026                         result = &result->operator[](reference_token);
12027                     }
12028                     break;
12029                 }
12030 
12031                 case detail::value_t::object:
12032                 {
12033                     // create an entry in the object
12034                     result = &result->operator[](reference_token);
12035                     break;
12036                 }
12037 
12038                 case detail::value_t::array:
12039                 {
12040                     // create an entry in the array
12041                     result = &result->operator[](array_index(reference_token));
12042                     break;
12043                 }
12044 
12045                 /*
12046                 The following code is only reached if there exists a reference
12047                 token _and_ the current value is primitive. In this case, we have
12048                 an error situation, because primitive values may only occur as
12049                 single value; that is, with an empty list of reference tokens.
12050                 */
12051                 default:
12052                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
12053             }
12054         }
12055 
12056         return *result;
12057     }
12058 
12059     /*!
12060     @brief return a reference to the pointed to value
12061 
12062     @note This version does not throw if a value is not present, but tries to
12063           create nested values instead. For instance, calling this function
12064           with pointer `"/this/that"` on a null value is equivalent to calling
12065           `operator[]("this").operator[]("that")` on that value, effectively
12066           changing the null value to an object.
12067 
12068     @param[in] ptr  a JSON value
12069 
12070     @return reference to the JSON value pointed to by the JSON pointer
12071 
12072     @complexity Linear in the length of the JSON pointer.
12073 
12074     @throw parse_error.106   if an array index begins with '0'
12075     @throw parse_error.109   if an array index was not a number
12076     @throw out_of_range.404  if the JSON pointer can not be resolved
12077     */
get_unchecked(BasicJsonType * ptr) const12078     BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12079     {
12080         for (const auto& reference_token : reference_tokens)
12081         {
12082             // convert null values to arrays or objects before continuing
12083             if (ptr->is_null())
12084             {
12085                 // check if reference token is a number
12086                 const bool nums =
12087                     std::all_of(reference_token.begin(), reference_token.end(),
12088                                 [](const unsigned char x)
12089                 {
12090                     return std::isdigit(x);
12091                 });
12092 
12093                 // change value to array for numbers or "-" or to object otherwise
12094                 *ptr = (nums || reference_token == "-")
12095                        ? detail::value_t::array
12096                        : detail::value_t::object;
12097             }
12098 
12099             switch (ptr->type())
12100             {
12101                 case detail::value_t::object:
12102                 {
12103                     // use unchecked object access
12104                     ptr = &ptr->operator[](reference_token);
12105                     break;
12106                 }
12107 
12108                 case detail::value_t::array:
12109                 {
12110                     if (reference_token == "-")
12111                     {
12112                         // explicitly treat "-" as index beyond the end
12113                         ptr = &ptr->operator[](ptr->m_value.array->size());
12114                     }
12115                     else
12116                     {
12117                         // convert array index to number; unchecked access
12118                         ptr = &ptr->operator[](array_index(reference_token));
12119                     }
12120                     break;
12121                 }
12122 
12123                 default:
12124                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12125             }
12126         }
12127 
12128         return *ptr;
12129     }
12130 
12131     /*!
12132     @throw parse_error.106   if an array index begins with '0'
12133     @throw parse_error.109   if an array index was not a number
12134     @throw out_of_range.402  if the array index '-' is used
12135     @throw out_of_range.404  if the JSON pointer can not be resolved
12136     */
get_checked(BasicJsonType * ptr) const12137     BasicJsonType& get_checked(BasicJsonType* ptr) const
12138     {
12139         for (const auto& reference_token : reference_tokens)
12140         {
12141             switch (ptr->type())
12142             {
12143                 case detail::value_t::object:
12144                 {
12145                     // note: at performs range check
12146                     ptr = &ptr->at(reference_token);
12147                     break;
12148                 }
12149 
12150                 case detail::value_t::array:
12151                 {
12152                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12153                     {
12154                         // "-" always fails the range check
12155                         JSON_THROW(detail::out_of_range::create(402,
12156                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12157                                                                 ") is out of range"));
12158                     }
12159 
12160                     // note: at performs range check
12161                     ptr = &ptr->at(array_index(reference_token));
12162                     break;
12163                 }
12164 
12165                 default:
12166                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12167             }
12168         }
12169 
12170         return *ptr;
12171     }
12172 
12173     /*!
12174     @brief return a const reference to the pointed to value
12175 
12176     @param[in] ptr  a JSON value
12177 
12178     @return const reference to the JSON value pointed to by the JSON
12179     pointer
12180 
12181     @throw parse_error.106   if an array index begins with '0'
12182     @throw parse_error.109   if an array index was not a number
12183     @throw out_of_range.402  if the array index '-' is used
12184     @throw out_of_range.404  if the JSON pointer can not be resolved
12185     */
get_unchecked(const BasicJsonType * ptr) const12186     const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12187     {
12188         for (const auto& reference_token : reference_tokens)
12189         {
12190             switch (ptr->type())
12191             {
12192                 case detail::value_t::object:
12193                 {
12194                     // use unchecked object access
12195                     ptr = &ptr->operator[](reference_token);
12196                     break;
12197                 }
12198 
12199                 case detail::value_t::array:
12200                 {
12201                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12202                     {
12203                         // "-" cannot be used for const access
12204                         JSON_THROW(detail::out_of_range::create(402,
12205                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12206                                                                 ") is out of range"));
12207                     }
12208 
12209                     // use unchecked array access
12210                     ptr = &ptr->operator[](array_index(reference_token));
12211                     break;
12212                 }
12213 
12214                 default:
12215                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12216             }
12217         }
12218 
12219         return *ptr;
12220     }
12221 
12222     /*!
12223     @throw parse_error.106   if an array index begins with '0'
12224     @throw parse_error.109   if an array index was not a number
12225     @throw out_of_range.402  if the array index '-' is used
12226     @throw out_of_range.404  if the JSON pointer can not be resolved
12227     */
get_checked(const BasicJsonType * ptr) const12228     const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12229     {
12230         for (const auto& reference_token : reference_tokens)
12231         {
12232             switch (ptr->type())
12233             {
12234                 case detail::value_t::object:
12235                 {
12236                     // note: at performs range check
12237                     ptr = &ptr->at(reference_token);
12238                     break;
12239                 }
12240 
12241                 case detail::value_t::array:
12242                 {
12243                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12244                     {
12245                         // "-" always fails the range check
12246                         JSON_THROW(detail::out_of_range::create(402,
12247                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12248                                                                 ") is out of range"));
12249                     }
12250 
12251                     // note: at performs range check
12252                     ptr = &ptr->at(array_index(reference_token));
12253                     break;
12254                 }
12255 
12256                 default:
12257                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
12258             }
12259         }
12260 
12261         return *ptr;
12262     }
12263 
12264     /*!
12265     @throw parse_error.106   if an array index begins with '0'
12266     @throw parse_error.109   if an array index was not a number
12267     */
contains(const BasicJsonType * ptr) const12268     bool contains(const BasicJsonType* ptr) const
12269     {
12270         for (const auto& reference_token : reference_tokens)
12271         {
12272             switch (ptr->type())
12273             {
12274                 case detail::value_t::object:
12275                 {
12276                     if (!ptr->contains(reference_token))
12277                     {
12278                         // we did not find the key in the object
12279                         return false;
12280                     }
12281 
12282                     ptr = &ptr->operator[](reference_token);
12283                     break;
12284                 }
12285 
12286                 case detail::value_t::array:
12287                 {
12288                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12289                     {
12290                         // "-" always fails the range check
12291                         return false;
12292                     }
12293                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12294                     {
12295                         // invalid char
12296                         return false;
12297                     }
12298                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12299                     {
12300                         if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12301                         {
12302                             // first char should be between '1' and '9'
12303                             return false;
12304                         }
12305                         for (std::size_t i = 1; i < reference_token.size(); i++)
12306                         {
12307                             if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12308                             {
12309                                 // other char should be between '0' and '9'
12310                                 return false;
12311                             }
12312                         }
12313                     }
12314 
12315                     const auto idx = array_index(reference_token);
12316                     if (idx >= ptr->size())
12317                     {
12318                         // index out of range
12319                         return false;
12320                     }
12321 
12322                     ptr = &ptr->operator[](idx);
12323                     break;
12324                 }
12325 
12326                 default:
12327                 {
12328                     // we do not expect primitive values if there is still a
12329                     // reference token to process
12330                     return false;
12331                 }
12332             }
12333         }
12334 
12335         // no reference token left means we found a primitive value
12336         return true;
12337     }
12338 
12339     /*!
12340     @brief split the string input to reference tokens
12341 
12342     @note This function is only called by the json_pointer constructor.
12343           All exceptions below are documented there.
12344 
12345     @throw parse_error.107  if the pointer is not empty or begins with '/'
12346     @throw parse_error.108  if character '~' is not followed by '0' or '1'
12347     */
split(const std::string & reference_string)12348     static std::vector<std::string> split(const std::string& reference_string)
12349     {
12350         std::vector<std::string> result;
12351 
12352         // special case: empty reference string -> no reference tokens
12353         if (reference_string.empty())
12354         {
12355             return result;
12356         }
12357 
12358         // check if nonempty reference string begins with slash
12359         if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12360         {
12361             JSON_THROW(detail::parse_error::create(107, 1,
12362                                                    "JSON pointer must be empty or begin with '/' - was: '" +
12363                                                    reference_string + "'"));
12364         }
12365 
12366         // extract the reference tokens:
12367         // - slash: position of the last read slash (or end of string)
12368         // - start: position after the previous slash
12369         for (
12370             // search for the first slash after the first character
12371             std::size_t slash = reference_string.find_first_of('/', 1),
12372             // set the beginning of the first reference token
12373             start = 1;
12374             // we can stop if start == 0 (if slash == std::string::npos)
12375             start != 0;
12376             // set the beginning of the next reference token
12377             // (will eventually be 0 if slash == std::string::npos)
12378             start = (slash == std::string::npos) ? 0 : slash + 1,
12379             // find next slash
12380             slash = reference_string.find_first_of('/', start))
12381         {
12382             // use the text between the beginning of the reference token
12383             // (start) and the last slash (slash).
12384             auto reference_token = reference_string.substr(start, slash - start);
12385 
12386             // check reference tokens are properly escaped
12387             for (std::size_t pos = reference_token.find_first_of('~');
12388                     pos != std::string::npos;
12389                     pos = reference_token.find_first_of('~', pos + 1))
12390             {
12391                 JSON_ASSERT(reference_token[pos] == '~');
12392 
12393                 // ~ must be followed by 0 or 1
12394                 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12395                                          (reference_token[pos + 1] != '0' &&
12396                                           reference_token[pos + 1] != '1')))
12397                 {
12398                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
12399                 }
12400             }
12401 
12402             // finally, store the reference token
12403             unescape(reference_token);
12404             result.push_back(reference_token);
12405         }
12406 
12407         return result;
12408     }
12409 
12410     /*!
12411     @brief replace all occurrences of a substring by another string
12412 
12413     @param[in,out] s  the string to manipulate; changed so that all
12414                    occurrences of @a f are replaced with @a t
12415     @param[in]     f  the substring to replace with @a t
12416     @param[in]     t  the string to replace @a f
12417 
12418     @pre The search string @a f must not be empty. **This precondition is
12419     enforced with an assertion.**
12420 
12421     @since version 2.0.0
12422     */
replace_substring(std::string & s,const std::string & f,const std::string & t)12423     static void replace_substring(std::string& s, const std::string& f,
12424                                   const std::string& t)
12425     {
12426         JSON_ASSERT(!f.empty());
12427         for (auto pos = s.find(f);                // find first occurrence of f
12428                 pos != std::string::npos;         // make sure f was found
12429                 s.replace(pos, f.size(), t),      // replace with t, and
12430                 pos = s.find(f, pos + t.size()))  // find next occurrence of f
12431         {}
12432     }
12433 
12434   JSON_PRIVATE_UNLESS_TESTED:
12435     /// escape "~" to "~0" and "/" to "~1"
12436     static std::string escape(std::string s)
12437     {
12438         replace_substring(s, "~", "~0");
12439         replace_substring(s, "/", "~1");
12440         return s;
12441     }
12442 
12443     /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)12444     static void unescape(std::string& s)
12445     {
12446         replace_substring(s, "~1", "/");
12447         replace_substring(s, "~0", "~");
12448     }
12449 
12450   private:
12451     /*!
12452     @param[in] reference_string  the reference string to the current value
12453     @param[in] value             the value to consider
12454     @param[in,out] result        the result object to insert values to
12455 
12456     @note Empty objects or arrays are flattened to `null`.
12457     */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)12458     static void flatten(const std::string& reference_string,
12459                         const BasicJsonType& value,
12460                         BasicJsonType& result)
12461     {
12462         switch (value.type())
12463         {
12464             case detail::value_t::array:
12465             {
12466                 if (value.m_value.array->empty())
12467                 {
12468                     // flatten empty array as null
12469                     result[reference_string] = nullptr;
12470                 }
12471                 else
12472                 {
12473                     // iterate array and use index as reference string
12474                     for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12475                     {
12476                         flatten(reference_string + "/" + std::to_string(i),
12477                                 value.m_value.array->operator[](i), result);
12478                     }
12479                 }
12480                 break;
12481             }
12482 
12483             case detail::value_t::object:
12484             {
12485                 if (value.m_value.object->empty())
12486                 {
12487                     // flatten empty object as null
12488                     result[reference_string] = nullptr;
12489                 }
12490                 else
12491                 {
12492                     // iterate object and use keys as reference string
12493                     for (const auto& element : *value.m_value.object)
12494                     {
12495                         flatten(reference_string + "/" + escape(element.first), element.second, result);
12496                     }
12497                 }
12498                 break;
12499             }
12500 
12501             default:
12502             {
12503                 // add primitive value with its reference string
12504                 result[reference_string] = value;
12505                 break;
12506             }
12507         }
12508     }
12509 
12510     /*!
12511     @param[in] value  flattened JSON
12512 
12513     @return unflattened JSON
12514 
12515     @throw parse_error.109 if array index is not a number
12516     @throw type_error.314  if value is not an object
12517     @throw type_error.315  if object values are not primitive
12518     @throw type_error.313  if value cannot be unflattened
12519     */
12520     static BasicJsonType
unflatten(const BasicJsonType & value)12521     unflatten(const BasicJsonType& value)
12522     {
12523         if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
12524         {
12525             JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
12526         }
12527 
12528         BasicJsonType result;
12529 
12530         // iterate the JSON object values
12531         for (const auto& element : *value.m_value.object)
12532         {
12533             if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
12534             {
12535                 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
12536             }
12537 
12538             // assign value to reference pointed to by JSON pointer; Note that if
12539             // the JSON pointer is "" (i.e., points to the whole value), function
12540             // get_and_create returns a reference to result itself. An assignment
12541             // will then create a primitive value.
12542             json_pointer(element.first).get_and_create(result) = element.second;
12543         }
12544 
12545         return result;
12546     }
12547 
12548     /*!
12549     @brief compares two JSON pointers for equality
12550 
12551     @param[in] lhs  JSON pointer to compare
12552     @param[in] rhs  JSON pointer to compare
12553     @return whether @a lhs is equal to @a rhs
12554 
12555     @complexity Linear in the length of the JSON pointer
12556 
12557     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12558     */
operator ==(json_pointer const & lhs,json_pointer const & rhs)12559     friend bool operator==(json_pointer const& lhs,
12560                            json_pointer const& rhs) noexcept
12561     {
12562         return lhs.reference_tokens == rhs.reference_tokens;
12563     }
12564 
12565     /*!
12566     @brief compares two JSON pointers for inequality
12567 
12568     @param[in] lhs  JSON pointer to compare
12569     @param[in] rhs  JSON pointer to compare
12570     @return whether @a lhs is not equal @a rhs
12571 
12572     @complexity Linear in the length of the JSON pointer
12573 
12574     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12575     */
operator !=(json_pointer const & lhs,json_pointer const & rhs)12576     friend bool operator!=(json_pointer const& lhs,
12577                            json_pointer const& rhs) noexcept
12578     {
12579         return !(lhs == rhs);
12580     }
12581 
12582     /// the reference tokens
12583     std::vector<std::string> reference_tokens;
12584 };
12585 }  // namespace nlohmann
12586 
12587 // #include <nlohmann/detail/json_ref.hpp>
12588 
12589 
12590 #include <initializer_list>
12591 #include <utility>
12592 
12593 // #include <nlohmann/detail/meta/type_traits.hpp>
12594 
12595 
12596 namespace nlohmann
12597 {
12598 namespace detail
12599 {
12600 template<typename BasicJsonType>
12601 class json_ref
12602 {
12603   public:
12604     using value_type = BasicJsonType;
12605 
json_ref(value_type && value)12606     json_ref(value_type&& value)
12607         : owned_value(std::move(value))
12608         , value_ref(&owned_value)
12609         , is_rvalue(true)
12610     {}
12611 
json_ref(const value_type & value)12612     json_ref(const value_type& value)
12613         : value_ref(const_cast<value_type*>(&value))
12614         , is_rvalue(false)
12615     {}
12616 
json_ref(std::initializer_list<json_ref> init)12617     json_ref(std::initializer_list<json_ref> init)
12618         : owned_value(init)
12619         , value_ref(&owned_value)
12620         , is_rvalue(true)
12621     {}
12622 
12623     template <
12624         class... Args,
12625         enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)12626     json_ref(Args && ... args)
12627         : owned_value(std::forward<Args>(args)...)
12628         , value_ref(&owned_value)
12629         , is_rvalue(true)
12630     {}
12631 
12632     // class should be movable only
12633     json_ref(json_ref&&) = default;
12634     json_ref(const json_ref&) = delete;
12635     json_ref& operator=(const json_ref&) = delete;
12636     json_ref& operator=(json_ref&&) = delete;
12637     ~json_ref() = default;
12638 
moved_or_copied() const12639     value_type moved_or_copied() const
12640     {
12641         if (is_rvalue)
12642         {
12643             return std::move(*value_ref);
12644         }
12645         return *value_ref;
12646     }
12647 
operator *() const12648     value_type const& operator*() const
12649     {
12650         return *static_cast<value_type const*>(value_ref);
12651     }
12652 
operator ->() const12653     value_type const* operator->() const
12654     {
12655         return static_cast<value_type const*>(value_ref);
12656     }
12657 
12658   private:
12659     mutable value_type owned_value = nullptr;
12660     value_type* value_ref = nullptr;
12661     const bool is_rvalue = true;
12662 };
12663 }  // namespace detail
12664 }  // namespace nlohmann
12665 
12666 // #include <nlohmann/detail/macro_scope.hpp>
12667 
12668 // #include <nlohmann/detail/meta/cpp_future.hpp>
12669 
12670 // #include <nlohmann/detail/meta/type_traits.hpp>
12671 
12672 // #include <nlohmann/detail/output/binary_writer.hpp>
12673 
12674 
12675 #include <algorithm> // reverse
12676 #include <array> // array
12677 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
12678 #include <cstring> // memcpy
12679 #include <limits> // numeric_limits
12680 #include <string> // string
12681 #include <cmath> // isnan, isinf
12682 
12683 // #include <nlohmann/detail/input/binary_reader.hpp>
12684 
12685 // #include <nlohmann/detail/macro_scope.hpp>
12686 
12687 // #include <nlohmann/detail/output/output_adapters.hpp>
12688 
12689 
12690 #include <algorithm> // copy
12691 #include <cstddef> // size_t
12692 #include <ios> // streamsize
12693 #include <iterator> // back_inserter
12694 #include <memory> // shared_ptr, make_shared
12695 #include <ostream> // basic_ostream
12696 #include <string> // basic_string
12697 #include <vector> // vector
12698 // #include <nlohmann/detail/macro_scope.hpp>
12699 
12700 
12701 namespace nlohmann
12702 {
12703 namespace detail
12704 {
12705 /// abstract output adapter interface
12706 template<typename CharType> struct output_adapter_protocol
12707 {
12708     virtual void write_character(CharType c) = 0;
12709     virtual void write_characters(const CharType* s, std::size_t length) = 0;
12710     virtual ~output_adapter_protocol() = default;
12711 };
12712 
12713 /// a type to simplify interfaces
12714 template<typename CharType>
12715 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
12716 
12717 /// output adapter for byte vectors
12718 template<typename CharType>
12719 class output_vector_adapter : public output_adapter_protocol<CharType>
12720 {
12721   public:
output_vector_adapter(std::vector<CharType> & vec)12722     explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
12723         : v(vec)
12724     {}
12725 
write_character(CharType c)12726     void write_character(CharType c) override
12727     {
12728         v.push_back(c);
12729     }
12730 
12731     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)12732     void write_characters(const CharType* s, std::size_t length) override
12733     {
12734         std::copy(s, s + length, std::back_inserter(v));
12735     }
12736 
12737   private:
12738     std::vector<CharType>& v;
12739 };
12740 
12741 /// output adapter for output streams
12742 template<typename CharType>
12743 class output_stream_adapter : public output_adapter_protocol<CharType>
12744 {
12745   public:
output_stream_adapter(std::basic_ostream<CharType> & s)12746     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
12747         : stream(s)
12748     {}
12749 
write_character(CharType c)12750     void write_character(CharType c) override
12751     {
12752         stream.put(c);
12753     }
12754 
12755     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)12756     void write_characters(const CharType* s, std::size_t length) override
12757     {
12758         stream.write(s, static_cast<std::streamsize>(length));
12759     }
12760 
12761   private:
12762     std::basic_ostream<CharType>& stream;
12763 };
12764 
12765 /// output adapter for basic_string
12766 template<typename CharType, typename StringType = std::basic_string<CharType>>
12767 class output_string_adapter : public output_adapter_protocol<CharType>
12768 {
12769   public:
output_string_adapter(StringType & s)12770     explicit output_string_adapter(StringType& s) noexcept
12771         : str(s)
12772     {}
12773 
write_character(CharType c)12774     void write_character(CharType c) override
12775     {
12776         str.push_back(c);
12777     }
12778 
12779     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)12780     void write_characters(const CharType* s, std::size_t length) override
12781     {
12782         str.append(s, length);
12783     }
12784 
12785   private:
12786     StringType& str;
12787 };
12788 
12789 template<typename CharType, typename StringType = std::basic_string<CharType>>
12790 class output_adapter
12791 {
12792   public:
output_adapter(std::vector<CharType> & vec)12793     output_adapter(std::vector<CharType>& vec)
12794         : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
12795 
output_adapter(std::basic_ostream<CharType> & s)12796     output_adapter(std::basic_ostream<CharType>& s)
12797         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
12798 
output_adapter(StringType & s)12799     output_adapter(StringType& s)
12800         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
12801 
operator output_adapter_t<CharType>()12802     operator output_adapter_t<CharType>()
12803     {
12804         return oa;
12805     }
12806 
12807   private:
12808     output_adapter_t<CharType> oa = nullptr;
12809 };
12810 }  // namespace detail
12811 }  // namespace nlohmann
12812 
12813 
12814 namespace nlohmann
12815 {
12816 namespace detail
12817 {
12818 ///////////////////
12819 // binary writer //
12820 ///////////////////
12821 
12822 /*!
12823 @brief serialization to CBOR and MessagePack values
12824 */
12825 template<typename BasicJsonType, typename CharType>
12826 class binary_writer
12827 {
12828     using string_t = typename BasicJsonType::string_t;
12829     using binary_t = typename BasicJsonType::binary_t;
12830     using number_float_t = typename BasicJsonType::number_float_t;
12831 
12832   public:
12833     /*!
12834     @brief create a binary writer
12835 
12836     @param[in] adapter  output adapter to write to
12837     */
binary_writer(output_adapter_t<CharType> adapter)12838     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
12839     {
12840         JSON_ASSERT(oa);
12841     }
12842 
12843     /*!
12844     @param[in] j  JSON value to serialize
12845     @pre       j.type() == value_t::object
12846     */
write_bson(const BasicJsonType & j)12847     void write_bson(const BasicJsonType& j)
12848     {
12849         switch (j.type())
12850         {
12851             case value_t::object:
12852             {
12853                 write_bson_object(*j.m_value.object);
12854                 break;
12855             }
12856 
12857             default:
12858             {
12859                 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
12860             }
12861         }
12862     }
12863 
12864     /*!
12865     @param[in] j  JSON value to serialize
12866     */
write_cbor(const BasicJsonType & j)12867     void write_cbor(const BasicJsonType& j)
12868     {
12869         switch (j.type())
12870         {
12871             case value_t::null:
12872             {
12873                 oa->write_character(to_char_type(0xF6));
12874                 break;
12875             }
12876 
12877             case value_t::boolean:
12878             {
12879                 oa->write_character(j.m_value.boolean
12880                                     ? to_char_type(0xF5)
12881                                     : to_char_type(0xF4));
12882                 break;
12883             }
12884 
12885             case value_t::number_integer:
12886             {
12887                 if (j.m_value.number_integer >= 0)
12888                 {
12889                     // CBOR does not differentiate between positive signed
12890                     // integers and unsigned integers. Therefore, we used the
12891                     // code from the value_t::number_unsigned case here.
12892                     if (j.m_value.number_integer <= 0x17)
12893                     {
12894                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12895                     }
12896                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
12897                     {
12898                         oa->write_character(to_char_type(0x18));
12899                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
12900                     }
12901                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
12902                     {
12903                         oa->write_character(to_char_type(0x19));
12904                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
12905                     }
12906                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
12907                     {
12908                         oa->write_character(to_char_type(0x1A));
12909                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
12910                     }
12911                     else
12912                     {
12913                         oa->write_character(to_char_type(0x1B));
12914                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
12915                     }
12916                 }
12917                 else
12918                 {
12919                     // The conversions below encode the sign in the first
12920                     // byte, and the value is converted to a positive number.
12921                     const auto positive_number = -1 - j.m_value.number_integer;
12922                     if (j.m_value.number_integer >= -24)
12923                     {
12924                         write_number(static_cast<std::uint8_t>(0x20 + positive_number));
12925                     }
12926                     else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
12927                     {
12928                         oa->write_character(to_char_type(0x38));
12929                         write_number(static_cast<std::uint8_t>(positive_number));
12930                     }
12931                     else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
12932                     {
12933                         oa->write_character(to_char_type(0x39));
12934                         write_number(static_cast<std::uint16_t>(positive_number));
12935                     }
12936                     else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
12937                     {
12938                         oa->write_character(to_char_type(0x3A));
12939                         write_number(static_cast<std::uint32_t>(positive_number));
12940                     }
12941                     else
12942                     {
12943                         oa->write_character(to_char_type(0x3B));
12944                         write_number(static_cast<std::uint64_t>(positive_number));
12945                     }
12946                 }
12947                 break;
12948             }
12949 
12950             case value_t::number_unsigned:
12951             {
12952                 if (j.m_value.number_unsigned <= 0x17)
12953                 {
12954                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12955                 }
12956                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
12957                 {
12958                     oa->write_character(to_char_type(0x18));
12959                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
12960                 }
12961                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
12962                 {
12963                     oa->write_character(to_char_type(0x19));
12964                     write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
12965                 }
12966                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
12967                 {
12968                     oa->write_character(to_char_type(0x1A));
12969                     write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
12970                 }
12971                 else
12972                 {
12973                     oa->write_character(to_char_type(0x1B));
12974                     write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
12975                 }
12976                 break;
12977             }
12978 
12979             case value_t::number_float:
12980             {
12981                 if (std::isnan(j.m_value.number_float))
12982                 {
12983                     // NaN is 0xf97e00 in CBOR
12984                     oa->write_character(to_char_type(0xF9));
12985                     oa->write_character(to_char_type(0x7E));
12986                     oa->write_character(to_char_type(0x00));
12987                 }
12988                 else if (std::isinf(j.m_value.number_float))
12989                 {
12990                     // Infinity is 0xf97c00, -Infinity is 0xf9fc00
12991                     oa->write_character(to_char_type(0xf9));
12992                     oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
12993                     oa->write_character(to_char_type(0x00));
12994                 }
12995                 else
12996                 {
12997                     write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
12998                 }
12999                 break;
13000             }
13001 
13002             case value_t::string:
13003             {
13004                 // step 1: write control byte and the string length
13005                 const auto N = j.m_value.string->size();
13006                 if (N <= 0x17)
13007                 {
13008                     write_number(static_cast<std::uint8_t>(0x60 + N));
13009                 }
13010                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13011                 {
13012                     oa->write_character(to_char_type(0x78));
13013                     write_number(static_cast<std::uint8_t>(N));
13014                 }
13015                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13016                 {
13017                     oa->write_character(to_char_type(0x79));
13018                     write_number(static_cast<std::uint16_t>(N));
13019                 }
13020                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13021                 {
13022                     oa->write_character(to_char_type(0x7A));
13023                     write_number(static_cast<std::uint32_t>(N));
13024                 }
13025                 // LCOV_EXCL_START
13026                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13027                 {
13028                     oa->write_character(to_char_type(0x7B));
13029                     write_number(static_cast<std::uint64_t>(N));
13030                 }
13031                 // LCOV_EXCL_STOP
13032 
13033                 // step 2: write the string
13034                 oa->write_characters(
13035                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13036                     j.m_value.string->size());
13037                 break;
13038             }
13039 
13040             case value_t::array:
13041             {
13042                 // step 1: write control byte and the array size
13043                 const auto N = j.m_value.array->size();
13044                 if (N <= 0x17)
13045                 {
13046                     write_number(static_cast<std::uint8_t>(0x80 + N));
13047                 }
13048                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13049                 {
13050                     oa->write_character(to_char_type(0x98));
13051                     write_number(static_cast<std::uint8_t>(N));
13052                 }
13053                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13054                 {
13055                     oa->write_character(to_char_type(0x99));
13056                     write_number(static_cast<std::uint16_t>(N));
13057                 }
13058                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13059                 {
13060                     oa->write_character(to_char_type(0x9A));
13061                     write_number(static_cast<std::uint32_t>(N));
13062                 }
13063                 // LCOV_EXCL_START
13064                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13065                 {
13066                     oa->write_character(to_char_type(0x9B));
13067                     write_number(static_cast<std::uint64_t>(N));
13068                 }
13069                 // LCOV_EXCL_STOP
13070 
13071                 // step 2: write each element
13072                 for (const auto& el : *j.m_value.array)
13073                 {
13074                     write_cbor(el);
13075                 }
13076                 break;
13077             }
13078 
13079             case value_t::binary:
13080             {
13081                 if (j.m_value.binary->has_subtype())
13082                 {
13083                     write_number(static_cast<std::uint8_t>(0xd8));
13084                     write_number(j.m_value.binary->subtype());
13085                 }
13086 
13087                 // step 1: write control byte and the binary array size
13088                 const auto N = j.m_value.binary->size();
13089                 if (N <= 0x17)
13090                 {
13091                     write_number(static_cast<std::uint8_t>(0x40 + N));
13092                 }
13093                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13094                 {
13095                     oa->write_character(to_char_type(0x58));
13096                     write_number(static_cast<std::uint8_t>(N));
13097                 }
13098                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13099                 {
13100                     oa->write_character(to_char_type(0x59));
13101                     write_number(static_cast<std::uint16_t>(N));
13102                 }
13103                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13104                 {
13105                     oa->write_character(to_char_type(0x5A));
13106                     write_number(static_cast<std::uint32_t>(N));
13107                 }
13108                 // LCOV_EXCL_START
13109                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13110                 {
13111                     oa->write_character(to_char_type(0x5B));
13112                     write_number(static_cast<std::uint64_t>(N));
13113                 }
13114                 // LCOV_EXCL_STOP
13115 
13116                 // step 2: write each element
13117                 oa->write_characters(
13118                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13119                     N);
13120 
13121                 break;
13122             }
13123 
13124             case value_t::object:
13125             {
13126                 // step 1: write control byte and the object size
13127                 const auto N = j.m_value.object->size();
13128                 if (N <= 0x17)
13129                 {
13130                     write_number(static_cast<std::uint8_t>(0xA0 + N));
13131                 }
13132                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13133                 {
13134                     oa->write_character(to_char_type(0xB8));
13135                     write_number(static_cast<std::uint8_t>(N));
13136                 }
13137                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13138                 {
13139                     oa->write_character(to_char_type(0xB9));
13140                     write_number(static_cast<std::uint16_t>(N));
13141                 }
13142                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13143                 {
13144                     oa->write_character(to_char_type(0xBA));
13145                     write_number(static_cast<std::uint32_t>(N));
13146                 }
13147                 // LCOV_EXCL_START
13148                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13149                 {
13150                     oa->write_character(to_char_type(0xBB));
13151                     write_number(static_cast<std::uint64_t>(N));
13152                 }
13153                 // LCOV_EXCL_STOP
13154 
13155                 // step 2: write each element
13156                 for (const auto& el : *j.m_value.object)
13157                 {
13158                     write_cbor(el.first);
13159                     write_cbor(el.second);
13160                 }
13161                 break;
13162             }
13163 
13164             default:
13165                 break;
13166         }
13167     }
13168 
13169     /*!
13170     @param[in] j  JSON value to serialize
13171     */
write_msgpack(const BasicJsonType & j)13172     void write_msgpack(const BasicJsonType& j)
13173     {
13174         switch (j.type())
13175         {
13176             case value_t::null: // nil
13177             {
13178                 oa->write_character(to_char_type(0xC0));
13179                 break;
13180             }
13181 
13182             case value_t::boolean: // true and false
13183             {
13184                 oa->write_character(j.m_value.boolean
13185                                     ? to_char_type(0xC3)
13186                                     : to_char_type(0xC2));
13187                 break;
13188             }
13189 
13190             case value_t::number_integer:
13191             {
13192                 if (j.m_value.number_integer >= 0)
13193                 {
13194                     // MessagePack does not differentiate between positive
13195                     // signed integers and unsigned integers. Therefore, we used
13196                     // the code from the value_t::number_unsigned case here.
13197                     if (j.m_value.number_unsigned < 128)
13198                     {
13199                         // positive fixnum
13200                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13201                     }
13202                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13203                     {
13204                         // uint 8
13205                         oa->write_character(to_char_type(0xCC));
13206                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13207                     }
13208                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13209                     {
13210                         // uint 16
13211                         oa->write_character(to_char_type(0xCD));
13212                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13213                     }
13214                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13215                     {
13216                         // uint 32
13217                         oa->write_character(to_char_type(0xCE));
13218                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13219                     }
13220                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13221                     {
13222                         // uint 64
13223                         oa->write_character(to_char_type(0xCF));
13224                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13225                     }
13226                 }
13227                 else
13228                 {
13229                     if (j.m_value.number_integer >= -32)
13230                     {
13231                         // negative fixnum
13232                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13233                     }
13234                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13235                              j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13236                     {
13237                         // int 8
13238                         oa->write_character(to_char_type(0xD0));
13239                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13240                     }
13241                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13242                              j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13243                     {
13244                         // int 16
13245                         oa->write_character(to_char_type(0xD1));
13246                         write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13247                     }
13248                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13249                              j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13250                     {
13251                         // int 32
13252                         oa->write_character(to_char_type(0xD2));
13253                         write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13254                     }
13255                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13256                              j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13257                     {
13258                         // int 64
13259                         oa->write_character(to_char_type(0xD3));
13260                         write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13261                     }
13262                 }
13263                 break;
13264             }
13265 
13266             case value_t::number_unsigned:
13267             {
13268                 if (j.m_value.number_unsigned < 128)
13269                 {
13270                     // positive fixnum
13271                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13272                 }
13273                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13274                 {
13275                     // uint 8
13276                     oa->write_character(to_char_type(0xCC));
13277                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13278                 }
13279                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13280                 {
13281                     // uint 16
13282                     oa->write_character(to_char_type(0xCD));
13283                     write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13284                 }
13285                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13286                 {
13287                     // uint 32
13288                     oa->write_character(to_char_type(0xCE));
13289                     write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13290                 }
13291                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13292                 {
13293                     // uint 64
13294                     oa->write_character(to_char_type(0xCF));
13295                     write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13296                 }
13297                 break;
13298             }
13299 
13300             case value_t::number_float:
13301             {
13302                 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13303                 break;
13304             }
13305 
13306             case value_t::string:
13307             {
13308                 // step 1: write control byte and the string length
13309                 const auto N = j.m_value.string->size();
13310                 if (N <= 31)
13311                 {
13312                     // fixstr
13313                     write_number(static_cast<std::uint8_t>(0xA0 | N));
13314                 }
13315                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13316                 {
13317                     // str 8
13318                     oa->write_character(to_char_type(0xD9));
13319                     write_number(static_cast<std::uint8_t>(N));
13320                 }
13321                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13322                 {
13323                     // str 16
13324                     oa->write_character(to_char_type(0xDA));
13325                     write_number(static_cast<std::uint16_t>(N));
13326                 }
13327                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13328                 {
13329                     // str 32
13330                     oa->write_character(to_char_type(0xDB));
13331                     write_number(static_cast<std::uint32_t>(N));
13332                 }
13333 
13334                 // step 2: write the string
13335                 oa->write_characters(
13336                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13337                     j.m_value.string->size());
13338                 break;
13339             }
13340 
13341             case value_t::array:
13342             {
13343                 // step 1: write control byte and the array size
13344                 const auto N = j.m_value.array->size();
13345                 if (N <= 15)
13346                 {
13347                     // fixarray
13348                     write_number(static_cast<std::uint8_t>(0x90 | N));
13349                 }
13350                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13351                 {
13352                     // array 16
13353                     oa->write_character(to_char_type(0xDC));
13354                     write_number(static_cast<std::uint16_t>(N));
13355                 }
13356                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13357                 {
13358                     // array 32
13359                     oa->write_character(to_char_type(0xDD));
13360                     write_number(static_cast<std::uint32_t>(N));
13361                 }
13362 
13363                 // step 2: write each element
13364                 for (const auto& el : *j.m_value.array)
13365                 {
13366                     write_msgpack(el);
13367                 }
13368                 break;
13369             }
13370 
13371             case value_t::binary:
13372             {
13373                 // step 0: determine if the binary type has a set subtype to
13374                 // determine whether or not to use the ext or fixext types
13375                 const bool use_ext = j.m_value.binary->has_subtype();
13376 
13377                 // step 1: write control byte and the byte string length
13378                 const auto N = j.m_value.binary->size();
13379                 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13380                 {
13381                     std::uint8_t output_type{};
13382                     bool fixed = true;
13383                     if (use_ext)
13384                     {
13385                         switch (N)
13386                         {
13387                             case 1:
13388                                 output_type = 0xD4; // fixext 1
13389                                 break;
13390                             case 2:
13391                                 output_type = 0xD5; // fixext 2
13392                                 break;
13393                             case 4:
13394                                 output_type = 0xD6; // fixext 4
13395                                 break;
13396                             case 8:
13397                                 output_type = 0xD7; // fixext 8
13398                                 break;
13399                             case 16:
13400                                 output_type = 0xD8; // fixext 16
13401                                 break;
13402                             default:
13403                                 output_type = 0xC7; // ext 8
13404                                 fixed = false;
13405                                 break;
13406                         }
13407 
13408                     }
13409                     else
13410                     {
13411                         output_type = 0xC4; // bin 8
13412                         fixed = false;
13413                     }
13414 
13415                     oa->write_character(to_char_type(output_type));
13416                     if (!fixed)
13417                     {
13418                         write_number(static_cast<std::uint8_t>(N));
13419                     }
13420                 }
13421                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13422                 {
13423                     std::uint8_t output_type = use_ext
13424                                                ? 0xC8 // ext 16
13425                                                : 0xC5; // bin 16
13426 
13427                     oa->write_character(to_char_type(output_type));
13428                     write_number(static_cast<std::uint16_t>(N));
13429                 }
13430                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13431                 {
13432                     std::uint8_t output_type = use_ext
13433                                                ? 0xC9 // ext 32
13434                                                : 0xC6; // bin 32
13435 
13436                     oa->write_character(to_char_type(output_type));
13437                     write_number(static_cast<std::uint32_t>(N));
13438                 }
13439 
13440                 // step 1.5: if this is an ext type, write the subtype
13441                 if (use_ext)
13442                 {
13443                     write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13444                 }
13445 
13446                 // step 2: write the byte string
13447                 oa->write_characters(
13448                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13449                     N);
13450 
13451                 break;
13452             }
13453 
13454             case value_t::object:
13455             {
13456                 // step 1: write control byte and the object size
13457                 const auto N = j.m_value.object->size();
13458                 if (N <= 15)
13459                 {
13460                     // fixmap
13461                     write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13462                 }
13463                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13464                 {
13465                     // map 16
13466                     oa->write_character(to_char_type(0xDE));
13467                     write_number(static_cast<std::uint16_t>(N));
13468                 }
13469                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13470                 {
13471                     // map 32
13472                     oa->write_character(to_char_type(0xDF));
13473                     write_number(static_cast<std::uint32_t>(N));
13474                 }
13475 
13476                 // step 2: write each element
13477                 for (const auto& el : *j.m_value.object)
13478                 {
13479                     write_msgpack(el.first);
13480                     write_msgpack(el.second);
13481                 }
13482                 break;
13483             }
13484 
13485             default:
13486                 break;
13487         }
13488     }
13489 
13490     /*!
13491     @param[in] j  JSON value to serialize
13492     @param[in] use_count   whether to use '#' prefixes (optimized format)
13493     @param[in] use_type    whether to use '$' prefixes (optimized format)
13494     @param[in] add_prefix  whether prefixes need to be used for this value
13495     */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)13496     void write_ubjson(const BasicJsonType& j, const bool use_count,
13497                       const bool use_type, const bool add_prefix = true)
13498     {
13499         switch (j.type())
13500         {
13501             case value_t::null:
13502             {
13503                 if (add_prefix)
13504                 {
13505                     oa->write_character(to_char_type('Z'));
13506                 }
13507                 break;
13508             }
13509 
13510             case value_t::boolean:
13511             {
13512                 if (add_prefix)
13513                 {
13514                     oa->write_character(j.m_value.boolean
13515                                         ? to_char_type('T')
13516                                         : to_char_type('F'));
13517                 }
13518                 break;
13519             }
13520 
13521             case value_t::number_integer:
13522             {
13523                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
13524                 break;
13525             }
13526 
13527             case value_t::number_unsigned:
13528             {
13529                 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
13530                 break;
13531             }
13532 
13533             case value_t::number_float:
13534             {
13535                 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
13536                 break;
13537             }
13538 
13539             case value_t::string:
13540             {
13541                 if (add_prefix)
13542                 {
13543                     oa->write_character(to_char_type('S'));
13544                 }
13545                 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
13546                 oa->write_characters(
13547                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13548                     j.m_value.string->size());
13549                 break;
13550             }
13551 
13552             case value_t::array:
13553             {
13554                 if (add_prefix)
13555                 {
13556                     oa->write_character(to_char_type('['));
13557                 }
13558 
13559                 bool prefix_required = true;
13560                 if (use_type && !j.m_value.array->empty())
13561                 {
13562                     JSON_ASSERT(use_count);
13563                     const CharType first_prefix = ubjson_prefix(j.front());
13564                     const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
13565                                                          [this, first_prefix](const BasicJsonType & v)
13566                     {
13567                         return ubjson_prefix(v) == first_prefix;
13568                     });
13569 
13570                     if (same_prefix)
13571                     {
13572                         prefix_required = false;
13573                         oa->write_character(to_char_type('$'));
13574                         oa->write_character(first_prefix);
13575                     }
13576                 }
13577 
13578                 if (use_count)
13579                 {
13580                     oa->write_character(to_char_type('#'));
13581                     write_number_with_ubjson_prefix(j.m_value.array->size(), true);
13582                 }
13583 
13584                 for (const auto& el : *j.m_value.array)
13585                 {
13586                     write_ubjson(el, use_count, use_type, prefix_required);
13587                 }
13588 
13589                 if (!use_count)
13590                 {
13591                     oa->write_character(to_char_type(']'));
13592                 }
13593 
13594                 break;
13595             }
13596 
13597             case value_t::binary:
13598             {
13599                 if (add_prefix)
13600                 {
13601                     oa->write_character(to_char_type('['));
13602                 }
13603 
13604                 if (use_type && !j.m_value.binary->empty())
13605                 {
13606                     JSON_ASSERT(use_count);
13607                     oa->write_character(to_char_type('$'));
13608                     oa->write_character('U');
13609                 }
13610 
13611                 if (use_count)
13612                 {
13613                     oa->write_character(to_char_type('#'));
13614                     write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
13615                 }
13616 
13617                 if (use_type)
13618                 {
13619                     oa->write_characters(
13620                         reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13621                         j.m_value.binary->size());
13622                 }
13623                 else
13624                 {
13625                     for (size_t i = 0; i < j.m_value.binary->size(); ++i)
13626                     {
13627                         oa->write_character(to_char_type('U'));
13628                         oa->write_character(j.m_value.binary->data()[i]);
13629                     }
13630                 }
13631 
13632                 if (!use_count)
13633                 {
13634                     oa->write_character(to_char_type(']'));
13635                 }
13636 
13637                 break;
13638             }
13639 
13640             case value_t::object:
13641             {
13642                 if (add_prefix)
13643                 {
13644                     oa->write_character(to_char_type('{'));
13645                 }
13646 
13647                 bool prefix_required = true;
13648                 if (use_type && !j.m_value.object->empty())
13649                 {
13650                     JSON_ASSERT(use_count);
13651                     const CharType first_prefix = ubjson_prefix(j.front());
13652                     const bool same_prefix = std::all_of(j.begin(), j.end(),
13653                                                          [this, first_prefix](const BasicJsonType & v)
13654                     {
13655                         return ubjson_prefix(v) == first_prefix;
13656                     });
13657 
13658                     if (same_prefix)
13659                     {
13660                         prefix_required = false;
13661                         oa->write_character(to_char_type('$'));
13662                         oa->write_character(first_prefix);
13663                     }
13664                 }
13665 
13666                 if (use_count)
13667                 {
13668                     oa->write_character(to_char_type('#'));
13669                     write_number_with_ubjson_prefix(j.m_value.object->size(), true);
13670                 }
13671 
13672                 for (const auto& el : *j.m_value.object)
13673                 {
13674                     write_number_with_ubjson_prefix(el.first.size(), true);
13675                     oa->write_characters(
13676                         reinterpret_cast<const CharType*>(el.first.c_str()),
13677                         el.first.size());
13678                     write_ubjson(el.second, use_count, use_type, prefix_required);
13679                 }
13680 
13681                 if (!use_count)
13682                 {
13683                     oa->write_character(to_char_type('}'));
13684                 }
13685 
13686                 break;
13687             }
13688 
13689             default:
13690                 break;
13691         }
13692     }
13693 
13694   private:
13695     //////////
13696     // BSON //
13697     //////////
13698 
13699     /*!
13700     @return The size of a BSON document entry header, including the id marker
13701             and the entry name size (and its null-terminator).
13702     */
calc_bson_entry_header_size(const string_t & name)13703     static std::size_t calc_bson_entry_header_size(const string_t& name)
13704     {
13705         const auto it = name.find(static_cast<typename string_t::value_type>(0));
13706         if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
13707         {
13708             JSON_THROW(out_of_range::create(409,
13709                                             "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
13710         }
13711 
13712         return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
13713     }
13714 
13715     /*!
13716     @brief Writes the given @a element_type and @a name to the output adapter
13717     */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)13718     void write_bson_entry_header(const string_t& name,
13719                                  const std::uint8_t element_type)
13720     {
13721         oa->write_character(to_char_type(element_type)); // boolean
13722         oa->write_characters(
13723             reinterpret_cast<const CharType*>(name.c_str()),
13724             name.size() + 1u);
13725     }
13726 
13727     /*!
13728     @brief Writes a BSON element with key @a name and boolean value @a value
13729     */
write_bson_boolean(const string_t & name,const bool value)13730     void write_bson_boolean(const string_t& name,
13731                             const bool value)
13732     {
13733         write_bson_entry_header(name, 0x08);
13734         oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
13735     }
13736 
13737     /*!
13738     @brief Writes a BSON element with key @a name and double value @a value
13739     */
write_bson_double(const string_t & name,const double value)13740     void write_bson_double(const string_t& name,
13741                            const double value)
13742     {
13743         write_bson_entry_header(name, 0x01);
13744         write_number<double, true>(value);
13745     }
13746 
13747     /*!
13748     @return The size of the BSON-encoded string in @a value
13749     */
calc_bson_string_size(const string_t & value)13750     static std::size_t calc_bson_string_size(const string_t& value)
13751     {
13752         return sizeof(std::int32_t) + value.size() + 1ul;
13753     }
13754 
13755     /*!
13756     @brief Writes a BSON element with key @a name and string value @a value
13757     */
write_bson_string(const string_t & name,const string_t & value)13758     void write_bson_string(const string_t& name,
13759                            const string_t& value)
13760     {
13761         write_bson_entry_header(name, 0x02);
13762 
13763         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
13764         oa->write_characters(
13765             reinterpret_cast<const CharType*>(value.c_str()),
13766             value.size() + 1);
13767     }
13768 
13769     /*!
13770     @brief Writes a BSON element with key @a name and null value
13771     */
write_bson_null(const string_t & name)13772     void write_bson_null(const string_t& name)
13773     {
13774         write_bson_entry_header(name, 0x0A);
13775     }
13776 
13777     /*!
13778     @return The size of the BSON-encoded integer @a value
13779     */
calc_bson_integer_size(const std::int64_t value)13780     static std::size_t calc_bson_integer_size(const std::int64_t value)
13781     {
13782         return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
13783                ? sizeof(std::int32_t)
13784                : sizeof(std::int64_t);
13785     }
13786 
13787     /*!
13788     @brief Writes a BSON element with key @a name and integer @a value
13789     */
write_bson_integer(const string_t & name,const std::int64_t value)13790     void write_bson_integer(const string_t& name,
13791                             const std::int64_t value)
13792     {
13793         if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
13794         {
13795             write_bson_entry_header(name, 0x10); // int32
13796             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13797         }
13798         else
13799         {
13800             write_bson_entry_header(name, 0x12); // int64
13801             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13802         }
13803     }
13804 
13805     /*!
13806     @return The size of the BSON-encoded unsigned integer in @a j
13807     */
calc_bson_unsigned_size(const std::uint64_t value)13808     static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
13809     {
13810         return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13811                ? sizeof(std::int32_t)
13812                : sizeof(std::int64_t);
13813     }
13814 
13815     /*!
13816     @brief Writes a BSON element with key @a name and unsigned @a value
13817     */
write_bson_unsigned(const string_t & name,const std::uint64_t value)13818     void write_bson_unsigned(const string_t& name,
13819                              const std::uint64_t value)
13820     {
13821         if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
13822         {
13823             write_bson_entry_header(name, 0x10 /* int32 */);
13824             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
13825         }
13826         else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
13827         {
13828             write_bson_entry_header(name, 0x12 /* int64 */);
13829             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
13830         }
13831         else
13832         {
13833             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
13834         }
13835     }
13836 
13837     /*!
13838     @brief Writes a BSON element with key @a name and object @a value
13839     */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)13840     void write_bson_object_entry(const string_t& name,
13841                                  const typename BasicJsonType::object_t& value)
13842     {
13843         write_bson_entry_header(name, 0x03); // object
13844         write_bson_object(value);
13845     }
13846 
13847     /*!
13848     @return The size of the BSON-encoded array @a value
13849     */
calc_bson_array_size(const typename BasicJsonType::array_t & value)13850     static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
13851     {
13852         std::size_t array_index = 0ul;
13853 
13854         const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
13855         {
13856             return result + calc_bson_element_size(std::to_string(array_index++), el);
13857         });
13858 
13859         return sizeof(std::int32_t) + embedded_document_size + 1ul;
13860     }
13861 
13862     /*!
13863     @return The size of the BSON-encoded binary array @a value
13864     */
calc_bson_binary_size(const typename BasicJsonType::binary_t & value)13865     static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
13866     {
13867         return sizeof(std::int32_t) + value.size() + 1ul;
13868     }
13869 
13870     /*!
13871     @brief Writes a BSON element with key @a name and array @a value
13872     */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)13873     void write_bson_array(const string_t& name,
13874                           const typename BasicJsonType::array_t& value)
13875     {
13876         write_bson_entry_header(name, 0x04); // array
13877         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
13878 
13879         std::size_t array_index = 0ul;
13880 
13881         for (const auto& el : value)
13882         {
13883             write_bson_element(std::to_string(array_index++), el);
13884         }
13885 
13886         oa->write_character(to_char_type(0x00));
13887     }
13888 
13889     /*!
13890     @brief Writes a BSON element with key @a name and binary value @a value
13891     */
write_bson_binary(const string_t & name,const binary_t & value)13892     void write_bson_binary(const string_t& name,
13893                            const binary_t& value)
13894     {
13895         write_bson_entry_header(name, 0x05);
13896 
13897         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
13898         write_number(value.has_subtype() ? value.subtype() : std::uint8_t(0x00));
13899 
13900         oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
13901     }
13902 
13903     /*!
13904     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
13905     @return The calculated size for the BSON document entry for @a j with the given @a name.
13906     */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)13907     static std::size_t calc_bson_element_size(const string_t& name,
13908             const BasicJsonType& j)
13909     {
13910         const auto header_size = calc_bson_entry_header_size(name);
13911         switch (j.type())
13912         {
13913             case value_t::object:
13914                 return header_size + calc_bson_object_size(*j.m_value.object);
13915 
13916             case value_t::array:
13917                 return header_size + calc_bson_array_size(*j.m_value.array);
13918 
13919             case value_t::binary:
13920                 return header_size + calc_bson_binary_size(*j.m_value.binary);
13921 
13922             case value_t::boolean:
13923                 return header_size + 1ul;
13924 
13925             case value_t::number_float:
13926                 return header_size + 8ul;
13927 
13928             case value_t::number_integer:
13929                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
13930 
13931             case value_t::number_unsigned:
13932                 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
13933 
13934             case value_t::string:
13935                 return header_size + calc_bson_string_size(*j.m_value.string);
13936 
13937             case value_t::null:
13938                 return header_size + 0ul;
13939 
13940             // LCOV_EXCL_START
13941             default:
13942                 JSON_ASSERT(false);
13943                 return 0ul;
13944                 // LCOV_EXCL_STOP
13945         }
13946     }
13947 
13948     /*!
13949     @brief Serializes the JSON value @a j to BSON and associates it with the
13950            key @a name.
13951     @param name The name to associate with the JSON entity @a j within the
13952                 current BSON document
13953     @return The size of the BSON entry
13954     */
write_bson_element(const string_t & name,const BasicJsonType & j)13955     void write_bson_element(const string_t& name,
13956                             const BasicJsonType& j)
13957     {
13958         switch (j.type())
13959         {
13960             case value_t::object:
13961                 return write_bson_object_entry(name, *j.m_value.object);
13962 
13963             case value_t::array:
13964                 return write_bson_array(name, *j.m_value.array);
13965 
13966             case value_t::binary:
13967                 return write_bson_binary(name, *j.m_value.binary);
13968 
13969             case value_t::boolean:
13970                 return write_bson_boolean(name, j.m_value.boolean);
13971 
13972             case value_t::number_float:
13973                 return write_bson_double(name, j.m_value.number_float);
13974 
13975             case value_t::number_integer:
13976                 return write_bson_integer(name, j.m_value.number_integer);
13977 
13978             case value_t::number_unsigned:
13979                 return write_bson_unsigned(name, j.m_value.number_unsigned);
13980 
13981             case value_t::string:
13982                 return write_bson_string(name, *j.m_value.string);
13983 
13984             case value_t::null:
13985                 return write_bson_null(name);
13986 
13987             // LCOV_EXCL_START
13988             default:
13989                 JSON_ASSERT(false);
13990                 return;
13991                 // LCOV_EXCL_STOP
13992         }
13993     }
13994 
13995     /*!
13996     @brief Calculates the size of the BSON serialization of the given
13997            JSON-object @a j.
13998     @param[in] j  JSON value to serialize
13999     @pre       j.type() == value_t::object
14000     */
calc_bson_object_size(const typename BasicJsonType::object_t & value)14001     static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14002     {
14003         std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14004                                     [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14005         {
14006             return result += calc_bson_element_size(el.first, el.second);
14007         });
14008 
14009         return sizeof(std::int32_t) + document_size + 1ul;
14010     }
14011 
14012     /*!
14013     @param[in] j  JSON value to serialize
14014     @pre       j.type() == value_t::object
14015     */
write_bson_object(const typename BasicJsonType::object_t & value)14016     void write_bson_object(const typename BasicJsonType::object_t& value)
14017     {
14018         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14019 
14020         for (const auto& el : value)
14021         {
14022             write_bson_element(el.first, el.second);
14023         }
14024 
14025         oa->write_character(to_char_type(0x00));
14026     }
14027 
14028     //////////
14029     // CBOR //
14030     //////////
14031 
get_cbor_float_prefix(float)14032     static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14033     {
14034         return to_char_type(0xFA);  // Single-Precision Float
14035     }
14036 
get_cbor_float_prefix(double)14037     static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14038     {
14039         return to_char_type(0xFB);  // Double-Precision Float
14040     }
14041 
14042     /////////////
14043     // MsgPack //
14044     /////////////
14045 
get_msgpack_float_prefix(float)14046     static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14047     {
14048         return to_char_type(0xCA);  // float 32
14049     }
14050 
get_msgpack_float_prefix(double)14051     static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14052     {
14053         return to_char_type(0xCB);  // float 64
14054     }
14055 
14056     ////////////
14057     // UBJSON //
14058     ////////////
14059 
14060     // UBJSON: write number (floating point)
14061     template<typename NumberType, typename std::enable_if<
14062                  std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14063     void write_number_with_ubjson_prefix(const NumberType n,
14064                                          const bool add_prefix)
14065     {
14066         if (add_prefix)
14067         {
14068             oa->write_character(get_ubjson_float_prefix(n));
14069         }
14070         write_number(n);
14071     }
14072 
14073     // UBJSON: write number (unsigned integer)
14074     template<typename NumberType, typename std::enable_if<
14075                  std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14076     void write_number_with_ubjson_prefix(const NumberType n,
14077                                          const bool add_prefix)
14078     {
14079         if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14080         {
14081             if (add_prefix)
14082             {
14083                 oa->write_character(to_char_type('i'));  // int8
14084             }
14085             write_number(static_cast<std::uint8_t>(n));
14086         }
14087         else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14088         {
14089             if (add_prefix)
14090             {
14091                 oa->write_character(to_char_type('U'));  // uint8
14092             }
14093             write_number(static_cast<std::uint8_t>(n));
14094         }
14095         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14096         {
14097             if (add_prefix)
14098             {
14099                 oa->write_character(to_char_type('I'));  // int16
14100             }
14101             write_number(static_cast<std::int16_t>(n));
14102         }
14103         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14104         {
14105             if (add_prefix)
14106             {
14107                 oa->write_character(to_char_type('l'));  // int32
14108             }
14109             write_number(static_cast<std::int32_t>(n));
14110         }
14111         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14112         {
14113             if (add_prefix)
14114             {
14115                 oa->write_character(to_char_type('L'));  // int64
14116             }
14117             write_number(static_cast<std::int64_t>(n));
14118         }
14119         else
14120         {
14121             if (add_prefix)
14122             {
14123                 oa->write_character(to_char_type('H'));  // high-precision number
14124             }
14125 
14126             const auto number = BasicJsonType(n).dump();
14127             write_number_with_ubjson_prefix(number.size(), true);
14128             for (std::size_t i = 0; i < number.size(); ++i)
14129             {
14130                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14131             }
14132         }
14133     }
14134 
14135     // UBJSON: write number (signed integer)
14136     template < typename NumberType, typename std::enable_if <
14137                    std::is_signed<NumberType>::value&&
14138                    !std::is_floating_point<NumberType>::value, int >::type = 0 >
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14139     void write_number_with_ubjson_prefix(const NumberType n,
14140                                          const bool add_prefix)
14141     {
14142         if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14143         {
14144             if (add_prefix)
14145             {
14146                 oa->write_character(to_char_type('i'));  // int8
14147             }
14148             write_number(static_cast<std::int8_t>(n));
14149         }
14150         else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
14151         {
14152             if (add_prefix)
14153             {
14154                 oa->write_character(to_char_type('U'));  // uint8
14155             }
14156             write_number(static_cast<std::uint8_t>(n));
14157         }
14158         else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14159         {
14160             if (add_prefix)
14161             {
14162                 oa->write_character(to_char_type('I'));  // int16
14163             }
14164             write_number(static_cast<std::int16_t>(n));
14165         }
14166         else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14167         {
14168             if (add_prefix)
14169             {
14170                 oa->write_character(to_char_type('l'));  // int32
14171             }
14172             write_number(static_cast<std::int32_t>(n));
14173         }
14174         else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14175         {
14176             if (add_prefix)
14177             {
14178                 oa->write_character(to_char_type('L'));  // int64
14179             }
14180             write_number(static_cast<std::int64_t>(n));
14181         }
14182         // LCOV_EXCL_START
14183         else
14184         {
14185             if (add_prefix)
14186             {
14187                 oa->write_character(to_char_type('H'));  // high-precision number
14188             }
14189 
14190             const auto number = BasicJsonType(n).dump();
14191             write_number_with_ubjson_prefix(number.size(), true);
14192             for (std::size_t i = 0; i < number.size(); ++i)
14193             {
14194                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14195             }
14196         }
14197         // LCOV_EXCL_STOP
14198     }
14199 
14200     /*!
14201     @brief determine the type prefix of container values
14202     */
ubjson_prefix(const BasicJsonType & j) const14203     CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14204     {
14205         switch (j.type())
14206         {
14207             case value_t::null:
14208                 return 'Z';
14209 
14210             case value_t::boolean:
14211                 return j.m_value.boolean ? 'T' : 'F';
14212 
14213             case value_t::number_integer:
14214             {
14215                 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14216                 {
14217                     return 'i';
14218                 }
14219                 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14220                 {
14221                     return 'U';
14222                 }
14223                 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14224                 {
14225                     return 'I';
14226                 }
14227                 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14228                 {
14229                     return 'l';
14230                 }
14231                 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14232                 {
14233                     return 'L';
14234                 }
14235                 // anything else is treated as high-precision number
14236                 return 'H'; // LCOV_EXCL_LINE
14237             }
14238 
14239             case value_t::number_unsigned:
14240             {
14241                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14242                 {
14243                     return 'i';
14244                 }
14245                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14246                 {
14247                     return 'U';
14248                 }
14249                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14250                 {
14251                     return 'I';
14252                 }
14253                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14254                 {
14255                     return 'l';
14256                 }
14257                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14258                 {
14259                     return 'L';
14260                 }
14261                 // anything else is treated as high-precision number
14262                 return 'H'; // LCOV_EXCL_LINE
14263             }
14264 
14265             case value_t::number_float:
14266                 return get_ubjson_float_prefix(j.m_value.number_float);
14267 
14268             case value_t::string:
14269                 return 'S';
14270 
14271             case value_t::array: // fallthrough
14272             case value_t::binary:
14273                 return '[';
14274 
14275             case value_t::object:
14276                 return '{';
14277 
14278             default:  // discarded values
14279                 return 'N';
14280         }
14281     }
14282 
get_ubjson_float_prefix(float)14283     static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14284     {
14285         return 'd';  // float 32
14286     }
14287 
get_ubjson_float_prefix(double)14288     static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14289     {
14290         return 'D';  // float 64
14291     }
14292 
14293     ///////////////////////
14294     // Utility functions //
14295     ///////////////////////
14296 
14297     /*
14298     @brief write a number to output input
14299     @param[in] n number of type @a NumberType
14300     @tparam NumberType the type of the number
14301     @tparam OutputIsLittleEndian Set to true if output data is
14302                                  required to be little endian
14303 
14304     @note This function needs to respect the system's endianess, because bytes
14305           in CBOR, MessagePack, and UBJSON are stored in network order (big
14306           endian) and therefore need reordering on little endian systems.
14307     */
14308     template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)14309     void write_number(const NumberType n)
14310     {
14311         // step 1: write number to array of length NumberType
14312         std::array<CharType, sizeof(NumberType)> vec;
14313         std::memcpy(vec.data(), &n, sizeof(NumberType));
14314 
14315         // step 2: write array to output (with possible reordering)
14316         if (is_little_endian != OutputIsLittleEndian)
14317         {
14318             // reverse byte order prior to conversion if necessary
14319             std::reverse(vec.begin(), vec.end());
14320         }
14321 
14322         oa->write_characters(vec.data(), sizeof(NumberType));
14323     }
14324 
write_compact_float(const number_float_t n,detail::input_format_t format)14325     void write_compact_float(const number_float_t n, detail::input_format_t format)
14326     {
14327         if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14328                 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14329                 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14330         {
14331             oa->write_character(format == detail::input_format_t::cbor
14332                                 ? get_cbor_float_prefix(static_cast<float>(n))
14333                                 : get_msgpack_float_prefix(static_cast<float>(n)));
14334             write_number(static_cast<float>(n));
14335         }
14336         else
14337         {
14338             oa->write_character(format == detail::input_format_t::cbor
14339                                 ? get_cbor_float_prefix(n)
14340                                 : get_msgpack_float_prefix(n));
14341             write_number(n);
14342         }
14343     }
14344 
14345   public:
14346     // The following to_char_type functions are implement the conversion
14347     // between uint8_t and CharType. In case CharType is not unsigned,
14348     // such a conversion is required to allow values greater than 128.
14349     // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14350     template < typename C = CharType,
14351                enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)14352     static constexpr CharType to_char_type(std::uint8_t x) noexcept
14353     {
14354         return *reinterpret_cast<char*>(&x);
14355     }
14356 
14357     template < typename C = CharType,
14358                enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)14359     static CharType to_char_type(std::uint8_t x) noexcept
14360     {
14361         static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14362         static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14363         CharType result;
14364         std::memcpy(&result, &x, sizeof(x));
14365         return result;
14366     }
14367 
14368     template<typename C = CharType,
14369              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)14370     static constexpr CharType to_char_type(std::uint8_t x) noexcept
14371     {
14372         return x;
14373     }
14374 
14375     template < typename InputCharType, typename C = CharType,
14376                enable_if_t <
14377                    std::is_signed<C>::value &&
14378                    std::is_signed<char>::value &&
14379                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14380                    > * = nullptr >
to_char_type(InputCharType x)14381     static constexpr CharType to_char_type(InputCharType x) noexcept
14382     {
14383         return x;
14384     }
14385 
14386   private:
14387     /// whether we can assume little endianess
14388     const bool is_little_endian = little_endianess();
14389 
14390     /// the output
14391     output_adapter_t<CharType> oa = nullptr;
14392 };
14393 }  // namespace detail
14394 }  // namespace nlohmann
14395 
14396 // #include <nlohmann/detail/output/output_adapters.hpp>
14397 
14398 // #include <nlohmann/detail/output/serializer.hpp>
14399 
14400 
14401 #include <algorithm> // reverse, remove, fill, find, none_of
14402 #include <array> // array
14403 #include <clocale> // localeconv, lconv
14404 #include <cmath> // labs, isfinite, isnan, signbit
14405 #include <cstddef> // size_t, ptrdiff_t
14406 #include <cstdint> // uint8_t
14407 #include <cstdio> // snprintf
14408 #include <limits> // numeric_limits
14409 #include <string> // string, char_traits
14410 #include <type_traits> // is_same
14411 #include <utility> // move
14412 
14413 // #include <nlohmann/detail/conversions/to_chars.hpp>
14414 
14415 
14416 #include <array> // array
14417 #include <cmath>   // signbit, isfinite
14418 #include <cstdint> // intN_t, uintN_t
14419 #include <cstring> // memcpy, memmove
14420 #include <limits> // numeric_limits
14421 #include <type_traits> // conditional
14422 
14423 // #include <nlohmann/detail/macro_scope.hpp>
14424 
14425 
14426 namespace nlohmann
14427 {
14428 namespace detail
14429 {
14430 
14431 /*!
14432 @brief implements the Grisu2 algorithm for binary to decimal floating-point
14433 conversion.
14434 
14435 This implementation is a slightly modified version of the reference
14436 implementation which may be obtained from
14437 http://florian.loitsch.com/publications (bench.tar.gz).
14438 
14439 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
14440 
14441 For a detailed description of the algorithm see:
14442 
14443 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
14444     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
14445     Language Design and Implementation, PLDI 2010
14446 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
14447     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
14448     Design and Implementation, PLDI 1996
14449 */
14450 namespace dtoa_impl
14451 {
14452 
14453 template<typename Target, typename Source>
14454 Target reinterpret_bits(const Source source)
14455 {
14456     static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14457 
14458     Target target;
14459     std::memcpy(&target, &source, sizeof(Source));
14460     return target;
14461 }
14462 
14463 struct diyfp // f * 2^e
14464 {
14465     static constexpr int kPrecision = 64; // = q
14466 
14467     std::uint64_t f = 0;
14468     int e = 0;
14469 
diyfpnlohmann::detail::dtoa_impl::diyfp14470     constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
14471 
14472     /*!
14473     @brief returns x - y
14474     @pre x.e == y.e and x.f >= y.f
14475     */
subnlohmann::detail::dtoa_impl::diyfp14476     static diyfp sub(const diyfp& x, const diyfp& y) noexcept
14477     {
14478         JSON_ASSERT(x.e == y.e);
14479         JSON_ASSERT(x.f >= y.f);
14480 
14481         return {x.f - y.f, x.e};
14482     }
14483 
14484     /*!
14485     @brief returns x * y
14486     @note The result is rounded. (Only the upper q bits are returned.)
14487     */
mulnlohmann::detail::dtoa_impl::diyfp14488     static diyfp mul(const diyfp& x, const diyfp& y) noexcept
14489     {
14490         static_assert(kPrecision == 64, "internal error");
14491 
14492         // Computes:
14493         //  f = round((x.f * y.f) / 2^q)
14494         //  e = x.e + y.e + q
14495 
14496         // Emulate the 64-bit * 64-bit multiplication:
14497         //
14498         // p = u * v
14499         //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
14500         //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
14501         //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
14502         //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
14503         //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
14504         //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
14505         //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
14506         //
14507         // (Since Q might be larger than 2^32 - 1)
14508         //
14509         //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
14510         //
14511         // (Q_hi + H does not overflow a 64-bit int)
14512         //
14513         //   = p_lo + 2^64 p_hi
14514 
14515         const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
14516         const std::uint64_t u_hi = x.f >> 32u;
14517         const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
14518         const std::uint64_t v_hi = y.f >> 32u;
14519 
14520         const std::uint64_t p0 = u_lo * v_lo;
14521         const std::uint64_t p1 = u_lo * v_hi;
14522         const std::uint64_t p2 = u_hi * v_lo;
14523         const std::uint64_t p3 = u_hi * v_hi;
14524 
14525         const std::uint64_t p0_hi = p0 >> 32u;
14526         const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
14527         const std::uint64_t p1_hi = p1 >> 32u;
14528         const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
14529         const std::uint64_t p2_hi = p2 >> 32u;
14530 
14531         std::uint64_t Q = p0_hi + p1_lo + p2_lo;
14532 
14533         // The full product might now be computed as
14534         //
14535         // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
14536         // p_lo = p0_lo + (Q << 32)
14537         //
14538         // But in this particular case here, the full p_lo is not required.
14539         // Effectively we only need to add the highest bit in p_lo to p_hi (and
14540         // Q_hi + 1 does not overflow).
14541 
14542         Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
14543 
14544         const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
14545 
14546         return {h, x.e + y.e + 64};
14547     }
14548 
14549     /*!
14550     @brief normalize x such that the significand is >= 2^(q-1)
14551     @pre x.f != 0
14552     */
normalizenlohmann::detail::dtoa_impl::diyfp14553     static diyfp normalize(diyfp x) noexcept
14554     {
14555         JSON_ASSERT(x.f != 0);
14556 
14557         while ((x.f >> 63u) == 0)
14558         {
14559             x.f <<= 1u;
14560             x.e--;
14561         }
14562 
14563         return x;
14564     }
14565 
14566     /*!
14567     @brief normalize x such that the result has the exponent E
14568     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
14569     */
normalize_tonlohmann::detail::dtoa_impl::diyfp14570     static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
14571     {
14572         const int delta = x.e - target_exponent;
14573 
14574         JSON_ASSERT(delta >= 0);
14575         JSON_ASSERT(((x.f << delta) >> delta) == x.f);
14576 
14577         return {x.f << delta, target_exponent};
14578     }
14579 };
14580 
14581 struct boundaries
14582 {
14583     diyfp w;
14584     diyfp minus;
14585     diyfp plus;
14586 };
14587 
14588 /*!
14589 Compute the (normalized) diyfp representing the input number 'value' and its
14590 boundaries.
14591 
14592 @pre value must be finite and positive
14593 */
14594 template<typename FloatType>
compute_boundaries(FloatType value)14595 boundaries compute_boundaries(FloatType value)
14596 {
14597     JSON_ASSERT(std::isfinite(value));
14598     JSON_ASSERT(value > 0);
14599 
14600     // Convert the IEEE representation into a diyfp.
14601     //
14602     // If v is denormal:
14603     //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
14604     // If v is normalized:
14605     //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
14606 
14607     static_assert(std::numeric_limits<FloatType>::is_iec559,
14608                   "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
14609 
14610     constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
14611     constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
14612     constexpr int      kMinExp    = 1 - kBias;
14613     constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
14614 
14615     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
14616 
14617     const std::uint64_t bits = reinterpret_bits<bits_type>(value);
14618     const std::uint64_t E = bits >> (kPrecision - 1);
14619     const std::uint64_t F = bits & (kHiddenBit - 1);
14620 
14621     const bool is_denormal = E == 0;
14622     const diyfp v = is_denormal
14623                     ? diyfp(F, kMinExp)
14624                     : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
14625 
14626     // Compute the boundaries m- and m+ of the floating-point value
14627     // v = f * 2^e.
14628     //
14629     // Determine v- and v+, the floating-point predecessor and successor if v,
14630     // respectively.
14631     //
14632     //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
14633     //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
14634     //
14635     //      v+ = v + 2^e
14636     //
14637     // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
14638     // between m- and m+ round to v, regardless of how the input rounding
14639     // algorithm breaks ties.
14640     //
14641     //      ---+-------------+-------------+-------------+-------------+---  (A)
14642     //         v-            m-            v             m+            v+
14643     //
14644     //      -----------------+------+------+-------------+-------------+---  (B)
14645     //                       v-     m-     v             m+            v+
14646 
14647     const bool lower_boundary_is_closer = F == 0 && E > 1;
14648     const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
14649     const diyfp m_minus = lower_boundary_is_closer
14650                           ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
14651                           : diyfp(2 * v.f - 1, v.e - 1); // (A)
14652 
14653     // Determine the normalized w+ = m+.
14654     const diyfp w_plus = diyfp::normalize(m_plus);
14655 
14656     // Determine w- = m- such that e_(w-) = e_(w+).
14657     const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
14658 
14659     return {diyfp::normalize(v), w_minus, w_plus};
14660 }
14661 
14662 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
14663 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
14664 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
14665 //
14666 //      alpha <= e = e_c + e_w + q <= gamma
14667 //
14668 // or
14669 //
14670 //      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
14671 //                          <= f_c * f_w * 2^gamma
14672 //
14673 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
14674 //
14675 //      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
14676 //
14677 // or
14678 //
14679 //      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
14680 //
14681 // The choice of (alpha,gamma) determines the size of the table and the form of
14682 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
14683 // in practice:
14684 //
14685 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
14686 // processed independently: An integral part p1, and a fractional part p2:
14687 //
14688 //      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
14689 //              = (f div 2^-e) + (f mod 2^-e) * 2^e
14690 //              = p1 + p2 * 2^e
14691 //
14692 // The conversion of p1 into decimal form requires a series of divisions and
14693 // modulos by (a power of) 10. These operations are faster for 32-bit than for
14694 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
14695 // achieved by choosing
14696 //
14697 //      -e >= 32   or   e <= -32 := gamma
14698 //
14699 // In order to convert the fractional part
14700 //
14701 //      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
14702 //
14703 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
14704 // d[-i] are extracted in order:
14705 //
14706 //      (10 * p2) div 2^-e = d[-1]
14707 //      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
14708 //
14709 // The multiplication by 10 must not overflow. It is sufficient to choose
14710 //
14711 //      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
14712 //
14713 // Since p2 = f mod 2^-e < 2^-e,
14714 //
14715 //      -e <= 60   or   e >= -60 := alpha
14716 
14717 constexpr int kAlpha = -60;
14718 constexpr int kGamma = -32;
14719 
14720 struct cached_power // c = f * 2^e ~= 10^k
14721 {
14722     std::uint64_t f;
14723     int e;
14724     int k;
14725 };
14726 
14727 /*!
14728 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
14729 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
14730 satisfies (Definition 3.2 from [1])
14731 
14732      alpha <= e_c + e + q <= gamma.
14733 */
get_cached_power_for_binary_exponent(int e)14734 inline cached_power get_cached_power_for_binary_exponent(int e)
14735 {
14736     // Now
14737     //
14738     //      alpha <= e_c + e + q <= gamma                                    (1)
14739     //      ==> f_c * 2^alpha <= c * 2^e * 2^q
14740     //
14741     // and since the c's are normalized, 2^(q-1) <= f_c,
14742     //
14743     //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
14744     //      ==> 2^(alpha - e - 1) <= c
14745     //
14746     // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
14747     //
14748     //      k = ceil( log_10( 2^(alpha - e - 1) ) )
14749     //        = ceil( (alpha - e - 1) * log_10(2) )
14750     //
14751     // From the paper:
14752     // "In theory the result of the procedure could be wrong since c is rounded,
14753     //  and the computation itself is approximated [...]. In practice, however,
14754     //  this simple function is sufficient."
14755     //
14756     // For IEEE double precision floating-point numbers converted into
14757     // normalized diyfp's w = f * 2^e, with q = 64,
14758     //
14759     //      e >= -1022      (min IEEE exponent)
14760     //           -52        (p - 1)
14761     //           -52        (p - 1, possibly normalize denormal IEEE numbers)
14762     //           -11        (normalize the diyfp)
14763     //         = -1137
14764     //
14765     // and
14766     //
14767     //      e <= +1023      (max IEEE exponent)
14768     //           -52        (p - 1)
14769     //           -11        (normalize the diyfp)
14770     //         = 960
14771     //
14772     // This binary exponent range [-1137,960] results in a decimal exponent
14773     // range [-307,324]. One does not need to store a cached power for each
14774     // k in this range. For each such k it suffices to find a cached power
14775     // such that the exponent of the product lies in [alpha,gamma].
14776     // This implies that the difference of the decimal exponents of adjacent
14777     // table entries must be less than or equal to
14778     //
14779     //      floor( (gamma - alpha) * log_10(2) ) = 8.
14780     //
14781     // (A smaller distance gamma-alpha would require a larger table.)
14782 
14783     // NB:
14784     // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
14785 
14786     constexpr int kCachedPowersMinDecExp = -300;
14787     constexpr int kCachedPowersDecStep = 8;
14788 
14789     static constexpr std::array<cached_power, 79> kCachedPowers =
14790     {
14791         {
14792             { 0xAB70FE17C79AC6CA, -1060, -300 },
14793             { 0xFF77B1FCBEBCDC4F, -1034, -292 },
14794             { 0xBE5691EF416BD60C, -1007, -284 },
14795             { 0x8DD01FAD907FFC3C,  -980, -276 },
14796             { 0xD3515C2831559A83,  -954, -268 },
14797             { 0x9D71AC8FADA6C9B5,  -927, -260 },
14798             { 0xEA9C227723EE8BCB,  -901, -252 },
14799             { 0xAECC49914078536D,  -874, -244 },
14800             { 0x823C12795DB6CE57,  -847, -236 },
14801             { 0xC21094364DFB5637,  -821, -228 },
14802             { 0x9096EA6F3848984F,  -794, -220 },
14803             { 0xD77485CB25823AC7,  -768, -212 },
14804             { 0xA086CFCD97BF97F4,  -741, -204 },
14805             { 0xEF340A98172AACE5,  -715, -196 },
14806             { 0xB23867FB2A35B28E,  -688, -188 },
14807             { 0x84C8D4DFD2C63F3B,  -661, -180 },
14808             { 0xC5DD44271AD3CDBA,  -635, -172 },
14809             { 0x936B9FCEBB25C996,  -608, -164 },
14810             { 0xDBAC6C247D62A584,  -582, -156 },
14811             { 0xA3AB66580D5FDAF6,  -555, -148 },
14812             { 0xF3E2F893DEC3F126,  -529, -140 },
14813             { 0xB5B5ADA8AAFF80B8,  -502, -132 },
14814             { 0x87625F056C7C4A8B,  -475, -124 },
14815             { 0xC9BCFF6034C13053,  -449, -116 },
14816             { 0x964E858C91BA2655,  -422, -108 },
14817             { 0xDFF9772470297EBD,  -396, -100 },
14818             { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
14819             { 0xF8A95FCF88747D94,  -343,  -84 },
14820             { 0xB94470938FA89BCF,  -316,  -76 },
14821             { 0x8A08F0F8BF0F156B,  -289,  -68 },
14822             { 0xCDB02555653131B6,  -263,  -60 },
14823             { 0x993FE2C6D07B7FAC,  -236,  -52 },
14824             { 0xE45C10C42A2B3B06,  -210,  -44 },
14825             { 0xAA242499697392D3,  -183,  -36 },
14826             { 0xFD87B5F28300CA0E,  -157,  -28 },
14827             { 0xBCE5086492111AEB,  -130,  -20 },
14828             { 0x8CBCCC096F5088CC,  -103,  -12 },
14829             { 0xD1B71758E219652C,   -77,   -4 },
14830             { 0x9C40000000000000,   -50,    4 },
14831             { 0xE8D4A51000000000,   -24,   12 },
14832             { 0xAD78EBC5AC620000,     3,   20 },
14833             { 0x813F3978F8940984,    30,   28 },
14834             { 0xC097CE7BC90715B3,    56,   36 },
14835             { 0x8F7E32CE7BEA5C70,    83,   44 },
14836             { 0xD5D238A4ABE98068,   109,   52 },
14837             { 0x9F4F2726179A2245,   136,   60 },
14838             { 0xED63A231D4C4FB27,   162,   68 },
14839             { 0xB0DE65388CC8ADA8,   189,   76 },
14840             { 0x83C7088E1AAB65DB,   216,   84 },
14841             { 0xC45D1DF942711D9A,   242,   92 },
14842             { 0x924D692CA61BE758,   269,  100 },
14843             { 0xDA01EE641A708DEA,   295,  108 },
14844             { 0xA26DA3999AEF774A,   322,  116 },
14845             { 0xF209787BB47D6B85,   348,  124 },
14846             { 0xB454E4A179DD1877,   375,  132 },
14847             { 0x865B86925B9BC5C2,   402,  140 },
14848             { 0xC83553C5C8965D3D,   428,  148 },
14849             { 0x952AB45CFA97A0B3,   455,  156 },
14850             { 0xDE469FBD99A05FE3,   481,  164 },
14851             { 0xA59BC234DB398C25,   508,  172 },
14852             { 0xF6C69A72A3989F5C,   534,  180 },
14853             { 0xB7DCBF5354E9BECE,   561,  188 },
14854             { 0x88FCF317F22241E2,   588,  196 },
14855             { 0xCC20CE9BD35C78A5,   614,  204 },
14856             { 0x98165AF37B2153DF,   641,  212 },
14857             { 0xE2A0B5DC971F303A,   667,  220 },
14858             { 0xA8D9D1535CE3B396,   694,  228 },
14859             { 0xFB9B7CD9A4A7443C,   720,  236 },
14860             { 0xBB764C4CA7A44410,   747,  244 },
14861             { 0x8BAB8EEFB6409C1A,   774,  252 },
14862             { 0xD01FEF10A657842C,   800,  260 },
14863             { 0x9B10A4E5E9913129,   827,  268 },
14864             { 0xE7109BFBA19C0C9D,   853,  276 },
14865             { 0xAC2820D9623BF429,   880,  284 },
14866             { 0x80444B5E7AA7CF85,   907,  292 },
14867             { 0xBF21E44003ACDD2D,   933,  300 },
14868             { 0x8E679C2F5E44FF8F,   960,  308 },
14869             { 0xD433179D9C8CB841,   986,  316 },
14870             { 0x9E19DB92B4E31BA9,  1013,  324 },
14871         }
14872     };
14873 
14874     // This computation gives exactly the same results for k as
14875     //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
14876     // for |e| <= 1500, but doesn't require floating-point operations.
14877     // NB: log_10(2) ~= 78913 / 2^18
14878     JSON_ASSERT(e >= -1500);
14879     JSON_ASSERT(e <=  1500);
14880     const int f = kAlpha - e - 1;
14881     const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
14882 
14883     const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
14884     JSON_ASSERT(index >= 0);
14885     JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
14886 
14887     const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
14888     JSON_ASSERT(kAlpha <= cached.e + e + 64);
14889     JSON_ASSERT(kGamma >= cached.e + e + 64);
14890 
14891     return cached;
14892 }
14893 
14894 /*!
14895 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
14896 For n == 0, returns 1 and sets pow10 := 1.
14897 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)14898 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
14899 {
14900     // LCOV_EXCL_START
14901     if (n >= 1000000000)
14902     {
14903         pow10 = 1000000000;
14904         return 10;
14905     }
14906     // LCOV_EXCL_STOP
14907     else if (n >= 100000000)
14908     {
14909         pow10 = 100000000;
14910         return  9;
14911     }
14912     else if (n >= 10000000)
14913     {
14914         pow10 = 10000000;
14915         return  8;
14916     }
14917     else if (n >= 1000000)
14918     {
14919         pow10 = 1000000;
14920         return  7;
14921     }
14922     else if (n >= 100000)
14923     {
14924         pow10 = 100000;
14925         return  6;
14926     }
14927     else if (n >= 10000)
14928     {
14929         pow10 = 10000;
14930         return  5;
14931     }
14932     else if (n >= 1000)
14933     {
14934         pow10 = 1000;
14935         return  4;
14936     }
14937     else if (n >= 100)
14938     {
14939         pow10 = 100;
14940         return  3;
14941     }
14942     else if (n >= 10)
14943     {
14944         pow10 = 10;
14945         return  2;
14946     }
14947     else
14948     {
14949         pow10 = 1;
14950         return 1;
14951     }
14952 }
14953 
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)14954 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
14955                          std::uint64_t rest, std::uint64_t ten_k)
14956 {
14957     JSON_ASSERT(len >= 1);
14958     JSON_ASSERT(dist <= delta);
14959     JSON_ASSERT(rest <= delta);
14960     JSON_ASSERT(ten_k > 0);
14961 
14962     //               <--------------------------- delta ---->
14963     //                                  <---- dist --------->
14964     // --------------[------------------+-------------------]--------------
14965     //               M-                 w                   M+
14966     //
14967     //                                  ten_k
14968     //                                <------>
14969     //                                       <---- rest ---->
14970     // --------------[------------------+----+--------------]--------------
14971     //                                  w    V
14972     //                                       = buf * 10^k
14973     //
14974     // ten_k represents a unit-in-the-last-place in the decimal representation
14975     // stored in buf.
14976     // Decrement buf by ten_k while this takes buf closer to w.
14977 
14978     // The tests are written in this order to avoid overflow in unsigned
14979     // integer arithmetic.
14980 
14981     while (rest < dist
14982             && delta - rest >= ten_k
14983             && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
14984     {
14985         JSON_ASSERT(buf[len - 1] != '0');
14986         buf[len - 1]--;
14987         rest += ten_k;
14988     }
14989 }
14990 
14991 /*!
14992 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
14993 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
14994 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)14995 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
14996                              diyfp M_minus, diyfp w, diyfp M_plus)
14997 {
14998     static_assert(kAlpha >= -60, "internal error");
14999     static_assert(kGamma <= -32, "internal error");
15000 
15001     // Generates the digits (and the exponent) of a decimal floating-point
15002     // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15003     // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15004     //
15005     //               <--------------------------- delta ---->
15006     //                                  <---- dist --------->
15007     // --------------[------------------+-------------------]--------------
15008     //               M-                 w                   M+
15009     //
15010     // Grisu2 generates the digits of M+ from left to right and stops as soon as
15011     // V is in [M-,M+].
15012 
15013     JSON_ASSERT(M_plus.e >= kAlpha);
15014     JSON_ASSERT(M_plus.e <= kGamma);
15015 
15016     std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15017     std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
15018 
15019     // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15020     //
15021     //      M+ = f * 2^e
15022     //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15023     //         = ((p1        ) * 2^-e + (p2        )) * 2^e
15024     //         = p1 + p2 * 2^e
15025 
15026     const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15027 
15028     auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
15029     std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
15030 
15031     // 1)
15032     //
15033     // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15034 
15035     JSON_ASSERT(p1 > 0);
15036 
15037     std::uint32_t pow10;
15038     const int k = find_largest_pow10(p1, pow10);
15039 
15040     //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15041     //
15042     //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15043     //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
15044     //
15045     //      M+ = p1                                             + p2 * 2^e
15046     //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
15047     //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15048     //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
15049     //
15050     // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15051     //
15052     //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15053     //
15054     // but stop as soon as
15055     //
15056     //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15057 
15058     int n = k;
15059     while (n > 0)
15060     {
15061         // Invariants:
15062         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
15063         //      pow10 = 10^(n-1) <= p1 < 10^n
15064         //
15065         const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
15066         const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
15067         //
15068         //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15069         //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15070         //
15071         JSON_ASSERT(d <= 9);
15072         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15073         //
15074         //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15075         //
15076         p1 = r;
15077         n--;
15078         //
15079         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
15080         //      pow10 = 10^n
15081         //
15082 
15083         // Now check if enough digits have been generated.
15084         // Compute
15085         //
15086         //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15087         //
15088         // Note:
15089         // Since rest and delta share the same exponent e, it suffices to
15090         // compare the significands.
15091         const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15092         if (rest <= delta)
15093         {
15094             // V = buffer * 10^n, with M- <= V <= M+.
15095 
15096             decimal_exponent += n;
15097 
15098             // We may now just stop. But instead look if the buffer could be
15099             // decremented to bring V closer to w.
15100             //
15101             // pow10 = 10^n is now 1 ulp in the decimal representation V.
15102             // The rounding procedure works with diyfp's with an implicit
15103             // exponent of e.
15104             //
15105             //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15106             //
15107             const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15108             grisu2_round(buffer, length, dist, delta, rest, ten_n);
15109 
15110             return;
15111         }
15112 
15113         pow10 /= 10;
15114         //
15115         //      pow10 = 10^(n-1) <= p1 < 10^n
15116         // Invariants restored.
15117     }
15118 
15119     // 2)
15120     //
15121     // The digits of the integral part have been generated:
15122     //
15123     //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15124     //         = buffer            + p2 * 2^e
15125     //
15126     // Now generate the digits of the fractional part p2 * 2^e.
15127     //
15128     // Note:
15129     // No decimal point is generated: the exponent is adjusted instead.
15130     //
15131     // p2 actually represents the fraction
15132     //
15133     //      p2 * 2^e
15134     //          = p2 / 2^-e
15135     //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
15136     //
15137     // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15138     //
15139     //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15140     //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15141     //
15142     // using
15143     //
15144     //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15145     //                = (                   d) * 2^-e + (                   r)
15146     //
15147     // or
15148     //      10^m * p2 * 2^e = d + r * 2^e
15149     //
15150     // i.e.
15151     //
15152     //      M+ = buffer + p2 * 2^e
15153     //         = buffer + 10^-m * (d + r * 2^e)
15154     //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15155     //
15156     // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15157 
15158     JSON_ASSERT(p2 > delta);
15159 
15160     int m = 0;
15161     for (;;)
15162     {
15163         // Invariant:
15164         //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15165         //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
15166         //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
15167         //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15168         //
15169         JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15170         p2 *= 10;
15171         const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
15172         const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15173         //
15174         //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15175         //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15176         //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15177         //
15178         JSON_ASSERT(d <= 9);
15179         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15180         //
15181         //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15182         //
15183         p2 = r;
15184         m++;
15185         //
15186         //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15187         // Invariant restored.
15188 
15189         // Check if enough digits have been generated.
15190         //
15191         //      10^-m * p2 * 2^e <= delta * 2^e
15192         //              p2 * 2^e <= 10^m * delta * 2^e
15193         //                    p2 <= 10^m * delta
15194         delta *= 10;
15195         dist  *= 10;
15196         if (p2 <= delta)
15197         {
15198             break;
15199         }
15200     }
15201 
15202     // V = buffer * 10^-m, with M- <= V <= M+.
15203 
15204     decimal_exponent -= m;
15205 
15206     // 1 ulp in the decimal representation is now 10^-m.
15207     // Since delta and dist are now scaled by 10^m, we need to do the
15208     // same with ulp in order to keep the units in sync.
15209     //
15210     //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15211     //
15212     const std::uint64_t ten_m = one.f;
15213     grisu2_round(buffer, length, dist, delta, p2, ten_m);
15214 
15215     // By construction this algorithm generates the shortest possible decimal
15216     // number (Loitsch, Theorem 6.2) which rounds back to w.
15217     // For an input number of precision p, at least
15218     //
15219     //      N = 1 + ceil(p * log_10(2))
15220     //
15221     // decimal digits are sufficient to identify all binary floating-point
15222     // numbers (Matula, "In-and-Out conversions").
15223     // This implies that the algorithm does not produce more than N decimal
15224     // digits.
15225     //
15226     //      N = 17 for p = 53 (IEEE double precision)
15227     //      N = 9  for p = 24 (IEEE single precision)
15228 }
15229 
15230 /*!
15231 v = buf * 10^decimal_exponent
15232 len is the length of the buffer (number of decimal digits)
15233 The buffer must be large enough, i.e. >= max_digits10.
15234 */
15235 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)15236 inline void grisu2(char* buf, int& len, int& decimal_exponent,
15237                    diyfp m_minus, diyfp v, diyfp m_plus)
15238 {
15239     JSON_ASSERT(m_plus.e == m_minus.e);
15240     JSON_ASSERT(m_plus.e == v.e);
15241 
15242     //  --------(-----------------------+-----------------------)--------    (A)
15243     //          m-                      v                       m+
15244     //
15245     //  --------------------(-----------+-----------------------)--------    (B)
15246     //                      m-          v                       m+
15247     //
15248     // First scale v (and m- and m+) such that the exponent is in the range
15249     // [alpha, gamma].
15250 
15251     const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15252 
15253     const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15254 
15255     // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15256     const diyfp w       = diyfp::mul(v,       c_minus_k);
15257     const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15258     const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
15259 
15260     //  ----(---+---)---------------(---+---)---------------(---+---)----
15261     //          w-                      w                       w+
15262     //          = c*m-                  = c*v                   = c*m+
15263     //
15264     // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15265     // w+ are now off by a small amount.
15266     // In fact:
15267     //
15268     //      w - v * 10^k < 1 ulp
15269     //
15270     // To account for this inaccuracy, add resp. subtract 1 ulp.
15271     //
15272     //  --------+---[---------------(---+---)---------------]---+--------
15273     //          w-  M-                  w                   M+  w+
15274     //
15275     // Now any number in [M-, M+] (bounds included) will round to w when input,
15276     // regardless of how the input rounding algorithm breaks ties.
15277     //
15278     // And digit_gen generates the shortest possible such number in [M-, M+].
15279     // Note that this does not mean that Grisu2 always generates the shortest
15280     // possible number in the interval (m-, m+).
15281     const diyfp M_minus(w_minus.f + 1, w_minus.e);
15282     const diyfp M_plus (w_plus.f  - 1, w_plus.e );
15283 
15284     decimal_exponent = -cached.k; // = -(-k) = k
15285 
15286     grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15287 }
15288 
15289 /*!
15290 v = buf * 10^decimal_exponent
15291 len is the length of the buffer (number of decimal digits)
15292 The buffer must be large enough, i.e. >= max_digits10.
15293 */
15294 template<typename FloatType>
15295 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)15296 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15297 {
15298     static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15299                   "internal error: not enough precision");
15300 
15301     JSON_ASSERT(std::isfinite(value));
15302     JSON_ASSERT(value > 0);
15303 
15304     // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15305     // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15306     // decimal representations are not exactly "short".
15307     //
15308     // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15309     // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15310     // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
15311     // does.
15312     // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15313     // representation using the corresponding std::from_chars function recovers value exactly". That
15314     // indicates that single precision floating-point numbers should be recovered using
15315     // 'std::strtof'.
15316     //
15317     // NB: If the neighbors are computed for single-precision numbers, there is a single float
15318     //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15319     //     value is off by 1 ulp.
15320 #if 0
15321     const boundaries w = compute_boundaries(static_cast<double>(value));
15322 #else
15323     const boundaries w = compute_boundaries(value);
15324 #endif
15325 
15326     grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15327 }
15328 
15329 /*!
15330 @brief appends a decimal representation of e to buf
15331 @return a pointer to the element following the exponent.
15332 @pre -1000 < e < 1000
15333 */
15334 JSON_HEDLEY_NON_NULL(1)
15335 JSON_HEDLEY_RETURNS_NON_NULL
append_exponent(char * buf,int e)15336 inline char* append_exponent(char* buf, int e)
15337 {
15338     JSON_ASSERT(e > -1000);
15339     JSON_ASSERT(e <  1000);
15340 
15341     if (e < 0)
15342     {
15343         e = -e;
15344         *buf++ = '-';
15345     }
15346     else
15347     {
15348         *buf++ = '+';
15349     }
15350 
15351     auto k = static_cast<std::uint32_t>(e);
15352     if (k < 10)
15353     {
15354         // Always print at least two digits in the exponent.
15355         // This is for compatibility with printf("%g").
15356         *buf++ = '0';
15357         *buf++ = static_cast<char>('0' + k);
15358     }
15359     else if (k < 100)
15360     {
15361         *buf++ = static_cast<char>('0' + k / 10);
15362         k %= 10;
15363         *buf++ = static_cast<char>('0' + k);
15364     }
15365     else
15366     {
15367         *buf++ = static_cast<char>('0' + k / 100);
15368         k %= 100;
15369         *buf++ = static_cast<char>('0' + k / 10);
15370         k %= 10;
15371         *buf++ = static_cast<char>('0' + k);
15372     }
15373 
15374     return buf;
15375 }
15376 
15377 /*!
15378 @brief prettify v = buf * 10^decimal_exponent
15379 
15380 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
15381 notation. Otherwise it will be printed in exponential notation.
15382 
15383 @pre min_exp < 0
15384 @pre max_exp > 0
15385 */
15386 JSON_HEDLEY_NON_NULL(1)
15387 JSON_HEDLEY_RETURNS_NON_NULL
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)15388 inline char* format_buffer(char* buf, int len, int decimal_exponent,
15389                            int min_exp, int max_exp)
15390 {
15391     JSON_ASSERT(min_exp < 0);
15392     JSON_ASSERT(max_exp > 0);
15393 
15394     const int k = len;
15395     const int n = len + decimal_exponent;
15396 
15397     // v = buf * 10^(n-k)
15398     // k is the length of the buffer (number of decimal digits)
15399     // n is the position of the decimal point relative to the start of the buffer.
15400 
15401     if (k <= n && n <= max_exp)
15402     {
15403         // digits[000]
15404         // len <= max_exp + 2
15405 
15406         std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15407         // Make it look like a floating-point number (#362, #378)
15408         buf[n + 0] = '.';
15409         buf[n + 1] = '0';
15410         return buf + (static_cast<size_t>(n) + 2);
15411     }
15412 
15413     if (0 < n && n <= max_exp)
15414     {
15415         // dig.its
15416         // len <= max_digits10 + 1
15417 
15418         JSON_ASSERT(k > n);
15419 
15420         std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15421         buf[n] = '.';
15422         return buf + (static_cast<size_t>(k) + 1U);
15423     }
15424 
15425     if (min_exp < n && n <= 0)
15426     {
15427         // 0.[000]digits
15428         // len <= 2 + (-min_exp - 1) + max_digits10
15429 
15430         std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15431         buf[0] = '0';
15432         buf[1] = '.';
15433         std::memset(buf + 2, '0', static_cast<size_t>(-n));
15434         return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15435     }
15436 
15437     if (k == 1)
15438     {
15439         // dE+123
15440         // len <= 1 + 5
15441 
15442         buf += 1;
15443     }
15444     else
15445     {
15446         // d.igitsE+123
15447         // len <= max_digits10 + 1 + 5
15448 
15449         std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15450         buf[1] = '.';
15451         buf += 1 + static_cast<size_t>(k);
15452     }
15453 
15454     *buf++ = 'e';
15455     return append_exponent(buf, n - 1);
15456 }
15457 
15458 } // namespace dtoa_impl
15459 
15460 /*!
15461 @brief generates a decimal representation of the floating-point number value in [first, last).
15462 
15463 The format of the resulting decimal representation is similar to printf's %g
15464 format. Returns an iterator pointing past-the-end of the decimal representation.
15465 
15466 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
15467 @note The buffer must be large enough.
15468 @note The result is NOT null-terminated.
15469 */
15470 template<typename FloatType>
15471 JSON_HEDLEY_NON_NULL(1, 2)
15472 JSON_HEDLEY_RETURNS_NON_NULL
to_chars(char * first,const char * last,FloatType value)15473 char* to_chars(char* first, const char* last, FloatType value)
15474 {
15475     static_cast<void>(last); // maybe unused - fix warning
15476     JSON_ASSERT(std::isfinite(value));
15477 
15478     // Use signbit(value) instead of (value < 0) since signbit works for -0.
15479     if (std::signbit(value))
15480     {
15481         value = -value;
15482         *first++ = '-';
15483     }
15484 
15485     if (value == 0) // +-0
15486     {
15487         *first++ = '0';
15488         // Make it look like a floating-point number (#362, #378)
15489         *first++ = '.';
15490         *first++ = '0';
15491         return first;
15492     }
15493 
15494     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
15495 
15496     // Compute v = buffer * 10^decimal_exponent.
15497     // The decimal digits are stored in the buffer, which needs to be interpreted
15498     // as an unsigned decimal integer.
15499     // len is the length of the buffer, i.e. the number of decimal digits.
15500     int len = 0;
15501     int decimal_exponent = 0;
15502     dtoa_impl::grisu2(first, len, decimal_exponent, value);
15503 
15504     JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
15505 
15506     // Format the buffer like printf("%.*g", prec, value)
15507     constexpr int kMinExp = -4;
15508     // Use digits10 here to increase compatibility with version 2.
15509     constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
15510 
15511     JSON_ASSERT(last - first >= kMaxExp + 2);
15512     JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
15513     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
15514 
15515     return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
15516 }
15517 
15518 } // namespace detail
15519 } // namespace nlohmann
15520 
15521 // #include <nlohmann/detail/exceptions.hpp>
15522 
15523 // #include <nlohmann/detail/macro_scope.hpp>
15524 
15525 // #include <nlohmann/detail/meta/cpp_future.hpp>
15526 
15527 // #include <nlohmann/detail/output/binary_writer.hpp>
15528 
15529 // #include <nlohmann/detail/output/output_adapters.hpp>
15530 
15531 // #include <nlohmann/detail/value_t.hpp>
15532 
15533 
15534 namespace nlohmann
15535 {
15536 namespace detail
15537 {
15538 ///////////////////
15539 // serialization //
15540 ///////////////////
15541 
15542 /// how to treat decoding errors
15543 enum class error_handler_t
15544 {
15545     strict,  ///< throw a type_error exception in case of invalid UTF-8
15546     replace, ///< replace invalid UTF-8 sequences with U+FFFD
15547     ignore   ///< ignore invalid UTF-8 sequences
15548 };
15549 
15550 template<typename BasicJsonType>
15551 class serializer
15552 {
15553     using string_t = typename BasicJsonType::string_t;
15554     using number_float_t = typename BasicJsonType::number_float_t;
15555     using number_integer_t = typename BasicJsonType::number_integer_t;
15556     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
15557     using binary_char_t = typename BasicJsonType::binary_t::value_type;
15558     static constexpr std::uint8_t UTF8_ACCEPT = 0;
15559     static constexpr std::uint8_t UTF8_REJECT = 1;
15560 
15561   public:
15562     /*!
15563     @param[in] s  output stream to serialize to
15564     @param[in] ichar  indentation character to use
15565     @param[in] error_handler_  how to react on decoding errors
15566     */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)15567     serializer(output_adapter_t<char> s, const char ichar,
15568                error_handler_t error_handler_ = error_handler_t::strict)
15569         : o(std::move(s))
15570         , loc(std::localeconv())
15571         , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
15572         , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
15573         , indent_char(ichar)
15574         , indent_string(512, indent_char)
15575         , error_handler(error_handler_)
15576     {}
15577 
15578     // delete because of pointer members
15579     serializer(const serializer&) = delete;
15580     serializer& operator=(const serializer&) = delete;
15581     serializer(serializer&&) = delete;
15582     serializer& operator=(serializer&&) = delete;
15583     ~serializer() = default;
15584 
15585     /*!
15586     @brief internal implementation of the serialization function
15587 
15588     This function is called by the public member function dump and organizes
15589     the serialization internally. The indentation level is propagated as
15590     additional parameter. In case of arrays and objects, the function is
15591     called recursively.
15592 
15593     - strings and object keys are escaped using `escape_string()`
15594     - integer numbers are converted implicitly via `operator<<`
15595     - floating-point numbers are converted to a string using `"%g"` format
15596     - binary values are serialized as objects containing the subtype and the
15597       byte array
15598 
15599     @param[in] val               value to serialize
15600     @param[in] pretty_print      whether the output shall be pretty-printed
15601     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
15602     in the output are escaped with `\uXXXX` sequences, and the result consists
15603     of ASCII characters only.
15604     @param[in] indent_step       the indent level
15605     @param[in] current_indent    the current indent level (only used internally)
15606     */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)15607     void dump(const BasicJsonType& val,
15608               const bool pretty_print,
15609               const bool ensure_ascii,
15610               const unsigned int indent_step,
15611               const unsigned int current_indent = 0)
15612     {
15613         switch (val.m_type)
15614         {
15615             case value_t::object:
15616             {
15617                 if (val.m_value.object->empty())
15618                 {
15619                     o->write_characters("{}", 2);
15620                     return;
15621                 }
15622 
15623                 if (pretty_print)
15624                 {
15625                     o->write_characters("{\n", 2);
15626 
15627                     // variable to hold indentation for recursive calls
15628                     const auto new_indent = current_indent + indent_step;
15629                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15630                     {
15631                         indent_string.resize(indent_string.size() * 2, ' ');
15632                     }
15633 
15634                     // first n-1 elements
15635                     auto i = val.m_value.object->cbegin();
15636                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15637                     {
15638                         o->write_characters(indent_string.c_str(), new_indent);
15639                         o->write_character('\"');
15640                         dump_escaped(i->first, ensure_ascii);
15641                         o->write_characters("\": ", 3);
15642                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
15643                         o->write_characters(",\n", 2);
15644                     }
15645 
15646                     // last element
15647                     JSON_ASSERT(i != val.m_value.object->cend());
15648                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15649                     o->write_characters(indent_string.c_str(), new_indent);
15650                     o->write_character('\"');
15651                     dump_escaped(i->first, ensure_ascii);
15652                     o->write_characters("\": ", 3);
15653                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
15654 
15655                     o->write_character('\n');
15656                     o->write_characters(indent_string.c_str(), current_indent);
15657                     o->write_character('}');
15658                 }
15659                 else
15660                 {
15661                     o->write_character('{');
15662 
15663                     // first n-1 elements
15664                     auto i = val.m_value.object->cbegin();
15665                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
15666                     {
15667                         o->write_character('\"');
15668                         dump_escaped(i->first, ensure_ascii);
15669                         o->write_characters("\":", 2);
15670                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
15671                         o->write_character(',');
15672                     }
15673 
15674                     // last element
15675                     JSON_ASSERT(i != val.m_value.object->cend());
15676                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
15677                     o->write_character('\"');
15678                     dump_escaped(i->first, ensure_ascii);
15679                     o->write_characters("\":", 2);
15680                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
15681 
15682                     o->write_character('}');
15683                 }
15684 
15685                 return;
15686             }
15687 
15688             case value_t::array:
15689             {
15690                 if (val.m_value.array->empty())
15691                 {
15692                     o->write_characters("[]", 2);
15693                     return;
15694                 }
15695 
15696                 if (pretty_print)
15697                 {
15698                     o->write_characters("[\n", 2);
15699 
15700                     // variable to hold indentation for recursive calls
15701                     const auto new_indent = current_indent + indent_step;
15702                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15703                     {
15704                         indent_string.resize(indent_string.size() * 2, ' ');
15705                     }
15706 
15707                     // first n-1 elements
15708                     for (auto i = val.m_value.array->cbegin();
15709                             i != val.m_value.array->cend() - 1; ++i)
15710                     {
15711                         o->write_characters(indent_string.c_str(), new_indent);
15712                         dump(*i, true, ensure_ascii, indent_step, new_indent);
15713                         o->write_characters(",\n", 2);
15714                     }
15715 
15716                     // last element
15717                     JSON_ASSERT(!val.m_value.array->empty());
15718                     o->write_characters(indent_string.c_str(), new_indent);
15719                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
15720 
15721                     o->write_character('\n');
15722                     o->write_characters(indent_string.c_str(), current_indent);
15723                     o->write_character(']');
15724                 }
15725                 else
15726                 {
15727                     o->write_character('[');
15728 
15729                     // first n-1 elements
15730                     for (auto i = val.m_value.array->cbegin();
15731                             i != val.m_value.array->cend() - 1; ++i)
15732                     {
15733                         dump(*i, false, ensure_ascii, indent_step, current_indent);
15734                         o->write_character(',');
15735                     }
15736 
15737                     // last element
15738                     JSON_ASSERT(!val.m_value.array->empty());
15739                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
15740 
15741                     o->write_character(']');
15742                 }
15743 
15744                 return;
15745             }
15746 
15747             case value_t::string:
15748             {
15749                 o->write_character('\"');
15750                 dump_escaped(*val.m_value.string, ensure_ascii);
15751                 o->write_character('\"');
15752                 return;
15753             }
15754 
15755             case value_t::binary:
15756             {
15757                 if (pretty_print)
15758                 {
15759                     o->write_characters("{\n", 2);
15760 
15761                     // variable to hold indentation for recursive calls
15762                     const auto new_indent = current_indent + indent_step;
15763                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
15764                     {
15765                         indent_string.resize(indent_string.size() * 2, ' ');
15766                     }
15767 
15768                     o->write_characters(indent_string.c_str(), new_indent);
15769 
15770                     o->write_characters("\"bytes\": [", 10);
15771 
15772                     if (!val.m_value.binary->empty())
15773                     {
15774                         for (auto i = val.m_value.binary->cbegin();
15775                                 i != val.m_value.binary->cend() - 1; ++i)
15776                         {
15777                             dump_integer(*i);
15778                             o->write_characters(", ", 2);
15779                         }
15780                         dump_integer(val.m_value.binary->back());
15781                     }
15782 
15783                     o->write_characters("],\n", 3);
15784                     o->write_characters(indent_string.c_str(), new_indent);
15785 
15786                     o->write_characters("\"subtype\": ", 11);
15787                     if (val.m_value.binary->has_subtype())
15788                     {
15789                         dump_integer(val.m_value.binary->subtype());
15790                     }
15791                     else
15792                     {
15793                         o->write_characters("null", 4);
15794                     }
15795                     o->write_character('\n');
15796                     o->write_characters(indent_string.c_str(), current_indent);
15797                     o->write_character('}');
15798                 }
15799                 else
15800                 {
15801                     o->write_characters("{\"bytes\":[", 10);
15802 
15803                     if (!val.m_value.binary->empty())
15804                     {
15805                         for (auto i = val.m_value.binary->cbegin();
15806                                 i != val.m_value.binary->cend() - 1; ++i)
15807                         {
15808                             dump_integer(*i);
15809                             o->write_character(',');
15810                         }
15811                         dump_integer(val.m_value.binary->back());
15812                     }
15813 
15814                     o->write_characters("],\"subtype\":", 12);
15815                     if (val.m_value.binary->has_subtype())
15816                     {
15817                         dump_integer(val.m_value.binary->subtype());
15818                         o->write_character('}');
15819                     }
15820                     else
15821                     {
15822                         o->write_characters("null}", 5);
15823                     }
15824                 }
15825                 return;
15826             }
15827 
15828             case value_t::boolean:
15829             {
15830                 if (val.m_value.boolean)
15831                 {
15832                     o->write_characters("true", 4);
15833                 }
15834                 else
15835                 {
15836                     o->write_characters("false", 5);
15837                 }
15838                 return;
15839             }
15840 
15841             case value_t::number_integer:
15842             {
15843                 dump_integer(val.m_value.number_integer);
15844                 return;
15845             }
15846 
15847             case value_t::number_unsigned:
15848             {
15849                 dump_integer(val.m_value.number_unsigned);
15850                 return;
15851             }
15852 
15853             case value_t::number_float:
15854             {
15855                 dump_float(val.m_value.number_float);
15856                 return;
15857             }
15858 
15859             case value_t::discarded:
15860             {
15861                 o->write_characters("<discarded>", 11);
15862                 return;
15863             }
15864 
15865             case value_t::null:
15866             {
15867                 o->write_characters("null", 4);
15868                 return;
15869             }
15870 
15871             default:            // LCOV_EXCL_LINE
15872                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
15873         }
15874     }
15875 
15876   JSON_PRIVATE_UNLESS_TESTED:
15877     /*!
15878     @brief dump escaped string
15879 
15880     Escape a string by replacing certain special characters by a sequence of an
15881     escape character (backslash) and another character and other control
15882     characters by a sequence of "\u" followed by a four-digit hex
15883     representation. The escaped string is written to output stream @a o.
15884 
15885     @param[in] s  the string to escape
15886     @param[in] ensure_ascii  whether to escape non-ASCII characters with
15887                              \uXXXX sequences
15888 
15889     @complexity Linear in the length of string @a s.
15890     */
15891     void dump_escaped(const string_t& s, const bool ensure_ascii)
15892     {
15893         std::uint32_t codepoint;
15894         std::uint8_t state = UTF8_ACCEPT;
15895         std::size_t bytes = 0;  // number of bytes written to string_buffer
15896 
15897         // number of bytes written at the point of the last valid byte
15898         std::size_t bytes_after_last_accept = 0;
15899         std::size_t undumped_chars = 0;
15900 
15901         for (std::size_t i = 0; i < s.size(); ++i)
15902         {
15903             const auto byte = static_cast<uint8_t>(s[i]);
15904 
15905             switch (decode(state, codepoint, byte))
15906             {
15907                 case UTF8_ACCEPT:  // decode found a new code point
15908                 {
15909                     switch (codepoint)
15910                     {
15911                         case 0x08: // backspace
15912                         {
15913                             string_buffer[bytes++] = '\\';
15914                             string_buffer[bytes++] = 'b';
15915                             break;
15916                         }
15917 
15918                         case 0x09: // horizontal tab
15919                         {
15920                             string_buffer[bytes++] = '\\';
15921                             string_buffer[bytes++] = 't';
15922                             break;
15923                         }
15924 
15925                         case 0x0A: // newline
15926                         {
15927                             string_buffer[bytes++] = '\\';
15928                             string_buffer[bytes++] = 'n';
15929                             break;
15930                         }
15931 
15932                         case 0x0C: // formfeed
15933                         {
15934                             string_buffer[bytes++] = '\\';
15935                             string_buffer[bytes++] = 'f';
15936                             break;
15937                         }
15938 
15939                         case 0x0D: // carriage return
15940                         {
15941                             string_buffer[bytes++] = '\\';
15942                             string_buffer[bytes++] = 'r';
15943                             break;
15944                         }
15945 
15946                         case 0x22: // quotation mark
15947                         {
15948                             string_buffer[bytes++] = '\\';
15949                             string_buffer[bytes++] = '\"';
15950                             break;
15951                         }
15952 
15953                         case 0x5C: // reverse solidus
15954                         {
15955                             string_buffer[bytes++] = '\\';
15956                             string_buffer[bytes++] = '\\';
15957                             break;
15958                         }
15959 
15960                         default:
15961                         {
15962                             // escape control characters (0x00..0x1F) or, if
15963                             // ensure_ascii parameter is used, non-ASCII characters
15964                             if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
15965                             {
15966                                 if (codepoint <= 0xFFFF)
15967                                 {
15968                                     (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
15969                                                     static_cast<std::uint16_t>(codepoint));
15970                                     bytes += 6;
15971                                 }
15972                                 else
15973                                 {
15974                                     (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
15975                                                     static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
15976                                                     static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
15977                                     bytes += 12;
15978                                 }
15979                             }
15980                             else
15981                             {
15982                                 // copy byte to buffer (all previous bytes
15983                                 // been copied have in default case above)
15984                                 string_buffer[bytes++] = s[i];
15985                             }
15986                             break;
15987                         }
15988                     }
15989 
15990                     // write buffer and reset index; there must be 13 bytes
15991                     // left, as this is the maximal number of bytes to be
15992                     // written ("\uxxxx\uxxxx\0") for one code point
15993                     if (string_buffer.size() - bytes < 13)
15994                     {
15995                         o->write_characters(string_buffer.data(), bytes);
15996                         bytes = 0;
15997                     }
15998 
15999                     // remember the byte position of this accept
16000                     bytes_after_last_accept = bytes;
16001                     undumped_chars = 0;
16002                     break;
16003                 }
16004 
16005                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
16006                 {
16007                     switch (error_handler)
16008                     {
16009                         case error_handler_t::strict:
16010                         {
16011                             std::string sn(3, '\0');
16012                             (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16013                             JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
16014                         }
16015 
16016                         case error_handler_t::ignore:
16017                         case error_handler_t::replace:
16018                         {
16019                             // in case we saw this character the first time, we
16020                             // would like to read it again, because the byte
16021                             // may be OK for itself, but just not OK for the
16022                             // previous sequence
16023                             if (undumped_chars > 0)
16024                             {
16025                                 --i;
16026                             }
16027 
16028                             // reset length buffer to the last accepted index;
16029                             // thus removing/ignoring the invalid characters
16030                             bytes = bytes_after_last_accept;
16031 
16032                             if (error_handler == error_handler_t::replace)
16033                             {
16034                                 // add a replacement character
16035                                 if (ensure_ascii)
16036                                 {
16037                                     string_buffer[bytes++] = '\\';
16038                                     string_buffer[bytes++] = 'u';
16039                                     string_buffer[bytes++] = 'f';
16040                                     string_buffer[bytes++] = 'f';
16041                                     string_buffer[bytes++] = 'f';
16042                                     string_buffer[bytes++] = 'd';
16043                                 }
16044                                 else
16045                                 {
16046                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16047                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16048                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16049                                 }
16050 
16051                                 // write buffer and reset index; there must be 13 bytes
16052                                 // left, as this is the maximal number of bytes to be
16053                                 // written ("\uxxxx\uxxxx\0") for one code point
16054                                 if (string_buffer.size() - bytes < 13)
16055                                 {
16056                                     o->write_characters(string_buffer.data(), bytes);
16057                                     bytes = 0;
16058                                 }
16059 
16060                                 bytes_after_last_accept = bytes;
16061                             }
16062 
16063                             undumped_chars = 0;
16064 
16065                             // continue processing the string
16066                             state = UTF8_ACCEPT;
16067                             break;
16068                         }
16069 
16070                         default:            // LCOV_EXCL_LINE
16071                             JSON_ASSERT(false);  // LCOV_EXCL_LINE
16072                     }
16073                     break;
16074                 }
16075 
16076                 default:  // decode found yet incomplete multi-byte code point
16077                 {
16078                     if (!ensure_ascii)
16079                     {
16080                         // code point will not be escaped - copy byte to buffer
16081                         string_buffer[bytes++] = s[i];
16082                     }
16083                     ++undumped_chars;
16084                     break;
16085                 }
16086             }
16087         }
16088 
16089         // we finished processing the string
16090         if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16091         {
16092             // write buffer
16093             if (bytes > 0)
16094             {
16095                 o->write_characters(string_buffer.data(), bytes);
16096             }
16097         }
16098         else
16099         {
16100             // we finish reading, but do not accept: string was incomplete
16101             switch (error_handler)
16102             {
16103                 case error_handler_t::strict:
16104                 {
16105                     std::string sn(3, '\0');
16106                     (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16107                     JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
16108                 }
16109 
16110                 case error_handler_t::ignore:
16111                 {
16112                     // write all accepted bytes
16113                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
16114                     break;
16115                 }
16116 
16117                 case error_handler_t::replace:
16118                 {
16119                     // write all accepted bytes
16120                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
16121                     // add a replacement character
16122                     if (ensure_ascii)
16123                     {
16124                         o->write_characters("\\ufffd", 6);
16125                     }
16126                     else
16127                     {
16128                         o->write_characters("\xEF\xBF\xBD", 3);
16129                     }
16130                     break;
16131                 }
16132 
16133                 default:            // LCOV_EXCL_LINE
16134                     JSON_ASSERT(false);  // LCOV_EXCL_LINE
16135             }
16136         }
16137     }
16138 
16139   private:
16140     /*!
16141     @brief count digits
16142 
16143     Count the number of decimal (base 10) digits for an input unsigned integer.
16144 
16145     @param[in] x  unsigned integer number to count its digits
16146     @return    number of decimal digits
16147     */
count_digits(number_unsigned_t x)16148     inline unsigned int count_digits(number_unsigned_t x) noexcept
16149     {
16150         unsigned int n_digits = 1;
16151         for (;;)
16152         {
16153             if (x < 10)
16154             {
16155                 return n_digits;
16156             }
16157             if (x < 100)
16158             {
16159                 return n_digits + 1;
16160             }
16161             if (x < 1000)
16162             {
16163                 return n_digits + 2;
16164             }
16165             if (x < 10000)
16166             {
16167                 return n_digits + 3;
16168             }
16169             x = x / 10000u;
16170             n_digits += 4;
16171         }
16172     }
16173 
16174     /*!
16175     @brief dump an integer
16176 
16177     Dump a given integer to output stream @a o. Works internally with
16178     @a number_buffer.
16179 
16180     @param[in] x  integer number (signed or unsigned) to dump
16181     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
16182     */
16183     template < typename NumberType, detail::enable_if_t <
16184                    std::is_same<NumberType, number_unsigned_t>::value ||
16185                    std::is_same<NumberType, number_integer_t>::value ||
16186                    std::is_same<NumberType, binary_char_t>::value,
16187                    int > = 0 >
dump_integer(NumberType x)16188     void dump_integer(NumberType x)
16189     {
16190         static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16191         {
16192             {
16193                 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16194                 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16195                 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16196                 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16197                 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16198                 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16199                 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16200                 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16201                 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16202                 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16203             }
16204         };
16205 
16206         // special case for "0"
16207         if (x == 0)
16208         {
16209             o->write_character('0');
16210             return;
16211         }
16212 
16213         // use a pointer to fill the buffer
16214         auto buffer_ptr = number_buffer.begin();
16215 
16216         const bool is_negative = std::is_same<NumberType, number_integer_t>::value && !(x >= 0); // see issue #755
16217         number_unsigned_t abs_value;
16218 
16219         unsigned int n_chars;
16220 
16221         if (is_negative)
16222         {
16223             *buffer_ptr = '-';
16224             abs_value = remove_sign(static_cast<number_integer_t>(x));
16225 
16226             // account one more byte for the minus sign
16227             n_chars = 1 + count_digits(abs_value);
16228         }
16229         else
16230         {
16231             abs_value = static_cast<number_unsigned_t>(x);
16232             n_chars = count_digits(abs_value);
16233         }
16234 
16235         // spare 1 byte for '\0'
16236         JSON_ASSERT(n_chars < number_buffer.size() - 1);
16237 
16238         // jump to the end to generate the string from backward
16239         // so we later avoid reversing the result
16240         buffer_ptr += n_chars;
16241 
16242         // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16243         // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16244         while (abs_value >= 100)
16245         {
16246             const auto digits_index = static_cast<unsigned>((abs_value % 100));
16247             abs_value /= 100;
16248             *(--buffer_ptr) = digits_to_99[digits_index][1];
16249             *(--buffer_ptr) = digits_to_99[digits_index][0];
16250         }
16251 
16252         if (abs_value >= 10)
16253         {
16254             const auto digits_index = static_cast<unsigned>(abs_value);
16255             *(--buffer_ptr) = digits_to_99[digits_index][1];
16256             *(--buffer_ptr) = digits_to_99[digits_index][0];
16257         }
16258         else
16259         {
16260             *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16261         }
16262 
16263         o->write_characters(number_buffer.data(), n_chars);
16264     }
16265 
16266     /*!
16267     @brief dump a floating-point number
16268 
16269     Dump a given floating-point number to output stream @a o. Works internally
16270     with @a number_buffer.
16271 
16272     @param[in] x  floating-point number to dump
16273     */
dump_float(number_float_t x)16274     void dump_float(number_float_t x)
16275     {
16276         // NaN / inf
16277         if (!std::isfinite(x))
16278         {
16279             o->write_characters("null", 4);
16280             return;
16281         }
16282 
16283         // If number_float_t is an IEEE-754 single or double precision number,
16284         // use the Grisu2 algorithm to produce short numbers which are
16285         // guaranteed to round-trip, using strtof and strtod, resp.
16286         //
16287         // NB: The test below works if <long double> == <double>.
16288         static constexpr bool is_ieee_single_or_double
16289             = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
16290               (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
16291 
16292         dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16293     }
16294 
dump_float(number_float_t x,std::true_type)16295     void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16296     {
16297         char* begin = number_buffer.data();
16298         char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16299 
16300         o->write_characters(begin, static_cast<size_t>(end - begin));
16301     }
16302 
dump_float(number_float_t x,std::false_type)16303     void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16304     {
16305         // get number of digits for a float -> text -> float round-trip
16306         static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16307 
16308         // the actual conversion
16309         std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16310 
16311         // negative value indicates an error
16312         JSON_ASSERT(len > 0);
16313         // check if buffer was large enough
16314         JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16315 
16316         // erase thousands separator
16317         if (thousands_sep != '\0')
16318         {
16319             const auto end = std::remove(number_buffer.begin(),
16320                                          number_buffer.begin() + len, thousands_sep);
16321             std::fill(end, number_buffer.end(), '\0');
16322             JSON_ASSERT((end - number_buffer.begin()) <= len);
16323             len = (end - number_buffer.begin());
16324         }
16325 
16326         // convert decimal point to '.'
16327         if (decimal_point != '\0' && decimal_point != '.')
16328         {
16329             const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16330             if (dec_pos != number_buffer.end())
16331             {
16332                 *dec_pos = '.';
16333             }
16334         }
16335 
16336         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16337 
16338         // determine if need to append ".0"
16339         const bool value_is_int_like =
16340             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16341                          [](char c)
16342         {
16343             return c == '.' || c == 'e';
16344         });
16345 
16346         if (value_is_int_like)
16347         {
16348             o->write_characters(".0", 2);
16349         }
16350     }
16351 
16352     /*!
16353     @brief check whether a string is UTF-8 encoded
16354 
16355     The function checks each byte of a string whether it is UTF-8 encoded. The
16356     result of the check is stored in the @a state parameter. The function must
16357     be called initially with state 0 (accept). State 1 means the string must
16358     be rejected, because the current byte is not allowed. If the string is
16359     completely processed, but the state is non-zero, the string ended
16360     prematurely; that is, the last byte indicated more bytes should have
16361     followed.
16362 
16363     @param[in,out] state  the state of the decoding
16364     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
16365     @param[in] byte       next byte to decode
16366     @return               new state
16367 
16368     @note The function has been edited: a std::array is used.
16369 
16370     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
16371     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
16372     */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)16373     static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16374     {
16375         static const std::array<std::uint8_t, 400> utf8d =
16376         {
16377             {
16378                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
16379                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
16380                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
16381                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
16382                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
16383                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
16384                 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
16385                 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16386                 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16387                 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16388                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
16389                 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
16390                 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
16391                 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
16392             }
16393         };
16394 
16395         const std::uint8_t type = utf8d[byte];
16396 
16397         codep = (state != UTF8_ACCEPT)
16398                 ? (byte & 0x3fu) | (codep << 6u)
16399                 : (0xFFu >> type) & (byte);
16400 
16401         std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16402         JSON_ASSERT(index < 400);
16403         state = utf8d[index];
16404         return state;
16405     }
16406 
16407     /*
16408      * Overload to make the compiler happy while it is instantiating
16409      * dump_integer for number_unsigned_t.
16410      * Must never be called.
16411      */
remove_sign(number_unsigned_t x)16412     number_unsigned_t remove_sign(number_unsigned_t x)
16413     {
16414         JSON_ASSERT(false); // LCOV_EXCL_LINE
16415         return x; // LCOV_EXCL_LINE
16416     }
16417 
16418     /*
16419      * Helper function for dump_integer
16420      *
16421      * This function takes a negative signed integer and returns its absolute
16422      * value as unsigned integer. The plus/minus shuffling is necessary as we can
16423      * not directly remove the sign of an arbitrary signed integer as the
16424      * absolute values of INT_MIN and INT_MAX are usually not the same. See
16425      * #1708 for details.
16426      */
remove_sign(number_integer_t x)16427     inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16428     {
16429         JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)());
16430         return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16431     }
16432 
16433   private:
16434     /// the output of the serializer
16435     output_adapter_t<char> o = nullptr;
16436 
16437     /// a (hopefully) large enough character buffer
16438     std::array<char, 64> number_buffer{{}};
16439 
16440     /// the locale
16441     const std::lconv* loc = nullptr;
16442     /// the locale's thousand separator character
16443     const char thousands_sep = '\0';
16444     /// the locale's decimal point character
16445     const char decimal_point = '\0';
16446 
16447     /// string buffer
16448     std::array<char, 512> string_buffer{{}};
16449 
16450     /// the indentation character
16451     const char indent_char;
16452     /// the indentation string
16453     string_t indent_string;
16454 
16455     /// error_handler how to react on decoding errors
16456     const error_handler_t error_handler;
16457 };
16458 }  // namespace detail
16459 }  // namespace nlohmann
16460 
16461 // #include <nlohmann/detail/value_t.hpp>
16462 
16463 // #include <nlohmann/json_fwd.hpp>
16464 
16465 // #include <nlohmann/ordered_map.hpp>
16466 
16467 
16468 #include <functional> // less
16469 #include <memory> // allocator
16470 #include <utility> // pair
16471 #include <vector> // vector
16472 
16473 // #include <nlohmann/detail/macro_scope.hpp>
16474 
16475 
16476 namespace nlohmann
16477 {
16478 
16479 /// ordered_map: a minimal map-like container that preserves insertion order
16480 /// for use within nlohmann::basic_json<ordered_map>
16481 template <class Key, class T, class IgnoredLess = std::less<Key>,
16482           class Allocator = std::allocator<std::pair<const Key, T>>>
16483                   struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
16484 {
16485     using key_type = Key;
16486     using mapped_type = T;
16487     using Container = std::vector<std::pair<const Key, T>, Allocator>;
16488     using typename Container::iterator;
16489     using typename Container::const_iterator;
16490     using typename Container::size_type;
16491     using typename Container::value_type;
16492 
16493     // Explicit constructors instead of `using Container::Container`
16494     // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_mapnlohmann::ordered_map16495     ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
16496     template <class It>
ordered_mapnlohmann::ordered_map16497     ordered_map(It first, It last, const Allocator& alloc = Allocator())
16498         : Container{first, last, alloc} {}
ordered_mapnlohmann::ordered_map16499     ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
16500         : Container{init, alloc} {}
16501 
emplacenlohmann::ordered_map16502     std::pair<iterator, bool> emplace(const key_type& key, T&& t)
16503     {
16504         for (auto it = this->begin(); it != this->end(); ++it)
16505         {
16506             if (it->first == key)
16507             {
16508                 return {it, false};
16509             }
16510         }
16511         Container::emplace_back(key, t);
16512         return {--this->end(), true};
16513     }
16514 
operator []nlohmann::ordered_map16515     T& operator[](const Key& key)
16516     {
16517         return emplace(key, T{}).first->second;
16518     }
16519 
operator []nlohmann::ordered_map16520     const T& operator[](const Key& key) const
16521     {
16522         return at(key);
16523     }
16524 
atnlohmann::ordered_map16525     T& at(const Key& key)
16526     {
16527         for (auto it = this->begin(); it != this->end(); ++it)
16528         {
16529             if (it->first == key)
16530             {
16531                 return it->second;
16532             }
16533         }
16534 
16535         JSON_THROW(std::out_of_range("key not found"));
16536     }
16537 
atnlohmann::ordered_map16538     const T& at(const Key& key) const
16539     {
16540         for (auto it = this->begin(); it != this->end(); ++it)
16541         {
16542             if (it->first == key)
16543             {
16544                 return it->second;
16545             }
16546         }
16547 
16548         JSON_THROW(std::out_of_range("key not found"));
16549     }
16550 
erasenlohmann::ordered_map16551     size_type erase(const Key& key)
16552     {
16553         for (auto it = this->begin(); it != this->end(); ++it)
16554         {
16555             if (it->first == key)
16556             {
16557                 // Since we cannot move const Keys, re-construct them in place
16558                 for (auto next = it; ++next != this->end(); ++it)
16559                 {
16560                     it->~value_type(); // Destroy but keep allocation
16561                     new (&*it) value_type{std::move(*next)};
16562                 }
16563                 Container::pop_back();
16564                 return 1;
16565             }
16566         }
16567         return 0;
16568     }
16569 
erasenlohmann::ordered_map16570     iterator erase(iterator pos)
16571     {
16572         auto it = pos;
16573 
16574         // Since we cannot move const Keys, re-construct them in place
16575         for (auto next = it; ++next != this->end(); ++it)
16576         {
16577             it->~value_type(); // Destroy but keep allocation
16578             new (&*it) value_type{std::move(*next)};
16579         }
16580         Container::pop_back();
16581         return pos;
16582     }
16583 
countnlohmann::ordered_map16584     size_type count(const Key& key) const
16585     {
16586         for (auto it = this->begin(); it != this->end(); ++it)
16587         {
16588             if (it->first == key)
16589             {
16590                 return 1;
16591             }
16592         }
16593         return 0;
16594     }
16595 
findnlohmann::ordered_map16596     iterator find(const Key& key)
16597     {
16598         for (auto it = this->begin(); it != this->end(); ++it)
16599         {
16600             if (it->first == key)
16601             {
16602                 return it;
16603             }
16604         }
16605         return Container::end();
16606     }
16607 
findnlohmann::ordered_map16608     const_iterator find(const Key& key) const
16609     {
16610         for (auto it = this->begin(); it != this->end(); ++it)
16611         {
16612             if (it->first == key)
16613             {
16614                 return it;
16615             }
16616         }
16617         return Container::end();
16618     }
16619 
insertnlohmann::ordered_map16620     std::pair<iterator, bool> insert( value_type&& value )
16621     {
16622         return emplace(value.first, std::move(value.second));
16623     }
16624 
insertnlohmann::ordered_map16625     std::pair<iterator, bool> insert( const value_type& value )
16626     {
16627         for (auto it = this->begin(); it != this->end(); ++it)
16628         {
16629             if (it->first == value.first)
16630             {
16631                 return {it, false};
16632             }
16633         }
16634         Container::push_back(value);
16635         return {--this->end(), true};
16636     }
16637 };
16638 
16639 }  // namespace nlohmann
16640 
16641 
16642 /*!
16643 @brief namespace for Niels Lohmann
16644 @see https://github.com/nlohmann
16645 @since version 1.0.0
16646 */
16647 namespace nlohmann
16648 {
16649 
16650 /*!
16651 @brief a class to store JSON values
16652 
16653 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
16654 in @ref object_t)
16655 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
16656 in @ref array_t)
16657 @tparam StringType type for JSON strings and object keys (`std::string` by
16658 default; will be used in @ref string_t)
16659 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
16660 in @ref boolean_t)
16661 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
16662 default; will be used in @ref number_integer_t)
16663 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
16664 `uint64_t` by default; will be used in @ref number_unsigned_t)
16665 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
16666 default; will be used in @ref number_float_t)
16667 @tparam BinaryType type for packed binary data for compatibility with binary
16668 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
16669 @ref binary_t)
16670 @tparam AllocatorType type of the allocator to use (`std::allocator` by
16671 default)
16672 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
16673 and `from_json()` (@ref adl_serializer by default)
16674 
16675 @requirement The class satisfies the following concept requirements:
16676 - Basic
16677  - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
16678    JSON values can be default constructed. The result will be a JSON null
16679    value.
16680  - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
16681    A JSON value can be constructed from an rvalue argument.
16682  - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
16683    A JSON value can be copy-constructed from an lvalue expression.
16684  - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
16685    A JSON value van be assigned from an rvalue argument.
16686  - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
16687    A JSON value can be copy-assigned from an lvalue expression.
16688  - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
16689    JSON values can be destructed.
16690 - Layout
16691  - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
16692    JSON values have
16693    [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
16694    All non-static data members are private and standard layout types, the
16695    class has no virtual functions or (virtual) base classes.
16696 - Library-wide
16697  - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
16698    JSON values can be compared with `==`, see @ref
16699    operator==(const_reference,const_reference).
16700  - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
16701    JSON values can be compared with `<`, see @ref
16702    operator<(const_reference,const_reference).
16703  - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
16704    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
16705    other compatible types, using unqualified function call @ref swap().
16706  - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
16707    JSON values can be compared against `std::nullptr_t` objects which are used
16708    to model the `null` value.
16709 - Container
16710  - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
16711    JSON values can be used like STL containers and provide iterator access.
16712  - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
16713    JSON values can be used like STL containers and provide reverse iterator
16714    access.
16715 
16716 @invariant The member variables @a m_value and @a m_type have the following
16717 relationship:
16718 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
16719 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
16720 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
16721 The invariants are checked by member function assert_invariant().
16722 
16723 @internal
16724 @note ObjectType trick from https://stackoverflow.com/a/9860911
16725 @endinternal
16726 
16727 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
16728 Format](http://rfc7159.net/rfc7159)
16729 
16730 @since version 1.0.0
16731 
16732 @nosubgrouping
16733 */
16734 NLOHMANN_BASIC_JSON_TPL_DECLARATION
16735 class basic_json
16736 {
16737   private:
16738     template<detail::value_t> friend struct detail::external_constructor;
16739     friend ::nlohmann::json_pointer<basic_json>;
16740 
16741     template<typename BasicJsonType, typename InputType>
16742     friend class ::nlohmann::detail::parser;
16743     friend ::nlohmann::detail::serializer<basic_json>;
16744     template<typename BasicJsonType>
16745     friend class ::nlohmann::detail::iter_impl;
16746     template<typename BasicJsonType, typename CharType>
16747     friend class ::nlohmann::detail::binary_writer;
16748     template<typename BasicJsonType, typename InputType, typename SAX>
16749     friend class ::nlohmann::detail::binary_reader;
16750     template<typename BasicJsonType>
16751     friend class ::nlohmann::detail::json_sax_dom_parser;
16752     template<typename BasicJsonType>
16753     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
16754 
16755     /// workaround type for MSVC
16756     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
16757 
16758   JSON_PRIVATE_UNLESS_TESTED:
16759     // convenience aliases for types residing in namespace detail;
16760     using lexer = ::nlohmann::detail::lexer_base<basic_json>;
16761 
16762     template<typename InputAdapterType>
parser(InputAdapterType adapter,detail::parser_callback_t<basic_json> cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)16763     static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
16764         InputAdapterType adapter,
16765         detail::parser_callback_t<basic_json>cb = nullptr,
16766         const bool allow_exceptions = true,
16767         const bool ignore_comments = false
16768                                  )
16769     {
16770         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
16771                 std::move(cb), allow_exceptions, ignore_comments);
16772     }
16773 
16774   private:
16775     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
16776     template<typename BasicJsonType>
16777     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
16778     template<typename BasicJsonType>
16779     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
16780     template<typename Iterator>
16781     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
16782     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
16783 
16784     template<typename CharType>
16785     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
16786 
16787     template<typename InputType>
16788     using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
16789     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
16790 
16791   JSON_PRIVATE_UNLESS_TESTED:
16792     using serializer = ::nlohmann::detail::serializer<basic_json>;
16793 
16794   public:
16795     using value_t = detail::value_t;
16796     /// JSON Pointer, see @ref nlohmann::json_pointer
16797     using json_pointer = ::nlohmann::json_pointer<basic_json>;
16798     template<typename T, typename SFINAE>
16799     using json_serializer = JSONSerializer<T, SFINAE>;
16800     /// how to treat decoding errors
16801     using error_handler_t = detail::error_handler_t;
16802     /// how to treat CBOR tags
16803     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
16804     /// helper type for initializer lists of basic_json values
16805     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
16806 
16807     using input_format_t = detail::input_format_t;
16808     /// SAX interface type, see @ref nlohmann::json_sax
16809     using json_sax_t = json_sax<basic_json>;
16810 
16811     ////////////////
16812     // exceptions //
16813     ////////////////
16814 
16815     /// @name exceptions
16816     /// Classes to implement user-defined exceptions.
16817     /// @{
16818 
16819     /// @copydoc detail::exception
16820     using exception = detail::exception;
16821     /// @copydoc detail::parse_error
16822     using parse_error = detail::parse_error;
16823     /// @copydoc detail::invalid_iterator
16824     using invalid_iterator = detail::invalid_iterator;
16825     /// @copydoc detail::type_error
16826     using type_error = detail::type_error;
16827     /// @copydoc detail::out_of_range
16828     using out_of_range = detail::out_of_range;
16829     /// @copydoc detail::other_error
16830     using other_error = detail::other_error;
16831 
16832     /// @}
16833 
16834 
16835     /////////////////////
16836     // container types //
16837     /////////////////////
16838 
16839     /// @name container types
16840     /// The canonic container types to use @ref basic_json like any other STL
16841     /// container.
16842     /// @{
16843 
16844     /// the type of elements in a basic_json container
16845     using value_type = basic_json;
16846 
16847     /// the type of an element reference
16848     using reference = value_type&;
16849     /// the type of an element const reference
16850     using const_reference = const value_type&;
16851 
16852     /// a type to represent differences between iterators
16853     using difference_type = std::ptrdiff_t;
16854     /// a type to represent container sizes
16855     using size_type = std::size_t;
16856 
16857     /// the allocator type
16858     using allocator_type = AllocatorType<basic_json>;
16859 
16860     /// the type of an element pointer
16861     using pointer = typename std::allocator_traits<allocator_type>::pointer;
16862     /// the type of an element const pointer
16863     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
16864 
16865     /// an iterator for a basic_json container
16866     using iterator = iter_impl<basic_json>;
16867     /// a const iterator for a basic_json container
16868     using const_iterator = iter_impl<const basic_json>;
16869     /// a reverse iterator for a basic_json container
16870     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
16871     /// a const reverse iterator for a basic_json container
16872     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
16873 
16874     /// @}
16875 
16876 
16877     /*!
16878     @brief returns the allocator associated with the container
16879     */
get_allocator()16880     static allocator_type get_allocator()
16881     {
16882         return allocator_type();
16883     }
16884 
16885     /*!
16886     @brief returns version information on the library
16887 
16888     This function returns a JSON object with information about the library,
16889     including the version number and information on the platform and compiler.
16890 
16891     @return JSON object holding version information
16892     key         | description
16893     ----------- | ---------------
16894     `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).
16895     `copyright` | The copyright line for the library as string.
16896     `name`      | The name of the library as string.
16897     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
16898     `url`       | The URL of the project as string.
16899     `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).
16900 
16901     @liveexample{The following code shows an example output of the `meta()`
16902     function.,meta}
16903 
16904     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
16905     changes to any JSON value.
16906 
16907     @complexity Constant.
16908 
16909     @since 2.1.0
16910     */
16911     JSON_HEDLEY_WARN_UNUSED_RESULT
meta()16912     static basic_json meta()
16913     {
16914         basic_json result;
16915 
16916         result["copyright"] = "(C) 2013-2020 Niels Lohmann";
16917         result["name"] = "JSON for Modern C++";
16918         result["url"] = "https://github.com/nlohmann/json";
16919         result["version"]["string"] =
16920             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
16921             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
16922             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
16923         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
16924         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
16925         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
16926 
16927 #ifdef _WIN32
16928         result["platform"] = "win32";
16929 #elif defined __linux__
16930         result["platform"] = "linux";
16931 #elif defined __APPLE__
16932         result["platform"] = "apple";
16933 #elif defined __unix__
16934         result["platform"] = "unix";
16935 #else
16936         result["platform"] = "unknown";
16937 #endif
16938 
16939 #if defined(__ICC) || defined(__INTEL_COMPILER)
16940         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
16941 #elif defined(__clang__)
16942         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
16943 #elif defined(__GNUC__) || defined(__GNUG__)
16944         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
16945 #elif defined(__HP_cc) || defined(__HP_aCC)
16946         result["compiler"] = "hp"
16947 #elif defined(__IBMCPP__)
16948         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
16949 #elif defined(_MSC_VER)
16950         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
16951 #elif defined(__PGI)
16952         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
16953 #elif defined(__SUNPRO_CC)
16954         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
16955 #else
16956         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
16957 #endif
16958 
16959 #ifdef __cplusplus
16960         result["compiler"]["c++"] = std::to_string(__cplusplus);
16961 #else
16962         result["compiler"]["c++"] = "unknown";
16963 #endif
16964         return result;
16965     }
16966 
16967 
16968     ///////////////////////////
16969     // JSON value data types //
16970     ///////////////////////////
16971 
16972     /// @name JSON value data types
16973     /// The data types to store a JSON value. These types are derived from
16974     /// the template arguments passed to class @ref basic_json.
16975     /// @{
16976 
16977 #if defined(JSON_HAS_CPP_14)
16978     // Use transparent comparator if possible, combined with perfect forwarding
16979     // on find() and count() calls prevents unnecessary string construction.
16980     using object_comparator_t = std::less<>;
16981 #else
16982     using object_comparator_t = std::less<StringType>;
16983 #endif
16984 
16985     /*!
16986     @brief a type for an object
16987 
16988     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
16989     > An object is an unordered collection of zero or more name/value pairs,
16990     > where a name is a string and a value is a string, number, boolean, null,
16991     > object, or array.
16992 
16993     To store objects in C++, a type is defined by the template parameters
16994     described below.
16995 
16996     @tparam ObjectType  the container to store objects (e.g., `std::map` or
16997     `std::unordered_map`)
16998     @tparam StringType the type of the keys or names (e.g., `std::string`).
16999     The comparison function `std::less<StringType>` is used to order elements
17000     inside the container.
17001     @tparam AllocatorType the allocator to use for objects (e.g.,
17002     `std::allocator`)
17003 
17004     #### Default type
17005 
17006     With the default values for @a ObjectType (`std::map`), @a StringType
17007     (`std::string`), and @a AllocatorType (`std::allocator`), the default
17008     value for @a object_t is:
17009 
17010     @code {.cpp}
17011     std::map<
17012       std::string, // key_type
17013       basic_json, // value_type
17014       std::less<std::string>, // key_compare
17015       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
17016     >
17017     @endcode
17018 
17019     #### Behavior
17020 
17021     The choice of @a object_t influences the behavior of the JSON class. With
17022     the default type, objects have the following behavior:
17023 
17024     - When all names are unique, objects will be interoperable in the sense
17025       that all software implementations receiving that object will agree on
17026       the name-value mappings.
17027     - When the names within an object are not unique, it is unspecified which
17028       one of the values for a given key will be chosen. For instance,
17029       `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
17030       `{"key": 2}`.
17031     - Internally, name/value pairs are stored in lexicographical order of the
17032       names. Objects will also be serialized (see @ref dump) in this order.
17033       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
17034       and serialized as `{"a": 2, "b": 1}`.
17035     - When comparing objects, the order of the name/value pairs is irrelevant.
17036       This makes objects interoperable in the sense that they will not be
17037       affected by these differences. For instance, `{"b": 1, "a": 2}` and
17038       `{"a": 2, "b": 1}` will be treated as equal.
17039 
17040     #### Limits
17041 
17042     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17043     > An implementation may set limits on the maximum depth of nesting.
17044 
17045     In this class, the object's limit of nesting is not explicitly constrained.
17046     However, a maximum depth of nesting may be introduced by the compiler or
17047     runtime environment. A theoretical limit can be queried by calling the
17048     @ref max_size function of a JSON object.
17049 
17050     #### Storage
17051 
17052     Objects are stored as pointers in a @ref basic_json type. That is, for any
17053     access to object values, a pointer of type `object_t*` must be
17054     dereferenced.
17055 
17056     @sa @ref array_t -- type for an array value
17057 
17058     @since version 1.0.0
17059 
17060     @note The order name/value pairs are added to the object is *not*
17061     preserved by the library. Therefore, iterating an object may return
17062     name/value pairs in a different order than they were originally stored. In
17063     fact, keys will be traversed in alphabetical order as `std::map` with
17064     `std::less` is used by default. Please note this behavior conforms to [RFC
17065     7159](http://rfc7159.net/rfc7159), because any order implements the
17066     specified "unordered" nature of JSON objects.
17067     */
17068     using object_t = ObjectType<StringType,
17069           basic_json,
17070           object_comparator_t,
17071           AllocatorType<std::pair<const StringType,
17072           basic_json>>>;
17073 
17074     /*!
17075     @brief a type for an array
17076 
17077     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
17078     > An array is an ordered sequence of zero or more values.
17079 
17080     To store objects in C++, a type is defined by the template parameters
17081     explained below.
17082 
17083     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
17084     `std::list`)
17085     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
17086 
17087     #### Default type
17088 
17089     With the default values for @a ArrayType (`std::vector`) and @a
17090     AllocatorType (`std::allocator`), the default value for @a array_t is:
17091 
17092     @code {.cpp}
17093     std::vector<
17094       basic_json, // value_type
17095       std::allocator<basic_json> // allocator_type
17096     >
17097     @endcode
17098 
17099     #### Limits
17100 
17101     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17102     > An implementation may set limits on the maximum depth of nesting.
17103 
17104     In this class, the array's limit of nesting is not explicitly constrained.
17105     However, a maximum depth of nesting may be introduced by the compiler or
17106     runtime environment. A theoretical limit can be queried by calling the
17107     @ref max_size function of a JSON array.
17108 
17109     #### Storage
17110 
17111     Arrays are stored as pointers in a @ref basic_json type. That is, for any
17112     access to array values, a pointer of type `array_t*` must be dereferenced.
17113 
17114     @sa @ref object_t -- type for an object value
17115 
17116     @since version 1.0.0
17117     */
17118     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17119 
17120     /*!
17121     @brief a type for a string
17122 
17123     [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
17124     > A string is a sequence of zero or more Unicode characters.
17125 
17126     To store objects in C++, a type is defined by the template parameter
17127     described below. Unicode values are split by the JSON class into
17128     byte-sized characters during deserialization.
17129 
17130     @tparam StringType  the container to store strings (e.g., `std::string`).
17131     Note this container is used for keys/names in objects, see @ref object_t.
17132 
17133     #### Default type
17134 
17135     With the default values for @a StringType (`std::string`), the default
17136     value for @a string_t is:
17137 
17138     @code {.cpp}
17139     std::string
17140     @endcode
17141 
17142     #### Encoding
17143 
17144     Strings are stored in UTF-8 encoding. Therefore, functions like
17145     `std::string::size()` or `std::string::length()` return the number of
17146     bytes in the string rather than the number of characters or glyphs.
17147 
17148     #### String comparison
17149 
17150     [RFC 7159](http://rfc7159.net/rfc7159) states:
17151     > Software implementations are typically required to test names of object
17152     > members for equality. Implementations that transform the textual
17153     > representation into sequences of Unicode code units and then perform the
17154     > comparison numerically, code unit by code unit, are interoperable in the
17155     > sense that implementations will agree in all cases on equality or
17156     > inequality of two strings. For example, implementations that compare
17157     > strings with escaped characters unconverted may incorrectly find that
17158     > `"a\\b"` and `"a\u005Cb"` are not equal.
17159 
17160     This implementation is interoperable as it does compare strings code unit
17161     by code unit.
17162 
17163     #### Storage
17164 
17165     String values are stored as pointers in a @ref basic_json type. That is,
17166     for any access to string values, a pointer of type `string_t*` must be
17167     dereferenced.
17168 
17169     @since version 1.0.0
17170     */
17171     using string_t = StringType;
17172 
17173     /*!
17174     @brief a type for a boolean
17175 
17176     [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
17177     type which differentiates the two literals `true` and `false`.
17178 
17179     To store objects in C++, a type is defined by the template parameter @a
17180     BooleanType which chooses the type to use.
17181 
17182     #### Default type
17183 
17184     With the default values for @a BooleanType (`bool`), the default value for
17185     @a boolean_t is:
17186 
17187     @code {.cpp}
17188     bool
17189     @endcode
17190 
17191     #### Storage
17192 
17193     Boolean values are stored directly inside a @ref basic_json type.
17194 
17195     @since version 1.0.0
17196     */
17197     using boolean_t = BooleanType;
17198 
17199     /*!
17200     @brief a type for a number (integer)
17201 
17202     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17203     > The representation of numbers is similar to that used in most
17204     > programming languages. A number is represented in base 10 using decimal
17205     > digits. It contains an integer component that may be prefixed with an
17206     > optional minus sign, which may be followed by a fraction part and/or an
17207     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17208     > cannot be represented in the grammar below (such as Infinity and NaN)
17209     > are not permitted.
17210 
17211     This description includes both integer and floating-point numbers.
17212     However, C++ allows more precise storage if it is known whether the number
17213     is a signed integer, an unsigned integer or a floating-point number.
17214     Therefore, three different types, @ref number_integer_t, @ref
17215     number_unsigned_t and @ref number_float_t are used.
17216 
17217     To store integer numbers in C++, a type is defined by the template
17218     parameter @a NumberIntegerType which chooses the type to use.
17219 
17220     #### Default type
17221 
17222     With the default values for @a NumberIntegerType (`int64_t`), the default
17223     value for @a number_integer_t is:
17224 
17225     @code {.cpp}
17226     int64_t
17227     @endcode
17228 
17229     #### Default behavior
17230 
17231     - The restrictions about leading zeros is not enforced in C++. Instead,
17232       leading zeros in integer literals lead to an interpretation as octal
17233       number. Internally, the value will be stored as decimal number. For
17234       instance, the C++ integer literal `010` will be serialized to `8`.
17235       During deserialization, leading zeros yield an error.
17236     - Not-a-number (NaN) values will be serialized to `null`.
17237 
17238     #### Limits
17239 
17240     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17241     > An implementation may set limits on the range and precision of numbers.
17242 
17243     When the default type is used, the maximal integer number that can be
17244     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
17245     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
17246     that are out of range will yield over/underflow when used in a
17247     constructor. During deserialization, too large or small integer numbers
17248     will be automatically be stored as @ref number_unsigned_t or @ref
17249     number_float_t.
17250 
17251     [RFC 7159](http://rfc7159.net/rfc7159) further states:
17252     > Note that when such software is used, numbers that are integers and are
17253     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17254     > that implementations will agree exactly on their numeric values.
17255 
17256     As this range is a subrange of the exactly supported range [INT64_MIN,
17257     INT64_MAX], this class's integer type is interoperable.
17258 
17259     #### Storage
17260 
17261     Integer number values are stored directly inside a @ref basic_json type.
17262 
17263     @sa @ref number_float_t -- type for number values (floating-point)
17264 
17265     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17266 
17267     @since version 1.0.0
17268     */
17269     using number_integer_t = NumberIntegerType;
17270 
17271     /*!
17272     @brief a type for a number (unsigned)
17273 
17274     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17275     > The representation of numbers is similar to that used in most
17276     > programming languages. A number is represented in base 10 using decimal
17277     > digits. It contains an integer component that may be prefixed with an
17278     > optional minus sign, which may be followed by a fraction part and/or an
17279     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17280     > cannot be represented in the grammar below (such as Infinity and NaN)
17281     > are not permitted.
17282 
17283     This description includes both integer and floating-point numbers.
17284     However, C++ allows more precise storage if it is known whether the number
17285     is a signed integer, an unsigned integer or a floating-point number.
17286     Therefore, three different types, @ref number_integer_t, @ref
17287     number_unsigned_t and @ref number_float_t are used.
17288 
17289     To store unsigned integer numbers in C++, a type is defined by the
17290     template parameter @a NumberUnsignedType which chooses the type to use.
17291 
17292     #### Default type
17293 
17294     With the default values for @a NumberUnsignedType (`uint64_t`), the
17295     default value for @a number_unsigned_t is:
17296 
17297     @code {.cpp}
17298     uint64_t
17299     @endcode
17300 
17301     #### Default behavior
17302 
17303     - The restrictions about leading zeros is not enforced in C++. Instead,
17304       leading zeros in integer literals lead to an interpretation as octal
17305       number. Internally, the value will be stored as decimal number. For
17306       instance, the C++ integer literal `010` will be serialized to `8`.
17307       During deserialization, leading zeros yield an error.
17308     - Not-a-number (NaN) values will be serialized to `null`.
17309 
17310     #### Limits
17311 
17312     [RFC 7159](http://rfc7159.net/rfc7159) specifies:
17313     > An implementation may set limits on the range and precision of numbers.
17314 
17315     When the default type is used, the maximal integer number that can be
17316     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
17317     number that can be stored is `0`. Integer numbers that are out of range
17318     will yield over/underflow when used in a constructor. During
17319     deserialization, too large or small integer numbers will be automatically
17320     be stored as @ref number_integer_t or @ref number_float_t.
17321 
17322     [RFC 7159](http://rfc7159.net/rfc7159) further states:
17323     > Note that when such software is used, numbers that are integers and are
17324     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
17325     > that implementations will agree exactly on their numeric values.
17326 
17327     As this range is a subrange (when considered in conjunction with the
17328     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
17329     this class's integer type is interoperable.
17330 
17331     #### Storage
17332 
17333     Integer number values are stored directly inside a @ref basic_json type.
17334 
17335     @sa @ref number_float_t -- type for number values (floating-point)
17336     @sa @ref number_integer_t -- type for number values (integer)
17337 
17338     @since version 2.0.0
17339     */
17340     using number_unsigned_t = NumberUnsignedType;
17341 
17342     /*!
17343     @brief a type for a number (floating-point)
17344 
17345     [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
17346     > The representation of numbers is similar to that used in most
17347     > programming languages. A number is represented in base 10 using decimal
17348     > digits. It contains an integer component that may be prefixed with an
17349     > optional minus sign, which may be followed by a fraction part and/or an
17350     > exponent part. Leading zeros are not allowed. (...) Numeric values that
17351     > cannot be represented in the grammar below (such as Infinity and NaN)
17352     > are not permitted.
17353 
17354     This description includes both integer and floating-point numbers.
17355     However, C++ allows more precise storage if it is known whether the number
17356     is a signed integer, an unsigned integer or a floating-point number.
17357     Therefore, three different types, @ref number_integer_t, @ref
17358     number_unsigned_t and @ref number_float_t are used.
17359 
17360     To store floating-point numbers in C++, a type is defined by the template
17361     parameter @a NumberFloatType which chooses the type to use.
17362 
17363     #### Default type
17364 
17365     With the default values for @a NumberFloatType (`double`), the default
17366     value for @a number_float_t is:
17367 
17368     @code {.cpp}
17369     double
17370     @endcode
17371 
17372     #### Default behavior
17373 
17374     - The restrictions about leading zeros is not enforced in C++. Instead,
17375       leading zeros in floating-point literals will be ignored. Internally,
17376       the value will be stored as decimal number. For instance, the C++
17377       floating-point literal `01.2` will be serialized to `1.2`. During
17378       deserialization, leading zeros yield an error.
17379     - Not-a-number (NaN) values will be serialized to `null`.
17380 
17381     #### Limits
17382 
17383     [RFC 7159](http://rfc7159.net/rfc7159) states:
17384     > This specification allows implementations to set limits on the range and
17385     > precision of numbers accepted. Since software that implements IEEE
17386     > 754-2008 binary64 (double precision) numbers is generally available and
17387     > widely used, good interoperability can be achieved by implementations
17388     > that expect no more precision or range than these provide, in the sense
17389     > that implementations will approximate JSON numbers within the expected
17390     > precision.
17391 
17392     This implementation does exactly follow this approach, as it uses double
17393     precision floating-point numbers. Note values smaller than
17394     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
17395     will be stored as NaN internally and be serialized to `null`.
17396 
17397     #### Storage
17398 
17399     Floating-point number values are stored directly inside a @ref basic_json
17400     type.
17401 
17402     @sa @ref number_integer_t -- type for number values (integer)
17403 
17404     @sa @ref number_unsigned_t -- type for number values (unsigned integer)
17405 
17406     @since version 1.0.0
17407     */
17408     using number_float_t = NumberFloatType;
17409 
17410     /*!
17411     @brief a type for a packed binary type
17412 
17413     This type is a type designed to carry binary data that appears in various
17414     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
17415     BSON's generic binary subtype. This type is NOT a part of standard JSON and
17416     exists solely for compatibility with these binary types. As such, it is
17417     simply defined as an ordered sequence of zero or more byte values.
17418 
17419     Additionally, as an implementation detail, the subtype of the binary data is
17420     carried around as a `std::uint8_t`, which is compatible with both of the
17421     binary data formats that use binary subtyping, (though the specific
17422     numbering is incompatible with each other, and it is up to the user to
17423     translate between them).
17424 
17425     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
17426     as:
17427     > Major type 2: a byte string. The string's length in bytes is represented
17428     > following the rules for positive integers (major type 0).
17429 
17430     [MessagePack's documentation on the bin type
17431     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
17432     describes this type as:
17433     > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
17434     > in addition to the size of the byte array.
17435 
17436     [BSON's specifications](http://bsonspec.org/spec.html) describe several
17437     binary types; however, this type is intended to represent the generic binary
17438     type which has the description:
17439     > Generic binary subtype - This is the most commonly used binary subtype and
17440     > should be the 'default' for drivers and tools.
17441 
17442     None of these impose any limitations on the internal representation other
17443     than the basic unit of storage be some type of array whose parts are
17444     decomposable into bytes.
17445 
17446     The default representation of this binary format is a
17447     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
17448     array in modern C++.
17449 
17450     #### Default type
17451 
17452     The default values for @a BinaryType is `std::vector<std::uint8_t>`
17453 
17454     #### Storage
17455 
17456     Binary Arrays are stored as pointers in a @ref basic_json type. That is,
17457     for any access to array values, a pointer of the type `binary_t*` must be
17458     dereferenced.
17459 
17460     #### Notes on subtypes
17461 
17462     - CBOR
17463        - Binary values are represented as byte strings. No subtypes are
17464          supported and will be ignored when CBOR is written.
17465     - MessagePack
17466        - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
17467          or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
17468          is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
17469          The subtype is then added as singed 8-bit integer.
17470        - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
17471     - BSON
17472        - If a subtype is given, it is used and added as unsigned 8-bit integer.
17473        - If no subtype is given, the generic binary subtype 0x00 is used.
17474 
17475     @sa @ref binary -- create a binary array
17476 
17477     @since version 3.8.0
17478     */
17479     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
17480     /// @}
17481 
17482   private:
17483 
17484     /// helper for exception-safe object creation
17485     template<typename T, typename... Args>
17486     JSON_HEDLEY_RETURNS_NON_NULL
create(Args &&...args)17487     static T* create(Args&& ... args)
17488     {
17489         AllocatorType<T> alloc;
17490         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17491 
17492         auto deleter = [&](T * object)
17493         {
17494             AllocatorTraits::deallocate(alloc, object, 1);
17495         };
17496         std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
17497         AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
17498         JSON_ASSERT(object != nullptr);
17499         return object.release();
17500     }
17501 
17502     ////////////////////////
17503     // JSON value storage //
17504     ////////////////////////
17505 
17506   JSON_PRIVATE_UNLESS_TESTED:
17507     /*!
17508     @brief a JSON value
17509 
17510     The actual storage for a JSON value of the @ref basic_json class. This
17511     union combines the different storage types for the JSON value types
17512     defined in @ref value_t.
17513 
17514     JSON type | value_t type    | used type
17515     --------- | --------------- | ------------------------
17516     object    | object          | pointer to @ref object_t
17517     array     | array           | pointer to @ref array_t
17518     string    | string          | pointer to @ref string_t
17519     boolean   | boolean         | @ref boolean_t
17520     number    | number_integer  | @ref number_integer_t
17521     number    | number_unsigned | @ref number_unsigned_t
17522     number    | number_float    | @ref number_float_t
17523     binary    | binary          | pointer to @ref binary_t
17524     null      | null            | *no value is stored*
17525 
17526     @note Variable-length types (objects, arrays, and strings) are stored as
17527     pointers. The size of the union should not exceed 64 bits if the default
17528     value types are used.
17529 
17530     @since version 1.0.0
17531     */
17532     union json_value
17533     {
17534         /// object (stored with pointer to save storage)
17535         object_t* object;
17536         /// array (stored with pointer to save storage)
17537         array_t* array;
17538         /// string (stored with pointer to save storage)
17539         string_t* string;
17540         /// binary (stored with pointer to save storage)
17541         binary_t* binary;
17542         /// boolean
17543         boolean_t boolean;
17544         /// number (integer)
17545         number_integer_t number_integer;
17546         /// number (unsigned integer)
17547         number_unsigned_t number_unsigned;
17548         /// number (floating-point)
17549         number_float_t number_float;
17550 
17551         /// default constructor (for null values)
17552         json_value() = default;
17553         /// constructor for booleans
json_value(boolean_t v)17554         json_value(boolean_t v) noexcept : boolean(v) {}
17555         /// constructor for numbers (integer)
json_value(number_integer_t v)17556         json_value(number_integer_t v) noexcept : number_integer(v) {}
17557         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)17558         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
17559         /// constructor for numbers (floating-point)
json_value(number_float_t v)17560         json_value(number_float_t v) noexcept : number_float(v) {}
17561         /// constructor for empty values of a given type
json_value(value_t t)17562         json_value(value_t t)
17563         {
17564             switch (t)
17565             {
17566                 case value_t::object:
17567                 {
17568                     object = create<object_t>();
17569                     break;
17570                 }
17571 
17572                 case value_t::array:
17573                 {
17574                     array = create<array_t>();
17575                     break;
17576                 }
17577 
17578                 case value_t::string:
17579                 {
17580                     string = create<string_t>("");
17581                     break;
17582                 }
17583 
17584                 case value_t::binary:
17585                 {
17586                     binary = create<binary_t>();
17587                     break;
17588                 }
17589 
17590                 case value_t::boolean:
17591                 {
17592                     boolean = boolean_t(false);
17593                     break;
17594                 }
17595 
17596                 case value_t::number_integer:
17597                 {
17598                     number_integer = number_integer_t(0);
17599                     break;
17600                 }
17601 
17602                 case value_t::number_unsigned:
17603                 {
17604                     number_unsigned = number_unsigned_t(0);
17605                     break;
17606                 }
17607 
17608                 case value_t::number_float:
17609                 {
17610                     number_float = number_float_t(0.0);
17611                     break;
17612                 }
17613 
17614                 case value_t::null:
17615                 {
17616                     object = nullptr;  // silence warning, see #821
17617                     break;
17618                 }
17619 
17620                 default:
17621                 {
17622                     object = nullptr;  // silence warning, see #821
17623                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17624                     {
17625                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.9.1")); // LCOV_EXCL_LINE
17626                     }
17627                     break;
17628                 }
17629             }
17630         }
17631 
17632         /// constructor for strings
json_value(const string_t & value)17633         json_value(const string_t& value)
17634         {
17635             string = create<string_t>(value);
17636         }
17637 
17638         /// constructor for rvalue strings
json_value(string_t && value)17639         json_value(string_t&& value)
17640         {
17641             string = create<string_t>(std::move(value));
17642         }
17643 
17644         /// constructor for objects
json_value(const object_t & value)17645         json_value(const object_t& value)
17646         {
17647             object = create<object_t>(value);
17648         }
17649 
17650         /// constructor for rvalue objects
json_value(object_t && value)17651         json_value(object_t&& value)
17652         {
17653             object = create<object_t>(std::move(value));
17654         }
17655 
17656         /// constructor for arrays
json_value(const array_t & value)17657         json_value(const array_t& value)
17658         {
17659             array = create<array_t>(value);
17660         }
17661 
17662         /// constructor for rvalue arrays
json_value(array_t && value)17663         json_value(array_t&& value)
17664         {
17665             array = create<array_t>(std::move(value));
17666         }
17667 
17668         /// constructor for binary arrays
json_value(const typename binary_t::container_type & value)17669         json_value(const typename binary_t::container_type& value)
17670         {
17671             binary = create<binary_t>(value);
17672         }
17673 
17674         /// constructor for rvalue binary arrays
json_value(typename binary_t::container_type && value)17675         json_value(typename binary_t::container_type&& value)
17676         {
17677             binary = create<binary_t>(std::move(value));
17678         }
17679 
17680         /// constructor for binary arrays (internal type)
json_value(const binary_t & value)17681         json_value(const binary_t& value)
17682         {
17683             binary = create<binary_t>(value);
17684         }
17685 
17686         /// constructor for rvalue binary arrays (internal type)
json_value(binary_t && value)17687         json_value(binary_t&& value)
17688         {
17689             binary = create<binary_t>(std::move(value));
17690         }
17691 
destroy(value_t t)17692         void destroy(value_t t) noexcept
17693         {
17694             // flatten the current json_value to a heap-allocated stack
17695             std::vector<basic_json> stack;
17696 
17697             // move the top-level items to stack
17698             if (t == value_t::array)
17699             {
17700                 stack.reserve(array->size());
17701                 std::move(array->begin(), array->end(), std::back_inserter(stack));
17702             }
17703             else if (t == value_t::object)
17704             {
17705                 stack.reserve(object->size());
17706                 for (auto&& it : *object)
17707                 {
17708                     stack.push_back(std::move(it.second));
17709                 }
17710             }
17711 
17712             while (!stack.empty())
17713             {
17714                 // move the last item to local variable to be processed
17715                 basic_json current_item(std::move(stack.back()));
17716                 stack.pop_back();
17717 
17718                 // if current_item is array/object, move
17719                 // its children to the stack to be processed later
17720                 if (current_item.is_array())
17721                 {
17722                     std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(),
17723                               std::back_inserter(stack));
17724 
17725                     current_item.m_value.array->clear();
17726                 }
17727                 else if (current_item.is_object())
17728                 {
17729                     for (auto&& it : *current_item.m_value.object)
17730                     {
17731                         stack.push_back(std::move(it.second));
17732                     }
17733 
17734                     current_item.m_value.object->clear();
17735                 }
17736 
17737                 // it's now safe that current_item get destructed
17738                 // since it doesn't have any children
17739             }
17740 
17741             switch (t)
17742             {
17743                 case value_t::object:
17744                 {
17745                     AllocatorType<object_t> alloc;
17746                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17747                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17748                     break;
17749                 }
17750 
17751                 case value_t::array:
17752                 {
17753                     AllocatorType<array_t> alloc;
17754                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17755                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17756                     break;
17757                 }
17758 
17759                 case value_t::string:
17760                 {
17761                     AllocatorType<string_t> alloc;
17762                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17763                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17764                     break;
17765                 }
17766 
17767                 case value_t::binary:
17768                 {
17769                     AllocatorType<binary_t> alloc;
17770                     std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17771                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17772                     break;
17773                 }
17774 
17775                 default:
17776                 {
17777                     break;
17778                 }
17779             }
17780         }
17781     };
17782 
17783   private:
17784     /*!
17785     @brief checks the class invariants
17786 
17787     This function asserts the class invariants. It needs to be called at the
17788     end of every constructor to make sure that created objects respect the
17789     invariant. Furthermore, it has to be called each time the type of a JSON
17790     value is changed, because the invariant expresses a relationship between
17791     @a m_type and @a m_value.
17792     */
assert_invariant() const17793     void assert_invariant() const noexcept
17794     {
17795         JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17796         JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17797         JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17798         JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17799     }
17800 
17801   public:
17802     //////////////////////////
17803     // JSON parser callback //
17804     //////////////////////////
17805 
17806     /*!
17807     @brief parser event types
17808 
17809     The parser callback distinguishes the following events:
17810     - `object_start`: the parser read `{` and started to process a JSON object
17811     - `key`: the parser read a key of a value in an object
17812     - `object_end`: the parser read `}` and finished processing a JSON object
17813     - `array_start`: the parser read `[` and started to process a JSON array
17814     - `array_end`: the parser read `]` and finished processing a JSON array
17815     - `value`: the parser finished reading a JSON value
17816 
17817     @image html callback_events.png "Example when certain parse events are triggered"
17818 
17819     @sa @ref parser_callback_t for more information and examples
17820     */
17821     using parse_event_t = detail::parse_event_t;
17822 
17823     /*!
17824     @brief per-element parser callback type
17825 
17826     With a parser callback function, the result of parsing a JSON text can be
17827     influenced. When passed to @ref parse, it is called on certain events
17828     (passed as @ref parse_event_t via parameter @a event) with a set recursion
17829     depth @a depth and context JSON value @a parsed. The return value of the
17830     callback function is a boolean indicating whether the element that emitted
17831     the callback shall be kept or not.
17832 
17833     We distinguish six scenarios (determined by the event type) in which the
17834     callback function can be called. The following table describes the values
17835     of the parameters @a depth, @a event, and @a parsed.
17836 
17837     parameter @a event | description | parameter @a depth | parameter @a parsed
17838     ------------------ | ----------- | ------------------ | -------------------
17839     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
17840     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
17841     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
17842     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
17843     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
17844     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
17845 
17846     @image html callback_events.png "Example when certain parse events are triggered"
17847 
17848     Discarding a value (i.e., returning `false`) has different effects
17849     depending on the context in which function was called:
17850 
17851     - Discarded values in structured types are skipped. That is, the parser
17852       will behave as if the discarded value was never read.
17853     - In case a value outside a structured type is skipped, it is replaced
17854       with `null`. This case happens if the top-level element is skipped.
17855 
17856     @param[in] depth  the depth of the recursion during parsing
17857 
17858     @param[in] event  an event of type parse_event_t indicating the context in
17859     the callback function has been called
17860 
17861     @param[in,out] parsed  the current intermediate parse result; note that
17862     writing to this value has no effect for parse_event_t::key events
17863 
17864     @return Whether the JSON value which called the function during parsing
17865     should be kept (`true`) or not (`false`). In the latter case, it is either
17866     skipped completely or replaced by an empty discarded object.
17867 
17868     @sa @ref parse for examples
17869 
17870     @since version 1.0.0
17871     */
17872     using parser_callback_t = detail::parser_callback_t<basic_json>;
17873 
17874     //////////////////
17875     // constructors //
17876     //////////////////
17877 
17878     /// @name constructors and destructors
17879     /// Constructors of class @ref basic_json, copy/move constructor, copy
17880     /// assignment, static functions creating objects, and the destructor.
17881     /// @{
17882 
17883     /*!
17884     @brief create an empty value with a given type
17885 
17886     Create an empty JSON value with a given type. The value will be default
17887     initialized with an empty value which depends on the type:
17888 
17889     Value type  | initial value
17890     ----------- | -------------
17891     null        | `null`
17892     boolean     | `false`
17893     string      | `""`
17894     number      | `0`
17895     object      | `{}`
17896     array       | `[]`
17897     binary      | empty array
17898 
17899     @param[in] v  the type of the value to create
17900 
17901     @complexity Constant.
17902 
17903     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17904     changes to any JSON value.
17905 
17906     @liveexample{The following code shows the constructor for different @ref
17907     value_t values,basic_json__value_t}
17908 
17909     @sa @ref clear() -- restores the postcondition of this constructor
17910 
17911     @since version 1.0.0
17912     */
basic_json(const value_t v)17913     basic_json(const value_t v)
17914         : m_type(v), m_value(v)
17915     {
17916         assert_invariant();
17917     }
17918 
17919     /*!
17920     @brief create a null object
17921 
17922     Create a `null` JSON value. It either takes a null pointer as parameter
17923     (explicitly creating `null`) or no parameter (implicitly creating `null`).
17924     The passed null pointer itself is not read -- it is only used to choose
17925     the right constructor.
17926 
17927     @complexity Constant.
17928 
17929     @exceptionsafety No-throw guarantee: this constructor never throws
17930     exceptions.
17931 
17932     @liveexample{The following code shows the constructor with and without a
17933     null pointer parameter.,basic_json__nullptr_t}
17934 
17935     @since version 1.0.0
17936     */
basic_json(std::nullptr_t=nullptr)17937     basic_json(std::nullptr_t = nullptr) noexcept
17938         : basic_json(value_t::null)
17939     {
17940         assert_invariant();
17941     }
17942 
17943     /*!
17944     @brief create a JSON value
17945 
17946     This is a "catch all" constructor for all compatible JSON types; that is,
17947     types for which a `to_json()` method exists. The constructor forwards the
17948     parameter @a val to that method (to `json_serializer<U>::to_json` method
17949     with `U = uncvref_t<CompatibleType>`, to be exact).
17950 
17951     Template type @a CompatibleType includes, but is not limited to, the
17952     following types:
17953     - **arrays**: @ref array_t and all kinds of compatible containers such as
17954       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
17955       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
17956       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
17957       which a @ref basic_json value can be constructed.
17958     - **objects**: @ref object_t and all kinds of compatible associative
17959       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
17960       and `std::unordered_multimap` with a `key_type` compatible to
17961       @ref string_t and a `value_type` from which a @ref basic_json value can
17962       be constructed.
17963     - **strings**: @ref string_t, string literals, and all compatible string
17964       containers can be used.
17965     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
17966       @ref number_float_t, and all convertible number types such as `int`,
17967       `size_t`, `int64_t`, `float` or `double` can be used.
17968     - **boolean**: @ref boolean_t / `bool` can be used.
17969     - **binary**: @ref binary_t / `std::vector<uint8_t>` may be used,
17970       unfortunately because string literals cannot be distinguished from binary
17971       character arrays by the C++ type system, all types compatible with `const
17972       char*` will be directed to the string constructor instead.  This is both
17973       for backwards compatibility, and due to the fact that a binary type is not
17974       a standard JSON type.
17975 
17976     See the examples below.
17977 
17978     @tparam CompatibleType a type such that:
17979     - @a CompatibleType is not derived from `std::istream`,
17980     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
17981          constructors),
17982     - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
17983     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
17984          @ref json_pointer, @ref iterator, etc ...)
17985     - @ref @ref json_serializer<U> has a
17986          `to_json(basic_json_t&, CompatibleType&&)` method
17987 
17988     @tparam U = `uncvref_t<CompatibleType>`
17989 
17990     @param[in] val the value to be forwarded to the respective constructor
17991 
17992     @complexity Usually linear in the size of the passed @a val, also
17993                 depending on the implementation of the called `to_json()`
17994                 method.
17995 
17996     @exceptionsafety Depends on the called constructor. For types directly
17997     supported by the library (i.e., all types for which no `to_json()` function
17998     was provided), strong guarantee holds: if an exception is thrown, there are
17999     no changes to any JSON value.
18000 
18001     @liveexample{The following code shows the constructor with several
18002     compatible types.,basic_json__CompatibleType}
18003 
18004     @since version 2.1.0
18005     */
18006     template < typename CompatibleType,
18007                typename U = detail::uncvref_t<CompatibleType>,
18008                detail::enable_if_t <
18009                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val)18010     basic_json(CompatibleType && val) noexcept(noexcept(
18011                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18012                                            std::forward<CompatibleType>(val))))
18013     {
18014         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18015         assert_invariant();
18016     }
18017 
18018     /*!
18019     @brief create a JSON value from an existing one
18020 
18021     This is a constructor for existing @ref basic_json types.
18022     It does not hijack copy/move constructors, since the parameter has different
18023     template arguments than the current ones.
18024 
18025     The constructor tries to convert the internal @ref m_value of the parameter.
18026 
18027     @tparam BasicJsonType a type such that:
18028     - @a BasicJsonType is a @ref basic_json type.
18029     - @a BasicJsonType has different template arguments than @ref basic_json_t.
18030 
18031     @param[in] val the @ref basic_json value to be converted.
18032 
18033     @complexity Usually linear in the size of the passed @a val, also
18034                 depending on the implementation of the called `to_json()`
18035                 method.
18036 
18037     @exceptionsafety Depends on the called constructor. For types directly
18038     supported by the library (i.e., all types for which no `to_json()` function
18039     was provided), strong guarantee holds: if an exception is thrown, there are
18040     no changes to any JSON value.
18041 
18042     @since version 3.2.0
18043     */
18044     template < typename BasicJsonType,
18045                detail::enable_if_t <
18046                    detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType & val)18047     basic_json(const BasicJsonType& val)
18048     {
18049         using other_boolean_t = typename BasicJsonType::boolean_t;
18050         using other_number_float_t = typename BasicJsonType::number_float_t;
18051         using other_number_integer_t = typename BasicJsonType::number_integer_t;
18052         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18053         using other_string_t = typename BasicJsonType::string_t;
18054         using other_object_t = typename BasicJsonType::object_t;
18055         using other_array_t = typename BasicJsonType::array_t;
18056         using other_binary_t = typename BasicJsonType::binary_t;
18057 
18058         switch (val.type())
18059         {
18060             case value_t::boolean:
18061                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18062                 break;
18063             case value_t::number_float:
18064                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18065                 break;
18066             case value_t::number_integer:
18067                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18068                 break;
18069             case value_t::number_unsigned:
18070                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18071                 break;
18072             case value_t::string:
18073                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18074                 break;
18075             case value_t::object:
18076                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18077                 break;
18078             case value_t::array:
18079                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18080                 break;
18081             case value_t::binary:
18082                 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18083                 break;
18084             case value_t::null:
18085                 *this = nullptr;
18086                 break;
18087             case value_t::discarded:
18088                 m_type = value_t::discarded;
18089                 break;
18090             default:            // LCOV_EXCL_LINE
18091                 JSON_ASSERT(false);  // LCOV_EXCL_LINE
18092         }
18093         assert_invariant();
18094     }
18095 
18096     /*!
18097     @brief create a container (array or object) from an initializer list
18098 
18099     Creates a JSON value of type array or object from the passed initializer
18100     list @a init. In case @a type_deduction is `true` (default), the type of
18101     the JSON value to be created is deducted from the initializer list @a init
18102     according to the following rules:
18103 
18104     1. If the list is empty, an empty JSON object value `{}` is created.
18105     2. If the list consists of pairs whose first element is a string, a JSON
18106        object value is created where the first elements of the pairs are
18107        treated as keys and the second elements are as values.
18108     3. In all other cases, an array is created.
18109 
18110     The rules aim to create the best fit between a C++ initializer list and
18111     JSON values. The rationale is as follows:
18112 
18113     1. The empty initializer list is written as `{}` which is exactly an empty
18114        JSON object.
18115     2. C++ has no way of describing mapped types other than to list a list of
18116        pairs. As JSON requires that keys must be of type string, rule 2 is the
18117        weakest constraint one can pose on initializer lists to interpret them
18118        as an object.
18119     3. In all other cases, the initializer list could not be interpreted as
18120        JSON object type, so interpreting it as JSON array type is safe.
18121 
18122     With the rules described above, the following JSON values cannot be
18123     expressed by an initializer list:
18124 
18125     - the empty array (`[]`): use @ref array(initializer_list_t)
18126       with an empty initializer list in this case
18127     - arrays whose elements satisfy rule 2: use @ref
18128       array(initializer_list_t) with the same initializer list
18129       in this case
18130 
18131     @note When used without parentheses around an empty initializer list, @ref
18132     basic_json() is called instead of this function, yielding the JSON null
18133     value.
18134 
18135     @param[in] init  initializer list with JSON values
18136 
18137     @param[in] type_deduction internal parameter; when set to `true`, the type
18138     of the JSON value is deducted from the initializer list @a init; when set
18139     to `false`, the type provided via @a manual_type is forced. This mode is
18140     used by the functions @ref array(initializer_list_t) and
18141     @ref object(initializer_list_t).
18142 
18143     @param[in] manual_type internal parameter; when @a type_deduction is set
18144     to `false`, the created JSON value will use the provided type (only @ref
18145     value_t::array and @ref value_t::object are valid); when @a type_deduction
18146     is set to `true`, this parameter has no effect
18147 
18148     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
18149     `value_t::object`, but @a init contains an element which is not a pair
18150     whose first element is a string. In this case, the constructor could not
18151     create an object. If @a type_deduction would have be `true`, an array
18152     would have been created. See @ref object(initializer_list_t)
18153     for an example.
18154 
18155     @complexity Linear in the size of the initializer list @a init.
18156 
18157     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18158     changes to any JSON value.
18159 
18160     @liveexample{The example below shows how JSON values are created from
18161     initializer lists.,basic_json__list_init_t}
18162 
18163     @sa @ref array(initializer_list_t) -- create a JSON array
18164     value from an initializer list
18165     @sa @ref object(initializer_list_t) -- create a JSON object
18166     value from an initializer list
18167 
18168     @since version 1.0.0
18169     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)18170     basic_json(initializer_list_t init,
18171                bool type_deduction = true,
18172                value_t manual_type = value_t::array)
18173     {
18174         // check if each element is an array with two elements whose first
18175         // element is a string
18176         bool is_an_object = std::all_of(init.begin(), init.end(),
18177                                         [](const detail::json_ref<basic_json>& element_ref)
18178         {
18179             return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18180         });
18181 
18182         // adjust type if type deduction is not wanted
18183         if (!type_deduction)
18184         {
18185             // if array is wanted, do not create an object though possible
18186             if (manual_type == value_t::array)
18187             {
18188                 is_an_object = false;
18189             }
18190 
18191             // if object is wanted but impossible, throw an exception
18192             if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18193             {
18194                 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
18195             }
18196         }
18197 
18198         if (is_an_object)
18199         {
18200             // the initializer list is a list of pairs -> create object
18201             m_type = value_t::object;
18202             m_value = value_t::object;
18203 
18204             std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
18205             {
18206                 auto element = element_ref.moved_or_copied();
18207                 m_value.object->emplace(
18208                     std::move(*((*element.m_value.array)[0].m_value.string)),
18209                     std::move((*element.m_value.array)[1]));
18210             });
18211         }
18212         else
18213         {
18214             // the initializer list describes an array -> create array
18215             m_type = value_t::array;
18216             m_value.array = create<array_t>(init.begin(), init.end());
18217         }
18218 
18219         assert_invariant();
18220     }
18221 
18222     /*!
18223     @brief explicitly create a binary array (without subtype)
18224 
18225     Creates a JSON binary array value from a given binary container. Binary
18226     values are part of various binary formats, such as CBOR, MessagePack, and
18227     BSON. This constructor is used to create a value for serialization to those
18228     formats.
18229 
18230     @note Note, this function exists because of the difficulty in correctly
18231     specifying the correct template overload in the standard value ctor, as both
18232     JSON arrays and JSON binary arrays are backed with some form of a
18233     `std::vector`. Because JSON binary arrays are a non-standard extension it
18234     was decided that it would be best to prevent automatic initialization of a
18235     binary array type, for backwards compatibility and so it does not happen on
18236     accident.
18237 
18238     @param[in] init container containing bytes to use as binary type
18239 
18240     @return JSON binary array value
18241 
18242     @complexity Linear in the size of @a init.
18243 
18244     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18245     changes to any JSON value.
18246 
18247     @since version 3.8.0
18248     */
18249     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init)18250     static basic_json binary(const typename binary_t::container_type& init)
18251     {
18252         auto res = basic_json();
18253         res.m_type = value_t::binary;
18254         res.m_value = init;
18255         return res;
18256     }
18257 
18258     /*!
18259     @brief explicitly create a binary array (with subtype)
18260 
18261     Creates a JSON binary array value from a given binary container. Binary
18262     values are part of various binary formats, such as CBOR, MessagePack, and
18263     BSON. This constructor is used to create a value for serialization to those
18264     formats.
18265 
18266     @note Note, this function exists because of the difficulty in correctly
18267     specifying the correct template overload in the standard value ctor, as both
18268     JSON arrays and JSON binary arrays are backed with some form of a
18269     `std::vector`. Because JSON binary arrays are a non-standard extension it
18270     was decided that it would be best to prevent automatic initialization of a
18271     binary array type, for backwards compatibility and so it does not happen on
18272     accident.
18273 
18274     @param[in] init container containing bytes to use as binary type
18275     @param[in] subtype subtype to use in MessagePack and BSON
18276 
18277     @return JSON binary array value
18278 
18279     @complexity Linear in the size of @a init.
18280 
18281     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18282     changes to any JSON value.
18283 
18284     @since version 3.8.0
18285     */
18286     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init,std::uint8_t subtype)18287     static basic_json binary(const typename binary_t::container_type& init, std::uint8_t subtype)
18288     {
18289         auto res = basic_json();
18290         res.m_type = value_t::binary;
18291         res.m_value = binary_t(init, subtype);
18292         return res;
18293     }
18294 
18295     /// @copydoc binary(const typename binary_t::container_type&)
18296     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init)18297     static basic_json binary(typename binary_t::container_type&& init)
18298     {
18299         auto res = basic_json();
18300         res.m_type = value_t::binary;
18301         res.m_value = std::move(init);
18302         return res;
18303     }
18304 
18305     /// @copydoc binary(const typename binary_t::container_type&, std::uint8_t)
18306     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init,std::uint8_t subtype)18307     static basic_json binary(typename binary_t::container_type&& init, std::uint8_t subtype)
18308     {
18309         auto res = basic_json();
18310         res.m_type = value_t::binary;
18311         res.m_value = binary_t(std::move(init), subtype);
18312         return res;
18313     }
18314 
18315     /*!
18316     @brief explicitly create an array from an initializer list
18317 
18318     Creates a JSON array value from a given initializer list. That is, given a
18319     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
18320     initializer list is empty, the empty array `[]` is created.
18321 
18322     @note This function is only needed to express two edge cases that cannot
18323     be realized with the initializer list constructor (@ref
18324     basic_json(initializer_list_t, bool, value_t)). These cases
18325     are:
18326     1. creating an array whose elements are all pairs whose first element is a
18327     string -- in this case, the initializer list constructor would create an
18328     object, taking the first elements as keys
18329     2. creating an empty array -- passing the empty initializer list to the
18330     initializer list constructor yields an empty object
18331 
18332     @param[in] init  initializer list with JSON values to create an array from
18333     (optional)
18334 
18335     @return JSON array value
18336 
18337     @complexity Linear in the size of @a init.
18338 
18339     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18340     changes to any JSON value.
18341 
18342     @liveexample{The following code shows an example for the `array`
18343     function.,array}
18344 
18345     @sa @ref basic_json(initializer_list_t, bool, value_t) --
18346     create a JSON value from an initializer list
18347     @sa @ref object(initializer_list_t) -- create a JSON object
18348     value from an initializer list
18349 
18350     @since version 1.0.0
18351     */
18352     JSON_HEDLEY_WARN_UNUSED_RESULT
array(initializer_list_t init={})18353     static basic_json array(initializer_list_t init = {})
18354     {
18355         return basic_json(init, false, value_t::array);
18356     }
18357 
18358     /*!
18359     @brief explicitly create an object from an initializer list
18360 
18361     Creates a JSON object value from a given initializer list. The initializer
18362     lists elements must be pairs, and their first elements must be strings. If
18363     the initializer list is empty, the empty object `{}` is created.
18364 
18365     @note This function is only added for symmetry reasons. In contrast to the
18366     related function @ref array(initializer_list_t), there are
18367     no cases which can only be expressed by this function. That is, any
18368     initializer list @a init can also be passed to the initializer list
18369     constructor @ref basic_json(initializer_list_t, bool, value_t).
18370 
18371     @param[in] init  initializer list to create an object from (optional)
18372 
18373     @return JSON object value
18374 
18375     @throw type_error.301 if @a init is not a list of pairs whose first
18376     elements are strings. In this case, no object can be created. When such a
18377     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
18378     an array would have been created from the passed initializer list @a init.
18379     See example below.
18380 
18381     @complexity Linear in the size of @a init.
18382 
18383     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18384     changes to any JSON value.
18385 
18386     @liveexample{The following code shows an example for the `object`
18387     function.,object}
18388 
18389     @sa @ref basic_json(initializer_list_t, bool, value_t) --
18390     create a JSON value from an initializer list
18391     @sa @ref array(initializer_list_t) -- create a JSON array
18392     value from an initializer list
18393 
18394     @since version 1.0.0
18395     */
18396     JSON_HEDLEY_WARN_UNUSED_RESULT
object(initializer_list_t init={})18397     static basic_json object(initializer_list_t init = {})
18398     {
18399         return basic_json(init, false, value_t::object);
18400     }
18401 
18402     /*!
18403     @brief construct an array with count copies of given value
18404 
18405     Constructs a JSON array value by creating @a cnt copies of a passed value.
18406     In case @a cnt is `0`, an empty array is created.
18407 
18408     @param[in] cnt  the number of JSON copies of @a val to create
18409     @param[in] val  the JSON value to copy
18410 
18411     @post `std::distance(begin(),end()) == cnt` holds.
18412 
18413     @complexity Linear in @a cnt.
18414 
18415     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18416     changes to any JSON value.
18417 
18418     @liveexample{The following code shows examples for the @ref
18419     basic_json(size_type\, const basic_json&)
18420     constructor.,basic_json__size_type_basic_json}
18421 
18422     @since version 1.0.0
18423     */
basic_json(size_type cnt,const basic_json & val)18424     basic_json(size_type cnt, const basic_json& val)
18425         : m_type(value_t::array)
18426     {
18427         m_value.array = create<array_t>(cnt, val);
18428         assert_invariant();
18429     }
18430 
18431     /*!
18432     @brief construct a JSON container given an iterator range
18433 
18434     Constructs the JSON value with the contents of the range `[first, last)`.
18435     The semantics depends on the different types a JSON value can have:
18436     - In case of a null type, invalid_iterator.206 is thrown.
18437     - In case of other primitive types (number, boolean, or string), @a first
18438       must be `begin()` and @a last must be `end()`. In this case, the value is
18439       copied. Otherwise, invalid_iterator.204 is thrown.
18440     - In case of structured types (array, object), the constructor behaves as
18441       similar versions for `std::vector` or `std::map`; that is, a JSON array
18442       or object is constructed from the values in the range.
18443 
18444     @tparam InputIT an input iterator type (@ref iterator or @ref
18445     const_iterator)
18446 
18447     @param[in] first begin of the range to copy from (included)
18448     @param[in] last end of the range to copy from (excluded)
18449 
18450     @pre Iterators @a first and @a last must be initialized. **This
18451          precondition is enforced with an assertion (see warning).** If
18452          assertions are switched off, a violation of this precondition yields
18453          undefined behavior.
18454 
18455     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
18456          checked efficiently. Only certain edge cases are detected; see the
18457          description of the exceptions below. A violation of this precondition
18458          yields undefined behavior.
18459 
18460     @warning A precondition is enforced with a runtime assertion that will
18461              result in calling `std::abort` if this precondition is not met.
18462              Assertions can be disabled by defining `NDEBUG` at compile time.
18463              See https://en.cppreference.com/w/cpp/error/assert for more
18464              information.
18465 
18466     @throw invalid_iterator.201 if iterators @a first and @a last are not
18467     compatible (i.e., do not belong to the same JSON value). In this case,
18468     the range `[first, last)` is undefined.
18469     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
18470     primitive type (number, boolean, or string), but @a first does not point
18471     to the first element any more. In this case, the range `[first, last)` is
18472     undefined. See example code below.
18473     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
18474     null value. In this case, the range `[first, last)` is undefined.
18475 
18476     @complexity Linear in distance between @a first and @a last.
18477 
18478     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18479     changes to any JSON value.
18480 
18481     @liveexample{The example below shows several ways to create JSON values by
18482     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
18483 
18484     @since version 1.0.0
18485     */
18486     template < class InputIT, typename std::enable_if <
18487                    std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18488                    std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
basic_json(InputIT first,InputIT last)18489     basic_json(InputIT first, InputIT last)
18490     {
18491         JSON_ASSERT(first.m_object != nullptr);
18492         JSON_ASSERT(last.m_object != nullptr);
18493 
18494         // make sure iterator fits the current value
18495         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18496         {
18497             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
18498         }
18499 
18500         // copy type from first iterator
18501         m_type = first.m_object->m_type;
18502 
18503         // check if iterator range is complete for primitive values
18504         switch (m_type)
18505         {
18506             case value_t::boolean:
18507             case value_t::number_float:
18508             case value_t::number_integer:
18509             case value_t::number_unsigned:
18510             case value_t::string:
18511             {
18512                 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18513                                          || !last.m_it.primitive_iterator.is_end()))
18514                 {
18515                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
18516                 }
18517                 break;
18518             }
18519 
18520             default:
18521                 break;
18522         }
18523 
18524         switch (m_type)
18525         {
18526             case value_t::number_integer:
18527             {
18528                 m_value.number_integer = first.m_object->m_value.number_integer;
18529                 break;
18530             }
18531 
18532             case value_t::number_unsigned:
18533             {
18534                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18535                 break;
18536             }
18537 
18538             case value_t::number_float:
18539             {
18540                 m_value.number_float = first.m_object->m_value.number_float;
18541                 break;
18542             }
18543 
18544             case value_t::boolean:
18545             {
18546                 m_value.boolean = first.m_object->m_value.boolean;
18547                 break;
18548             }
18549 
18550             case value_t::string:
18551             {
18552                 m_value = *first.m_object->m_value.string;
18553                 break;
18554             }
18555 
18556             case value_t::object:
18557             {
18558                 m_value.object = create<object_t>(first.m_it.object_iterator,
18559                                                   last.m_it.object_iterator);
18560                 break;
18561             }
18562 
18563             case value_t::array:
18564             {
18565                 m_value.array = create<array_t>(first.m_it.array_iterator,
18566                                                 last.m_it.array_iterator);
18567                 break;
18568             }
18569 
18570             case value_t::binary:
18571             {
18572                 m_value = *first.m_object->m_value.binary;
18573                 break;
18574             }
18575 
18576             default:
18577                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
18578                                                     std::string(first.m_object->type_name())));
18579         }
18580 
18581         assert_invariant();
18582     }
18583 
18584 
18585     ///////////////////////////////////////
18586     // other constructors and destructor //
18587     ///////////////////////////////////////
18588 
18589     template<typename JsonRef,
18590              detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
18591                                  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef & ref)18592     basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18593 
18594     /*!
18595     @brief copy constructor
18596 
18597     Creates a copy of a given JSON value.
18598 
18599     @param[in] other  the JSON value to copy
18600 
18601     @post `*this == other`
18602 
18603     @complexity Linear in the size of @a other.
18604 
18605     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18606     changes to any JSON value.
18607 
18608     @requirement This function helps `basic_json` satisfying the
18609     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18610     requirements:
18611     - The complexity is linear.
18612     - As postcondition, it holds: `other == basic_json(other)`.
18613 
18614     @liveexample{The following code shows an example for the copy
18615     constructor.,basic_json__basic_json}
18616 
18617     @since version 1.0.0
18618     */
basic_json(const basic_json & other)18619     basic_json(const basic_json& other)
18620         : m_type(other.m_type)
18621     {
18622         // check of passed value is valid
18623         other.assert_invariant();
18624 
18625         switch (m_type)
18626         {
18627             case value_t::object:
18628             {
18629                 m_value = *other.m_value.object;
18630                 break;
18631             }
18632 
18633             case value_t::array:
18634             {
18635                 m_value = *other.m_value.array;
18636                 break;
18637             }
18638 
18639             case value_t::string:
18640             {
18641                 m_value = *other.m_value.string;
18642                 break;
18643             }
18644 
18645             case value_t::boolean:
18646             {
18647                 m_value = other.m_value.boolean;
18648                 break;
18649             }
18650 
18651             case value_t::number_integer:
18652             {
18653                 m_value = other.m_value.number_integer;
18654                 break;
18655             }
18656 
18657             case value_t::number_unsigned:
18658             {
18659                 m_value = other.m_value.number_unsigned;
18660                 break;
18661             }
18662 
18663             case value_t::number_float:
18664             {
18665                 m_value = other.m_value.number_float;
18666                 break;
18667             }
18668 
18669             case value_t::binary:
18670             {
18671                 m_value = *other.m_value.binary;
18672                 break;
18673             }
18674 
18675             default:
18676                 break;
18677         }
18678 
18679         assert_invariant();
18680     }
18681 
18682     /*!
18683     @brief move constructor
18684 
18685     Move constructor. Constructs a JSON value with the contents of the given
18686     value @a other using move semantics. It "steals" the resources from @a
18687     other and leaves it as JSON null value.
18688 
18689     @param[in,out] other  value to move to this object
18690 
18691     @post `*this` has the same value as @a other before the call.
18692     @post @a other is a JSON null value.
18693 
18694     @complexity Constant.
18695 
18696     @exceptionsafety No-throw guarantee: this constructor never throws
18697     exceptions.
18698 
18699     @requirement This function helps `basic_json` satisfying the
18700     [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
18701     requirements.
18702 
18703     @liveexample{The code below shows the move constructor explicitly called
18704     via std::move.,basic_json__moveconstructor}
18705 
18706     @since version 1.0.0
18707     */
basic_json(basic_json && other)18708     basic_json(basic_json&& other) noexcept
18709         : m_type(std::move(other.m_type)),
18710           m_value(std::move(other.m_value))
18711     {
18712         // check that passed value is valid
18713         other.assert_invariant();
18714 
18715         // invalidate payload
18716         other.m_type = value_t::null;
18717         other.m_value = {};
18718 
18719         assert_invariant();
18720     }
18721 
18722     /*!
18723     @brief copy assignment
18724 
18725     Copy assignment operator. Copies a JSON value via the "copy and swap"
18726     strategy: It is expressed in terms of the copy constructor, destructor,
18727     and the `swap()` member function.
18728 
18729     @param[in] other  value to copy from
18730 
18731     @complexity Linear.
18732 
18733     @requirement This function helps `basic_json` satisfying the
18734     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18735     requirements:
18736     - The complexity is linear.
18737 
18738     @liveexample{The code below shows and example for the copy assignment. It
18739     creates a copy of value `a` which is then swapped with `b`. Finally\, the
18740     copy of `a` (which is the null value after the swap) is
18741     destroyed.,basic_json__copyassignment}
18742 
18743     @since version 1.0.0
18744     */
operator =(basic_json other)18745     basic_json& operator=(basic_json other) noexcept (
18746         std::is_nothrow_move_constructible<value_t>::value&&
18747         std::is_nothrow_move_assignable<value_t>::value&&
18748         std::is_nothrow_move_constructible<json_value>::value&&
18749         std::is_nothrow_move_assignable<json_value>::value
18750     )
18751     {
18752         // check that passed value is valid
18753         other.assert_invariant();
18754 
18755         using std::swap;
18756         swap(m_type, other.m_type);
18757         swap(m_value, other.m_value);
18758 
18759         assert_invariant();
18760         return *this;
18761     }
18762 
18763     /*!
18764     @brief destructor
18765 
18766     Destroys the JSON value and frees all allocated memory.
18767 
18768     @complexity Linear.
18769 
18770     @requirement This function helps `basic_json` satisfying the
18771     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
18772     requirements:
18773     - The complexity is linear.
18774     - All stored elements are destroyed and all memory is freed.
18775 
18776     @since version 1.0.0
18777     */
~basic_json()18778     ~basic_json() noexcept
18779     {
18780         assert_invariant();
18781         m_value.destroy(m_type);
18782     }
18783 
18784     /// @}
18785 
18786   public:
18787     ///////////////////////
18788     // object inspection //
18789     ///////////////////////
18790 
18791     /// @name object inspection
18792     /// Functions to inspect the type of a JSON value.
18793     /// @{
18794 
18795     /*!
18796     @brief serialization
18797 
18798     Serialization function for JSON values. The function tries to mimic
18799     Python's `json.dumps()` function, and currently supports its @a indent
18800     and @a ensure_ascii parameters.
18801 
18802     @param[in] indent If indent is nonnegative, then array elements and object
18803     members will be pretty-printed with that indent level. An indent level of
18804     `0` will only insert newlines. `-1` (the default) selects the most compact
18805     representation.
18806     @param[in] indent_char The character to use for indentation if @a indent is
18807     greater than `0`. The default is ` ` (space).
18808     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
18809     in the output are escaped with `\uXXXX` sequences, and the result consists
18810     of ASCII characters only.
18811     @param[in] error_handler  how to react on decoding errors; there are three
18812     possible values: `strict` (throws and exception in case a decoding error
18813     occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
18814     and `ignore` (ignore invalid UTF-8 sequences during serialization; all
18815     bytes are copied to the output unchanged).
18816 
18817     @return string containing the serialization of the JSON value
18818 
18819     @throw type_error.316 if a string stored inside the JSON value is not
18820                           UTF-8 encoded and @a error_handler is set to strict
18821 
18822     @note Binary values are serialized as object containing two keys:
18823       - "bytes": an array of bytes as integers
18824       - "subtype": the subtype as integer or "null" if the binary has no subtype
18825 
18826     @complexity Linear.
18827 
18828     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18829     changes in the JSON value.
18830 
18831     @liveexample{The following example shows the effect of different @a indent\,
18832     @a indent_char\, and @a ensure_ascii parameters to the result of the
18833     serialization.,dump}
18834 
18835     @see https://docs.python.org/2/library/json.html#json.dump
18836 
18837     @since version 1.0.0; indentation character @a indent_char, option
18838            @a ensure_ascii and exceptions added in version 3.0.0; error
18839            handlers added in version 3.4.0; serialization of binary values added
18840            in version 3.8.0.
18841     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const18842     string_t dump(const int indent = -1,
18843                   const char indent_char = ' ',
18844                   const bool ensure_ascii = false,
18845                   const error_handler_t error_handler = error_handler_t::strict) const
18846     {
18847         string_t result;
18848         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18849 
18850         if (indent >= 0)
18851         {
18852             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18853         }
18854         else
18855         {
18856             s.dump(*this, false, ensure_ascii, 0);
18857         }
18858 
18859         return result;
18860     }
18861 
18862     /*!
18863     @brief return the type of the JSON value (explicit)
18864 
18865     Return the type of the JSON value as a value from the @ref value_t
18866     enumeration.
18867 
18868     @return the type of the JSON value
18869             Value type                | return value
18870             ------------------------- | -------------------------
18871             null                      | value_t::null
18872             boolean                   | value_t::boolean
18873             string                    | value_t::string
18874             number (integer)          | value_t::number_integer
18875             number (unsigned integer) | value_t::number_unsigned
18876             number (floating-point)   | value_t::number_float
18877             object                    | value_t::object
18878             array                     | value_t::array
18879             binary                    | value_t::binary
18880             discarded                 | value_t::discarded
18881 
18882     @complexity Constant.
18883 
18884     @exceptionsafety No-throw guarantee: this member function never throws
18885     exceptions.
18886 
18887     @liveexample{The following code exemplifies `type()` for all JSON
18888     types.,type}
18889 
18890     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
18891     @sa @ref type_name() -- return the type as string
18892 
18893     @since version 1.0.0
18894     */
type() const18895     constexpr value_t type() const noexcept
18896     {
18897         return m_type;
18898     }
18899 
18900     /*!
18901     @brief return whether type is primitive
18902 
18903     This function returns true if and only if the JSON type is primitive
18904     (string, number, boolean, or null).
18905 
18906     @return `true` if type is primitive (string, number, boolean, or null),
18907     `false` otherwise.
18908 
18909     @complexity Constant.
18910 
18911     @exceptionsafety No-throw guarantee: this member function never throws
18912     exceptions.
18913 
18914     @liveexample{The following code exemplifies `is_primitive()` for all JSON
18915     types.,is_primitive}
18916 
18917     @sa @ref is_structured() -- returns whether JSON value is structured
18918     @sa @ref is_null() -- returns whether JSON value is `null`
18919     @sa @ref is_string() -- returns whether JSON value is a string
18920     @sa @ref is_boolean() -- returns whether JSON value is a boolean
18921     @sa @ref is_number() -- returns whether JSON value is a number
18922     @sa @ref is_binary() -- returns whether JSON value is a binary array
18923 
18924     @since version 1.0.0
18925     */
is_primitive() const18926     constexpr bool is_primitive() const noexcept
18927     {
18928         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18929     }
18930 
18931     /*!
18932     @brief return whether type is structured
18933 
18934     This function returns true if and only if the JSON type is structured
18935     (array or object).
18936 
18937     @return `true` if type is structured (array or object), `false` otherwise.
18938 
18939     @complexity Constant.
18940 
18941     @exceptionsafety No-throw guarantee: this member function never throws
18942     exceptions.
18943 
18944     @liveexample{The following code exemplifies `is_structured()` for all JSON
18945     types.,is_structured}
18946 
18947     @sa @ref is_primitive() -- returns whether value is primitive
18948     @sa @ref is_array() -- returns whether value is an array
18949     @sa @ref is_object() -- returns whether value is an object
18950 
18951     @since version 1.0.0
18952     */
is_structured() const18953     constexpr bool is_structured() const noexcept
18954     {
18955         return is_array() || is_object();
18956     }
18957 
18958     /*!
18959     @brief return whether value is null
18960 
18961     This function returns true if and only if the JSON value is null.
18962 
18963     @return `true` if type is null, `false` otherwise.
18964 
18965     @complexity Constant.
18966 
18967     @exceptionsafety No-throw guarantee: this member function never throws
18968     exceptions.
18969 
18970     @liveexample{The following code exemplifies `is_null()` for all JSON
18971     types.,is_null}
18972 
18973     @since version 1.0.0
18974     */
is_null() const18975     constexpr bool is_null() const noexcept
18976     {
18977         return m_type == value_t::null;
18978     }
18979 
18980     /*!
18981     @brief return whether value is a boolean
18982 
18983     This function returns true if and only if the JSON value is a boolean.
18984 
18985     @return `true` if type is boolean, `false` otherwise.
18986 
18987     @complexity Constant.
18988 
18989     @exceptionsafety No-throw guarantee: this member function never throws
18990     exceptions.
18991 
18992     @liveexample{The following code exemplifies `is_boolean()` for all JSON
18993     types.,is_boolean}
18994 
18995     @since version 1.0.0
18996     */
is_boolean() const18997     constexpr bool is_boolean() const noexcept
18998     {
18999         return m_type == value_t::boolean;
19000     }
19001 
19002     /*!
19003     @brief return whether value is a number
19004 
19005     This function returns true if and only if the JSON value is a number. This
19006     includes both integer (signed and unsigned) and floating-point values.
19007 
19008     @return `true` if type is number (regardless whether integer, unsigned
19009     integer or floating-type), `false` otherwise.
19010 
19011     @complexity Constant.
19012 
19013     @exceptionsafety No-throw guarantee: this member function never throws
19014     exceptions.
19015 
19016     @liveexample{The following code exemplifies `is_number()` for all JSON
19017     types.,is_number}
19018 
19019     @sa @ref is_number_integer() -- check if value is an integer or unsigned
19020     integer number
19021     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19022     number
19023     @sa @ref is_number_float() -- check if value is a floating-point number
19024 
19025     @since version 1.0.0
19026     */
is_number() const19027     constexpr bool is_number() const noexcept
19028     {
19029         return is_number_integer() || is_number_float();
19030     }
19031 
19032     /*!
19033     @brief return whether value is an integer number
19034 
19035     This function returns true if and only if the JSON value is a signed or
19036     unsigned integer number. This excludes floating-point values.
19037 
19038     @return `true` if type is an integer or unsigned integer number, `false`
19039     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_number_integer()` for all
19047     JSON types.,is_number_integer}
19048 
19049     @sa @ref is_number() -- check if value is a number
19050     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19051     number
19052     @sa @ref is_number_float() -- check if value is a floating-point number
19053 
19054     @since version 1.0.0
19055     */
is_number_integer() const19056     constexpr bool is_number_integer() const noexcept
19057     {
19058         return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19059     }
19060 
19061     /*!
19062     @brief return whether value is an unsigned integer number
19063 
19064     This function returns true if and only if the JSON value is an unsigned
19065     integer number. This excludes floating-point and signed integer values.
19066 
19067     @return `true` if type is an unsigned integer number, `false` otherwise.
19068 
19069     @complexity Constant.
19070 
19071     @exceptionsafety No-throw guarantee: this member function never throws
19072     exceptions.
19073 
19074     @liveexample{The following code exemplifies `is_number_unsigned()` for all
19075     JSON types.,is_number_unsigned}
19076 
19077     @sa @ref is_number() -- check if value is a number
19078     @sa @ref is_number_integer() -- check if value is an integer or unsigned
19079     integer number
19080     @sa @ref is_number_float() -- check if value is a floating-point number
19081 
19082     @since version 2.0.0
19083     */
is_number_unsigned() const19084     constexpr bool is_number_unsigned() const noexcept
19085     {
19086         return m_type == value_t::number_unsigned;
19087     }
19088 
19089     /*!
19090     @brief return whether value is a floating-point number
19091 
19092     This function returns true if and only if the JSON value is a
19093     floating-point number. This excludes signed and unsigned integer values.
19094 
19095     @return `true` if type is a floating-point number, `false` otherwise.
19096 
19097     @complexity Constant.
19098 
19099     @exceptionsafety No-throw guarantee: this member function never throws
19100     exceptions.
19101 
19102     @liveexample{The following code exemplifies `is_number_float()` for all
19103     JSON types.,is_number_float}
19104 
19105     @sa @ref is_number() -- check if value is number
19106     @sa @ref is_number_integer() -- check if value is an integer number
19107     @sa @ref is_number_unsigned() -- check if value is an unsigned integer
19108     number
19109 
19110     @since version 1.0.0
19111     */
is_number_float() const19112     constexpr bool is_number_float() const noexcept
19113     {
19114         return m_type == value_t::number_float;
19115     }
19116 
19117     /*!
19118     @brief return whether value is an object
19119 
19120     This function returns true if and only if the JSON value is an object.
19121 
19122     @return `true` if type is object, `false` otherwise.
19123 
19124     @complexity Constant.
19125 
19126     @exceptionsafety No-throw guarantee: this member function never throws
19127     exceptions.
19128 
19129     @liveexample{The following code exemplifies `is_object()` for all JSON
19130     types.,is_object}
19131 
19132     @since version 1.0.0
19133     */
is_object() const19134     constexpr bool is_object() const noexcept
19135     {
19136         return m_type == value_t::object;
19137     }
19138 
19139     /*!
19140     @brief return whether value is an array
19141 
19142     This function returns true if and only if the JSON value is an array.
19143 
19144     @return `true` if type is array, `false` otherwise.
19145 
19146     @complexity Constant.
19147 
19148     @exceptionsafety No-throw guarantee: this member function never throws
19149     exceptions.
19150 
19151     @liveexample{The following code exemplifies `is_array()` for all JSON
19152     types.,is_array}
19153 
19154     @since version 1.0.0
19155     */
is_array() const19156     constexpr bool is_array() const noexcept
19157     {
19158         return m_type == value_t::array;
19159     }
19160 
19161     /*!
19162     @brief return whether value is a string
19163 
19164     This function returns true if and only if the JSON value is a string.
19165 
19166     @return `true` if type is string, `false` otherwise.
19167 
19168     @complexity Constant.
19169 
19170     @exceptionsafety No-throw guarantee: this member function never throws
19171     exceptions.
19172 
19173     @liveexample{The following code exemplifies `is_string()` for all JSON
19174     types.,is_string}
19175 
19176     @since version 1.0.0
19177     */
is_string() const19178     constexpr bool is_string() const noexcept
19179     {
19180         return m_type == value_t::string;
19181     }
19182 
19183     /*!
19184     @brief return whether value is a binary array
19185 
19186     This function returns true if and only if the JSON value is a binary array.
19187 
19188     @return `true` if type is binary array, `false` otherwise.
19189 
19190     @complexity Constant.
19191 
19192     @exceptionsafety No-throw guarantee: this member function never throws
19193     exceptions.
19194 
19195     @liveexample{The following code exemplifies `is_binary()` for all JSON
19196     types.,is_binary}
19197 
19198     @since version 3.8.0
19199     */
is_binary() const19200     constexpr bool is_binary() const noexcept
19201     {
19202         return m_type == value_t::binary;
19203     }
19204 
19205     /*!
19206     @brief return whether value is discarded
19207 
19208     This function returns true if and only if the JSON value was discarded
19209     during parsing with a callback function (see @ref parser_callback_t).
19210 
19211     @note This function will always be `false` for JSON values after parsing.
19212     That is, discarded values can only occur during parsing, but will be
19213     removed when inside a structured value or replaced by null in other cases.
19214 
19215     @return `true` if type is discarded, `false` otherwise.
19216 
19217     @complexity Constant.
19218 
19219     @exceptionsafety No-throw guarantee: this member function never throws
19220     exceptions.
19221 
19222     @liveexample{The following code exemplifies `is_discarded()` for all JSON
19223     types.,is_discarded}
19224 
19225     @since version 1.0.0
19226     */
is_discarded() const19227     constexpr bool is_discarded() const noexcept
19228     {
19229         return m_type == value_t::discarded;
19230     }
19231 
19232     /*!
19233     @brief return the type of the JSON value (implicit)
19234 
19235     Implicitly return the type of the JSON value as a value from the @ref
19236     value_t enumeration.
19237 
19238     @return the type of the JSON value
19239 
19240     @complexity Constant.
19241 
19242     @exceptionsafety No-throw guarantee: this member function never throws
19243     exceptions.
19244 
19245     @liveexample{The following code exemplifies the @ref value_t operator for
19246     all JSON types.,operator__value_t}
19247 
19248     @sa @ref type() -- return the type of the JSON value (explicit)
19249     @sa @ref type_name() -- return the type as string
19250 
19251     @since version 1.0.0
19252     */
operator value_t() const19253     constexpr operator value_t() const noexcept
19254     {
19255         return m_type;
19256     }
19257 
19258     /// @}
19259 
19260   private:
19261     //////////////////
19262     // value access //
19263     //////////////////
19264 
19265     /// get a boolean (explicit)
get_impl(boolean_t *) const19266     boolean_t get_impl(boolean_t* /*unused*/) const
19267     {
19268         if (JSON_HEDLEY_LIKELY(is_boolean()))
19269         {
19270             return m_value.boolean;
19271         }
19272 
19273         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
19274     }
19275 
19276     /// get a pointer to the value (object)
get_impl_ptr(object_t *)19277     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19278     {
19279         return is_object() ? m_value.object : nullptr;
19280     }
19281 
19282     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const19283     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19284     {
19285         return is_object() ? m_value.object : nullptr;
19286     }
19287 
19288     /// get a pointer to the value (array)
get_impl_ptr(array_t *)19289     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19290     {
19291         return is_array() ? m_value.array : nullptr;
19292     }
19293 
19294     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const19295     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19296     {
19297         return is_array() ? m_value.array : nullptr;
19298     }
19299 
19300     /// get a pointer to the value (string)
get_impl_ptr(string_t *)19301     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19302     {
19303         return is_string() ? m_value.string : nullptr;
19304     }
19305 
19306     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const19307     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19308     {
19309         return is_string() ? m_value.string : nullptr;
19310     }
19311 
19312     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)19313     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19314     {
19315         return is_boolean() ? &m_value.boolean : nullptr;
19316     }
19317 
19318     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const19319     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19320     {
19321         return is_boolean() ? &m_value.boolean : nullptr;
19322     }
19323 
19324     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)19325     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
19326     {
19327         return is_number_integer() ? &m_value.number_integer : nullptr;
19328     }
19329 
19330     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const19331     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
19332     {
19333         return is_number_integer() ? &m_value.number_integer : nullptr;
19334     }
19335 
19336     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)19337     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
19338     {
19339         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19340     }
19341 
19342     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const19343     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
19344     {
19345         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
19346     }
19347 
19348     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)19349     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
19350     {
19351         return is_number_float() ? &m_value.number_float : nullptr;
19352     }
19353 
19354     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const19355     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
19356     {
19357         return is_number_float() ? &m_value.number_float : nullptr;
19358     }
19359 
19360     /// get a pointer to the value (binary)
get_impl_ptr(binary_t *)19361     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
19362     {
19363         return is_binary() ? m_value.binary : nullptr;
19364     }
19365 
19366     /// get a pointer to the value (binary)
get_impl_ptr(const binary_t *) const19367     constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
19368     {
19369         return is_binary() ? m_value.binary : nullptr;
19370     }
19371 
19372     /*!
19373     @brief helper function to implement get_ref()
19374 
19375     This function helps to implement get_ref() without code duplication for
19376     const and non-const overloads
19377 
19378     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
19379 
19380     @throw type_error.303 if ReferenceType does not match underlying value
19381     type of the current JSON
19382     */
19383     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)19384     static ReferenceType get_ref_impl(ThisType& obj)
19385     {
19386         // delegate the call to get_ptr<>()
19387         auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
19388 
19389         if (JSON_HEDLEY_LIKELY(ptr != nullptr))
19390         {
19391             return *ptr;
19392         }
19393 
19394         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
19395     }
19396 
19397   public:
19398     /// @name value access
19399     /// Direct access to the stored value of a JSON value.
19400     /// @{
19401 
19402     /*!
19403     @brief get special-case overload
19404 
19405     This overloads avoids a lot of template boilerplate, it can be seen as the
19406     identity method
19407 
19408     @tparam BasicJsonType == @ref basic_json
19409 
19410     @return a copy of *this
19411 
19412     @complexity Constant.
19413 
19414     @since version 2.1.0
19415     */
19416     template<typename BasicJsonType, detail::enable_if_t<
19417                  std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
19418                  int> = 0>
get() const19419     basic_json get() const
19420     {
19421         return *this;
19422     }
19423 
19424     /*!
19425     @brief get special-case overload
19426 
19427     This overloads converts the current @ref basic_json in a different
19428     @ref basic_json type
19429 
19430     @tparam BasicJsonType == @ref basic_json
19431 
19432     @return a copy of *this, converted into @tparam BasicJsonType
19433 
19434     @complexity Depending on the implementation of the called `from_json()`
19435                 method.
19436 
19437     @since version 3.2.0
19438     */
19439     template < typename BasicJsonType, detail::enable_if_t <
19440                    !std::is_same<BasicJsonType, basic_json>::value&&
19441                    detail::is_basic_json<BasicJsonType>::value, int > = 0 >
19442     BasicJsonType get() const
19443     {
19444         return *this;
19445     }
19446 
19447     /*!
19448     @brief get a value (explicit)
19449 
19450     Explicit type conversion between the JSON value and a compatible value
19451     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19452     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19453     The value is converted by calling the @ref json_serializer<ValueType>
19454     `from_json()` method.
19455 
19456     The function is equivalent to executing
19457     @code {.cpp}
19458     ValueType ret;
19459     JSONSerializer<ValueType>::from_json(*this, ret);
19460     return ret;
19461     @endcode
19462 
19463     This overloads is chosen if:
19464     - @a ValueType is not @ref basic_json,
19465     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19466       `void from_json(const basic_json&, ValueType&)`, and
19467     - @ref json_serializer<ValueType> does not have a `from_json()` method of
19468       the form `ValueType from_json(const basic_json&)`
19469 
19470     @tparam ValueTypeCV the provided value type
19471     @tparam ValueType the returned value type
19472 
19473     @return copy of the JSON value, converted to @a ValueType
19474 
19475     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19476 
19477     @liveexample{The example below shows several conversions from JSON values
19478     to other types. There a few things to note: (1) Floating-point numbers can
19479     be converted to integers\, (2) A JSON array can be converted to a standard
19480     `std::vector<short>`\, (3) A JSON object can be converted to C++
19481     associative containers such as `std::unordered_map<std::string\,
19482     json>`.,get__ValueType_const}
19483 
19484     @since version 2.1.0
19485     */
19486     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19487                detail::enable_if_t <
19488                    !detail::is_basic_json<ValueType>::value &&
19489                    detail::has_from_json<basic_json_t, ValueType>::value &&
19490                    !detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19491                    int > = 0 >
19492     ValueType get() const noexcept(noexcept(
19493                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
19494     {
19495         // we cannot static_assert on ValueTypeCV being non-const, because
19496         // there is support for get<const basic_json_t>(), which is why we
19497         // still need the uncvref
19498         static_assert(!std::is_reference<ValueTypeCV>::value,
19499                       "get() cannot be used with reference types, you might want to use get_ref()");
19500         static_assert(std::is_default_constructible<ValueType>::value,
19501                       "types must be DefaultConstructible when used with get()");
19502 
19503         ValueType ret;
19504         JSONSerializer<ValueType>::from_json(*this, ret);
19505         return ret;
19506     }
19507 
19508     /*!
19509     @brief get a value (explicit); special case
19510 
19511     Explicit type conversion between the JSON value and a compatible value
19512     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
19513     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
19514     The value is converted by calling the @ref json_serializer<ValueType>
19515     `from_json()` method.
19516 
19517     The function is equivalent to executing
19518     @code {.cpp}
19519     return JSONSerializer<ValueTypeCV>::from_json(*this);
19520     @endcode
19521 
19522     This overloads is chosen if:
19523     - @a ValueType is not @ref basic_json and
19524     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19525       `ValueType from_json(const basic_json&)`
19526 
19527     @note If @ref json_serializer<ValueType> has both overloads of
19528     `from_json()`, this one is chosen.
19529 
19530     @tparam ValueTypeCV the provided value type
19531     @tparam ValueType the returned value type
19532 
19533     @return copy of the JSON value, converted to @a ValueType
19534 
19535     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19536 
19537     @since version 2.1.0
19538     */
19539     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
19540                detail::enable_if_t < !std::is_same<basic_json_t, ValueType>::value &&
19541                                      detail::has_non_default_from_json<basic_json_t, ValueType>::value,
19542                                      int > = 0 >
19543     ValueType get() const noexcept(noexcept(
19544                                        JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
19545     {
19546         static_assert(!std::is_reference<ValueTypeCV>::value,
19547                       "get() cannot be used with reference types, you might want to use get_ref()");
19548         return JSONSerializer<ValueType>::from_json(*this);
19549     }
19550 
19551     /*!
19552     @brief get a value (explicit)
19553 
19554     Explicit type conversion between the JSON value and a compatible value.
19555     The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
19556     `from_json()` method.
19557 
19558     The function is equivalent to executing
19559     @code {.cpp}
19560     ValueType v;
19561     JSONSerializer<ValueType>::from_json(*this, v);
19562     @endcode
19563 
19564     This overloads is chosen if:
19565     - @a ValueType is not @ref basic_json,
19566     - @ref json_serializer<ValueType> has a `from_json()` method of the form
19567       `void from_json(const basic_json&, ValueType&)`, and
19568 
19569     @tparam ValueType the input parameter type.
19570 
19571     @return the input parameter, allowing chaining calls.
19572 
19573     @throw what @ref json_serializer<ValueType> `from_json()` method throws
19574 
19575     @liveexample{The example below shows several conversions from JSON values
19576     to other types. There a few things to note: (1) Floating-point numbers can
19577     be converted to integers\, (2) A JSON array can be converted to a standard
19578     `std::vector<short>`\, (3) A JSON object can be converted to C++
19579     associative containers such as `std::unordered_map<std::string\,
19580     json>`.,get_to}
19581 
19582     @since version 3.3.0
19583     */
19584     template < typename ValueType,
19585                detail::enable_if_t <
19586                    !detail::is_basic_json<ValueType>::value&&
19587                    detail::has_from_json<basic_json_t, ValueType>::value,
19588                    int > = 0 >
19589     ValueType & get_to(ValueType& v) const noexcept(noexcept(
19590                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
19591     {
19592         JSONSerializer<ValueType>::from_json(*this, v);
19593         return v;
19594     }
19595 
19596     // specialization to allow to call get_to with a basic_json value
19597     // see https://github.com/nlohmann/json/issues/2175
19598     template<typename ValueType,
19599              detail::enable_if_t <
19600                  detail::is_basic_json<ValueType>::value,
19601                  int> = 0>
19602     ValueType & get_to(ValueType& v) const
19603     {
19604         v = *this;
19605         return v;
19606     }
19607 
19608     template <
19609         typename T, std::size_t N,
19610         typename Array = T (&)[N],
19611         detail::enable_if_t <
19612             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
19613     Array get_to(T (&v)[N]) const
19614     noexcept(noexcept(JSONSerializer<Array>::from_json(
19615                           std::declval<const basic_json_t&>(), v)))
19616     {
19617         JSONSerializer<Array>::from_json(*this, v);
19618         return v;
19619     }
19620 
19621 
19622     /*!
19623     @brief get a pointer value (implicit)
19624 
19625     Implicit pointer access to the internally stored JSON value. No copies are
19626     made.
19627 
19628     @warning Writing data to the pointee of the result yields an undefined
19629     state.
19630 
19631     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19632     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19633     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
19634     assertion.
19635 
19636     @return pointer to the internally stored JSON value if the requested
19637     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19638 
19639     @complexity Constant.
19640 
19641     @liveexample{The example below shows how pointers to internal values of a
19642     JSON value can be requested. Note that no type conversions are made and a
19643     `nullptr` is returned if the value and the requested pointer type does not
19644     match.,get_ptr}
19645 
19646     @since version 1.0.0
19647     */
19648     template<typename PointerType, typename std::enable_if<
19649                  std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()19650     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19651     {
19652         // delegate the call to get_impl_ptr<>()
19653         return get_impl_ptr(static_cast<PointerType>(nullptr));
19654     }
19655 
19656     /*!
19657     @brief get a pointer value (implicit)
19658     @copydoc get_ptr()
19659     */
19660     template < typename PointerType, typename std::enable_if <
19661                    std::is_pointer<PointerType>::value&&
19662                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
get_ptr() const19663     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
19664     {
19665         // delegate the call to get_impl_ptr<>() const
19666         return get_impl_ptr(static_cast<PointerType>(nullptr));
19667     }
19668 
19669     /*!
19670     @brief get a pointer value (explicit)
19671 
19672     Explicit pointer access to the internally stored JSON value. No copies are
19673     made.
19674 
19675     @warning The pointer becomes invalid if the underlying JSON object
19676     changes.
19677 
19678     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
19679     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
19680     @ref number_unsigned_t, or @ref number_float_t.
19681 
19682     @return pointer to the internally stored JSON value if the requested
19683     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
19684 
19685     @complexity Constant.
19686 
19687     @liveexample{The example below shows how pointers to internal values of a
19688     JSON value can be requested. Note that no type conversions are made and a
19689     `nullptr` is returned if the value and the requested pointer type does not
19690     match.,get__PointerType}
19691 
19692     @sa @ref get_ptr() for explicit pointer-member access
19693 
19694     @since version 1.0.0
19695     */
19696     template<typename PointerType, typename std::enable_if<
19697                  std::is_pointer<PointerType>::value, int>::type = 0>
get()19698     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
19699     {
19700         // delegate the call to get_ptr
19701         return get_ptr<PointerType>();
19702     }
19703 
19704     /*!
19705     @brief get a pointer value (explicit)
19706     @copydoc get()
19707     */
19708     template<typename PointerType, typename std::enable_if<
19709                  std::is_pointer<PointerType>::value, int>::type = 0>
get() const19710     constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
19711     {
19712         // delegate the call to get_ptr
19713         return get_ptr<PointerType>();
19714     }
19715 
19716     /*!
19717     @brief get a reference value (implicit)
19718 
19719     Implicit reference access to the internally stored JSON value. No copies
19720     are made.
19721 
19722     @warning Writing data to the referee of the result yields an undefined
19723     state.
19724 
19725     @tparam ReferenceType reference type; must be a reference to @ref array_t,
19726     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
19727     @ref number_float_t. Enforced by static assertion.
19728 
19729     @return reference to the internally stored JSON value if the requested
19730     reference type @a ReferenceType fits to the JSON value; throws
19731     type_error.303 otherwise
19732 
19733     @throw type_error.303 in case passed type @a ReferenceType is incompatible
19734     with the stored JSON value; see example below
19735 
19736     @complexity Constant.
19737 
19738     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
19739 
19740     @since version 1.1.0
19741     */
19742     template<typename ReferenceType, typename std::enable_if<
19743                  std::is_reference<ReferenceType>::value, int>::type = 0>
19744     ReferenceType get_ref()
19745     {
19746         // delegate call to get_ref_impl
19747         return get_ref_impl<ReferenceType>(*this);
19748     }
19749 
19750     /*!
19751     @brief get a reference value (implicit)
19752     @copydoc get_ref()
19753     */
19754     template < typename ReferenceType, typename std::enable_if <
19755                    std::is_reference<ReferenceType>::value&&
19756                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
19757     ReferenceType get_ref() const
19758     {
19759         // delegate call to get_ref_impl
19760         return get_ref_impl<ReferenceType>(*this);
19761     }
19762 
19763     /*!
19764     @brief get a value (implicit)
19765 
19766     Implicit type conversion between the JSON value and a compatible value.
19767     The call is realized by calling @ref get() const.
19768 
19769     @tparam ValueType non-pointer type compatible to the JSON value, for
19770     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
19771     `std::vector` types for JSON arrays. The character type of @ref string_t
19772     as well as an initializer list of this type is excluded to avoid
19773     ambiguities as these types implicitly convert to `std::string`.
19774 
19775     @return copy of the JSON value, converted to type @a ValueType
19776 
19777     @throw type_error.302 in case passed type @a ValueType is incompatible
19778     to the JSON value type (e.g., the JSON value is of type boolean, but a
19779     string is requested); see example below
19780 
19781     @complexity Linear in the size of the JSON value.
19782 
19783     @liveexample{The example below shows several conversions from JSON values
19784     to other types. There a few things to note: (1) Floating-point numbers can
19785     be converted to integers\, (2) A JSON array can be converted to a standard
19786     `std::vector<short>`\, (3) A JSON object can be converted to C++
19787     associative containers such as `std::unordered_map<std::string\,
19788     json>`.,operator__ValueType}
19789 
19790     @since version 1.0.0
19791     */
19792     template < typename ValueType, typename std::enable_if <
19793                    !std::is_pointer<ValueType>::value&&
19794                    !std::is_same<ValueType, detail::json_ref<basic_json>>::value&&
19795                    !std::is_same<ValueType, typename string_t::value_type>::value&&
19796                    !detail::is_basic_json<ValueType>::value
19797                    && !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
19798 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19799                    && !std::is_same<ValueType, typename std::string_view>::value
19800 #endif
19801                    && detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
19802                    , int >::type = 0 >
operator ValueType() const19803     JSON_EXPLICIT operator ValueType() const
19804     {
19805         // delegate the call to get<>() const
19806         return get<ValueType>();
19807     }
19808 
19809     /*!
19810     @return reference to the binary value
19811 
19812     @throw type_error.302 if the value is not binary
19813 
19814     @sa @ref is_binary() to check if the value is binary
19815 
19816     @since version 3.8.0
19817     */
get_binary()19818     binary_t& get_binary()
19819     {
19820         if (!is_binary())
19821         {
19822             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19823         }
19824 
19825         return *get_ptr<binary_t*>();
19826     }
19827 
19828     /// @copydoc get_binary()
get_binary() const19829     const binary_t& get_binary() const
19830     {
19831         if (!is_binary())
19832         {
19833             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name())));
19834         }
19835 
19836         return *get_ptr<const binary_t*>();
19837     }
19838 
19839     /// @}
19840 
19841 
19842     ////////////////////
19843     // element access //
19844     ////////////////////
19845 
19846     /// @name element access
19847     /// Access to the JSON value.
19848     /// @{
19849 
19850     /*!
19851     @brief access specified array element with bounds checking
19852 
19853     Returns a reference to the element at specified location @a idx, with
19854     bounds checking.
19855 
19856     @param[in] idx  index of the element to access
19857 
19858     @return reference to the element at index @a idx
19859 
19860     @throw type_error.304 if the JSON value is not an array; in this case,
19861     calling `at` with an index makes no sense. See example below.
19862     @throw out_of_range.401 if the index @a idx is out of range of the array;
19863     that is, `idx >= size()`. See example below.
19864 
19865     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19866     changes in the JSON value.
19867 
19868     @complexity Constant.
19869 
19870     @since version 1.0.0
19871 
19872     @liveexample{The example below shows how array elements can be read and
19873     written using `at()`. It also demonstrates the different exceptions that
19874     can be thrown.,at__size_type}
19875     */
at(size_type idx)19876     reference at(size_type idx)
19877     {
19878         // at only works for arrays
19879         if (JSON_HEDLEY_LIKELY(is_array()))
19880         {
19881             JSON_TRY
19882             {
19883                 return m_value.array->at(idx);
19884             }
19885             JSON_CATCH (std::out_of_range&)
19886             {
19887                 // create better exception explanation
19888                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19889             }
19890         }
19891         else
19892         {
19893             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19894         }
19895     }
19896 
19897     /*!
19898     @brief access specified array element with bounds checking
19899 
19900     Returns a const reference to the element at specified location @a idx,
19901     with bounds checking.
19902 
19903     @param[in] idx  index of the element to access
19904 
19905     @return const reference to the element at index @a idx
19906 
19907     @throw type_error.304 if the JSON value is not an array; in this case,
19908     calling `at` with an index makes no sense. See example below.
19909     @throw out_of_range.401 if the index @a idx is out of range of the array;
19910     that is, `idx >= size()`. See example below.
19911 
19912     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19913     changes in the JSON value.
19914 
19915     @complexity Constant.
19916 
19917     @since version 1.0.0
19918 
19919     @liveexample{The example below shows how array elements can be read using
19920     `at()`. It also demonstrates the different exceptions that can be thrown.,
19921     at__size_type_const}
19922     */
at(size_type idx) const19923     const_reference at(size_type idx) const
19924     {
19925         // at only works for arrays
19926         if (JSON_HEDLEY_LIKELY(is_array()))
19927         {
19928             JSON_TRY
19929             {
19930                 return m_value.array->at(idx);
19931             }
19932             JSON_CATCH (std::out_of_range&)
19933             {
19934                 // create better exception explanation
19935                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
19936             }
19937         }
19938         else
19939         {
19940             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19941         }
19942     }
19943 
19944     /*!
19945     @brief access specified object element with bounds checking
19946 
19947     Returns a reference to the element at with specified key @a key, with
19948     bounds checking.
19949 
19950     @param[in] key  key of the element to access
19951 
19952     @return reference to the element at key @a key
19953 
19954     @throw type_error.304 if the JSON value is not an object; in this case,
19955     calling `at` with a key makes no sense. See example below.
19956     @throw out_of_range.403 if the key @a key is is not stored in the object;
19957     that is, `find(key) == end()`. See example below.
19958 
19959     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19960     changes in the JSON value.
19961 
19962     @complexity Logarithmic in the size of the container.
19963 
19964     @sa @ref operator[](const typename object_t::key_type&) for unchecked
19965     access by reference
19966     @sa @ref value() for access by value with a default value
19967 
19968     @since version 1.0.0
19969 
19970     @liveexample{The example below shows how object elements can be read and
19971     written using `at()`. It also demonstrates the different exceptions that
19972     can be thrown.,at__object_t_key_type}
19973     */
at(const typename object_t::key_type & key)19974     reference at(const typename object_t::key_type& key)
19975     {
19976         // at only works for objects
19977         if (JSON_HEDLEY_LIKELY(is_object()))
19978         {
19979             JSON_TRY
19980             {
19981                 return m_value.object->at(key);
19982             }
19983             JSON_CATCH (std::out_of_range&)
19984             {
19985                 // create better exception explanation
19986                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
19987             }
19988         }
19989         else
19990         {
19991             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
19992         }
19993     }
19994 
19995     /*!
19996     @brief access specified object element with bounds checking
19997 
19998     Returns a const reference to the element at with specified key @a key,
19999     with bounds checking.
20000 
20001     @param[in] key  key of the element to access
20002 
20003     @return const reference to the element at key @a key
20004 
20005     @throw type_error.304 if the JSON value is not an object; in this case,
20006     calling `at` with a key makes no sense. See example below.
20007     @throw out_of_range.403 if the key @a key is is not stored in the object;
20008     that is, `find(key) == end()`. See example below.
20009 
20010     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20011     changes in the JSON value.
20012 
20013     @complexity Logarithmic in the size of the container.
20014 
20015     @sa @ref operator[](const typename object_t::key_type&) for unchecked
20016     access by reference
20017     @sa @ref value() for access by value with a default value
20018 
20019     @since version 1.0.0
20020 
20021     @liveexample{The example below shows how object elements can be read using
20022     `at()`. It also demonstrates the different exceptions that can be thrown.,
20023     at__object_t_key_type_const}
20024     */
at(const typename object_t::key_type & key) const20025     const_reference at(const typename object_t::key_type& key) const
20026     {
20027         // at only works for objects
20028         if (JSON_HEDLEY_LIKELY(is_object()))
20029         {
20030             JSON_TRY
20031             {
20032                 return m_value.object->at(key);
20033             }
20034             JSON_CATCH (std::out_of_range&)
20035             {
20036                 // create better exception explanation
20037                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
20038             }
20039         }
20040         else
20041         {
20042             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
20043         }
20044     }
20045 
20046     /*!
20047     @brief access specified array element
20048 
20049     Returns a reference to the element at specified location @a idx.
20050 
20051     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
20052     then the array is silently filled up with `null` values to make `idx` a
20053     valid reference to the last stored element.
20054 
20055     @param[in] idx  index of the element to access
20056 
20057     @return reference to the element at index @a idx
20058 
20059     @throw type_error.305 if the JSON value is not an array or null; in that
20060     cases, using the [] operator with an index makes no sense.
20061 
20062     @complexity Constant if @a idx is in the range of the array. Otherwise
20063     linear in `idx - size()`.
20064 
20065     @liveexample{The example below shows how array elements can be read and
20066     written using `[]` operator. Note the addition of `null`
20067     values.,operatorarray__size_type}
20068 
20069     @since version 1.0.0
20070     */
operator [](size_type idx)20071     reference operator[](size_type idx)
20072     {
20073         // implicitly convert null value to an empty array
20074         if (is_null())
20075         {
20076             m_type = value_t::array;
20077             m_value.array = create<array_t>();
20078             assert_invariant();
20079         }
20080 
20081         // operator[] only works for arrays
20082         if (JSON_HEDLEY_LIKELY(is_array()))
20083         {
20084             // fill up array with null values if given idx is outside range
20085             if (idx >= m_value.array->size())
20086             {
20087                 m_value.array->insert(m_value.array->end(),
20088                                       idx - m_value.array->size() + 1,
20089                                       basic_json());
20090             }
20091 
20092             return m_value.array->operator[](idx);
20093         }
20094 
20095         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20096     }
20097 
20098     /*!
20099     @brief access specified array element
20100 
20101     Returns a const reference to the element at specified location @a idx.
20102 
20103     @param[in] idx  index of the element to access
20104 
20105     @return const reference to the element at index @a idx
20106 
20107     @throw type_error.305 if the JSON value is not an array; in that case,
20108     using the [] operator with an index makes no sense.
20109 
20110     @complexity Constant.
20111 
20112     @liveexample{The example below shows how array elements can be read using
20113     the `[]` operator.,operatorarray__size_type_const}
20114 
20115     @since version 1.0.0
20116     */
operator [](size_type idx) const20117     const_reference operator[](size_type idx) const
20118     {
20119         // const operator[] only works for arrays
20120         if (JSON_HEDLEY_LIKELY(is_array()))
20121         {
20122             return m_value.array->operator[](idx);
20123         }
20124 
20125         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
20126     }
20127 
20128     /*!
20129     @brief access specified object element
20130 
20131     Returns a reference to the element at with specified key @a key.
20132 
20133     @note If @a key is not found in the object, then it is silently added to
20134     the object and filled with a `null` value to make `key` a valid reference.
20135     In case the value was `null` before, it is converted to an object.
20136 
20137     @param[in] key  key of the element to access
20138 
20139     @return reference to the element at key @a key
20140 
20141     @throw type_error.305 if the JSON value is not an object or null; in that
20142     cases, using the [] operator with a key makes no sense.
20143 
20144     @complexity Logarithmic in the size of the container.
20145 
20146     @liveexample{The example below shows how object elements can be read and
20147     written using the `[]` operator.,operatorarray__key_type}
20148 
20149     @sa @ref at(const typename object_t::key_type&) for access by reference
20150     with range checking
20151     @sa @ref value() for access by value with a default value
20152 
20153     @since version 1.0.0
20154     */
operator [](const typename object_t::key_type & key)20155     reference operator[](const typename object_t::key_type& key)
20156     {
20157         // implicitly convert null value to an empty object
20158         if (is_null())
20159         {
20160             m_type = value_t::object;
20161             m_value.object = create<object_t>();
20162             assert_invariant();
20163         }
20164 
20165         // operator[] only works for objects
20166         if (JSON_HEDLEY_LIKELY(is_object()))
20167         {
20168             return m_value.object->operator[](key);
20169         }
20170 
20171         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20172     }
20173 
20174     /*!
20175     @brief read-only access specified object element
20176 
20177     Returns a const reference to the element at with specified key @a key. No
20178     bounds checking is performed.
20179 
20180     @warning If the element with key @a key does not exist, the behavior is
20181     undefined.
20182 
20183     @param[in] key  key of the element to access
20184 
20185     @return const reference to the element at key @a key
20186 
20187     @pre The element with key @a key must exist. **This precondition is
20188          enforced with an assertion.**
20189 
20190     @throw type_error.305 if the JSON value is not an object; in that case,
20191     using the [] operator with a key makes no sense.
20192 
20193     @complexity Logarithmic in the size of the container.
20194 
20195     @liveexample{The example below shows how object elements can be read using
20196     the `[]` operator.,operatorarray__key_type_const}
20197 
20198     @sa @ref at(const typename object_t::key_type&) for access by reference
20199     with range checking
20200     @sa @ref value() for access by value with a default value
20201 
20202     @since version 1.0.0
20203     */
operator [](const typename object_t::key_type & key) const20204     const_reference operator[](const typename object_t::key_type& key) const
20205     {
20206         // const operator[] only works for objects
20207         if (JSON_HEDLEY_LIKELY(is_object()))
20208         {
20209             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20210             return m_value.object->find(key)->second;
20211         }
20212 
20213         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20214     }
20215 
20216     /*!
20217     @brief access specified object element
20218 
20219     Returns a reference to the element at with specified key @a key.
20220 
20221     @note If @a key is not found in the object, then it is silently added to
20222     the object and filled with a `null` value to make `key` a valid reference.
20223     In case the value was `null` before, it is converted to an object.
20224 
20225     @param[in] key  key of the element to access
20226 
20227     @return reference to the element at key @a key
20228 
20229     @throw type_error.305 if the JSON value is not an object or null; in that
20230     cases, using the [] operator with a key makes no sense.
20231 
20232     @complexity Logarithmic in the size of the container.
20233 
20234     @liveexample{The example below shows how object elements can be read and
20235     written using the `[]` operator.,operatorarray__key_type}
20236 
20237     @sa @ref at(const typename object_t::key_type&) for access by reference
20238     with range checking
20239     @sa @ref value() for access by value with a default value
20240 
20241     @since version 1.1.0
20242     */
20243     template<typename T>
20244     JSON_HEDLEY_NON_NULL(2)
operator [](T * key)20245     reference operator[](T* key)
20246     {
20247         // implicitly convert null to object
20248         if (is_null())
20249         {
20250             m_type = value_t::object;
20251             m_value = value_t::object;
20252             assert_invariant();
20253         }
20254 
20255         // at only works for objects
20256         if (JSON_HEDLEY_LIKELY(is_object()))
20257         {
20258             return m_value.object->operator[](key);
20259         }
20260 
20261         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20262     }
20263 
20264     /*!
20265     @brief read-only access specified object element
20266 
20267     Returns a const reference to the element at with specified key @a key. No
20268     bounds checking is performed.
20269 
20270     @warning If the element with key @a key does not exist, the behavior is
20271     undefined.
20272 
20273     @param[in] key  key of the element to access
20274 
20275     @return const reference to the element at key @a key
20276 
20277     @pre The element with key @a key must exist. **This precondition is
20278          enforced with an assertion.**
20279 
20280     @throw type_error.305 if the JSON value is not an object; in that case,
20281     using the [] operator with a key makes no sense.
20282 
20283     @complexity Logarithmic in the size of the container.
20284 
20285     @liveexample{The example below shows how object elements can be read using
20286     the `[]` operator.,operatorarray__key_type_const}
20287 
20288     @sa @ref at(const typename object_t::key_type&) for access by reference
20289     with range checking
20290     @sa @ref value() for access by value with a default value
20291 
20292     @since version 1.1.0
20293     */
20294     template<typename T>
20295     JSON_HEDLEY_NON_NULL(2)
operator [](T * key) const20296     const_reference operator[](T* key) const
20297     {
20298         // at only works for objects
20299         if (JSON_HEDLEY_LIKELY(is_object()))
20300         {
20301             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
20302             return m_value.object->find(key)->second;
20303         }
20304 
20305         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
20306     }
20307 
20308     /*!
20309     @brief access specified object element with default value
20310 
20311     Returns either a copy of an object's element at the specified key @a key
20312     or a given default value if no element with key @a key exists.
20313 
20314     The function is basically equivalent to executing
20315     @code {.cpp}
20316     try {
20317         return at(key);
20318     } catch(out_of_range) {
20319         return default_value;
20320     }
20321     @endcode
20322 
20323     @note Unlike @ref at(const typename object_t::key_type&), this function
20324     does not throw if the given key @a key was not found.
20325 
20326     @note Unlike @ref operator[](const typename object_t::key_type& key), this
20327     function does not implicitly add an element to the position defined by @a
20328     key. This function is furthermore also applicable to const objects.
20329 
20330     @param[in] key  key of the element to access
20331     @param[in] default_value  the value to return if @a key is not found
20332 
20333     @tparam ValueType type compatible to JSON values, for instance `int` for
20334     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20335     JSON arrays. Note the type of the expected value at @a key and the default
20336     value @a default_value must be compatible.
20337 
20338     @return copy of the element at key @a key or @a default_value if @a key
20339     is not found
20340 
20341     @throw type_error.302 if @a default_value does not match the type of the
20342     value at @a key
20343     @throw type_error.306 if the JSON value is not an object; in that case,
20344     using `value()` with a key makes no sense.
20345 
20346     @complexity Logarithmic in the size of the container.
20347 
20348     @liveexample{The example below shows how object elements can be queried
20349     with a default value.,basic_json__value}
20350 
20351     @sa @ref at(const typename object_t::key_type&) for access by reference
20352     with range checking
20353     @sa @ref operator[](const typename object_t::key_type&) for unchecked
20354     access by reference
20355 
20356     @since version 1.0.0
20357     */
20358     // using std::is_convertible in a std::enable_if will fail when using explicit conversions
20359     template < class ValueType, typename std::enable_if <
20360                    detail::is_getable<basic_json_t, ValueType>::value
20361                    && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
20362     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
20363     {
20364         // at only works for objects
20365         if (JSON_HEDLEY_LIKELY(is_object()))
20366         {
20367             // if key is found, return value and given default value otherwise
20368             const auto it = find(key);
20369             if (it != end())
20370             {
20371                 return it->template get<ValueType>();
20372             }
20373 
20374             return default_value;
20375         }
20376 
20377         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20378     }
20379 
20380     /*!
20381     @brief overload for a default value of type const char*
20382     @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
20383     */
value(const typename object_t::key_type & key,const char * default_value) const20384     string_t value(const typename object_t::key_type& key, const char* default_value) const
20385     {
20386         return value(key, string_t(default_value));
20387     }
20388 
20389     /*!
20390     @brief access specified object element via JSON Pointer with default value
20391 
20392     Returns either a copy of an object's element at the specified key @a key
20393     or a given default value if no element with key @a key exists.
20394 
20395     The function is basically equivalent to executing
20396     @code {.cpp}
20397     try {
20398         return at(ptr);
20399     } catch(out_of_range) {
20400         return default_value;
20401     }
20402     @endcode
20403 
20404     @note Unlike @ref at(const json_pointer&), this function does not throw
20405     if the given key @a key was not found.
20406 
20407     @param[in] ptr  a JSON pointer to the element to access
20408     @param[in] default_value  the value to return if @a ptr found no value
20409 
20410     @tparam ValueType type compatible to JSON values, for instance `int` for
20411     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
20412     JSON arrays. Note the type of the expected value at @a key and the default
20413     value @a default_value must be compatible.
20414 
20415     @return copy of the element at key @a key or @a default_value if @a key
20416     is not found
20417 
20418     @throw type_error.302 if @a default_value does not match the type of the
20419     value at @a ptr
20420     @throw type_error.306 if the JSON value is not an object; in that case,
20421     using `value()` with a key makes no sense.
20422 
20423     @complexity Logarithmic in the size of the container.
20424 
20425     @liveexample{The example below shows how object elements can be queried
20426     with a default value.,basic_json__value_ptr}
20427 
20428     @sa @ref operator[](const json_pointer&) for unchecked access by reference
20429 
20430     @since version 2.0.2
20431     */
20432     template<class ValueType, typename std::enable_if<
20433                  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
20434     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20435     {
20436         // at only works for objects
20437         if (JSON_HEDLEY_LIKELY(is_object()))
20438         {
20439             // if pointer resolves a value, return it or use default value
20440             JSON_TRY
20441             {
20442                 return ptr.get_checked(this).template get<ValueType>();
20443             }
20444             JSON_INTERNAL_CATCH (out_of_range&)
20445             {
20446                 return default_value;
20447             }
20448         }
20449 
20450         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
20451     }
20452 
20453     /*!
20454     @brief overload for a default value of type const char*
20455     @copydoc basic_json::value(const json_pointer&, ValueType) const
20456     */
20457     JSON_HEDLEY_NON_NULL(3)
value(const json_pointer & ptr,const char * default_value) const20458     string_t value(const json_pointer& ptr, const char* default_value) const
20459     {
20460         return value(ptr, string_t(default_value));
20461     }
20462 
20463     /*!
20464     @brief access the first element
20465 
20466     Returns a reference to the first element in the container. For a JSON
20467     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
20468 
20469     @return In case of a structured type (array or object), a reference to the
20470     first element is returned. In case of number, string, boolean, or binary
20471     values, a reference to the value is returned.
20472 
20473     @complexity Constant.
20474 
20475     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20476     or an empty array or object (undefined behavior, **guarded by
20477     assertions**).
20478     @post The JSON value remains unchanged.
20479 
20480     @throw invalid_iterator.214 when called on `null` value
20481 
20482     @liveexample{The following code shows an example for `front()`.,front}
20483 
20484     @sa @ref back() -- access the last element
20485 
20486     @since version 1.0.0
20487     */
front()20488     reference front()
20489     {
20490         return *begin();
20491     }
20492 
20493     /*!
20494     @copydoc basic_json::front()
20495     */
front() const20496     const_reference front() const
20497     {
20498         return *cbegin();
20499     }
20500 
20501     /*!
20502     @brief access the last element
20503 
20504     Returns a reference to the last element in the container. For a JSON
20505     container `c`, the expression `c.back()` is equivalent to
20506     @code {.cpp}
20507     auto tmp = c.end();
20508     --tmp;
20509     return *tmp;
20510     @endcode
20511 
20512     @return In case of a structured type (array or object), a reference to the
20513     last element is returned. In case of number, string, boolean, or binary
20514     values, a reference to the value is returned.
20515 
20516     @complexity Constant.
20517 
20518     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
20519     or an empty array or object (undefined behavior, **guarded by
20520     assertions**).
20521     @post The JSON value remains unchanged.
20522 
20523     @throw invalid_iterator.214 when called on a `null` value. See example
20524     below.
20525 
20526     @liveexample{The following code shows an example for `back()`.,back}
20527 
20528     @sa @ref front() -- access the first element
20529 
20530     @since version 1.0.0
20531     */
back()20532     reference back()
20533     {
20534         auto tmp = end();
20535         --tmp;
20536         return *tmp;
20537     }
20538 
20539     /*!
20540     @copydoc basic_json::back()
20541     */
back() const20542     const_reference back() const
20543     {
20544         auto tmp = cend();
20545         --tmp;
20546         return *tmp;
20547     }
20548 
20549     /*!
20550     @brief remove element given an iterator
20551 
20552     Removes the element specified by iterator @a pos. The iterator @a pos must
20553     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
20554     but is not dereferenceable) cannot be used as a value for @a pos.
20555 
20556     If called on a primitive type other than `null`, the resulting JSON value
20557     will be `null`.
20558 
20559     @param[in] pos iterator to the element to remove
20560     @return Iterator following the last removed element. If the iterator @a
20561     pos refers to the last element, the `end()` iterator is returned.
20562 
20563     @tparam IteratorType an @ref iterator or @ref const_iterator
20564 
20565     @post Invalidates iterators and references at or after the point of the
20566     erase, including the `end()` iterator.
20567 
20568     @throw type_error.307 if called on a `null` value; example: `"cannot use
20569     erase() with null"`
20570     @throw invalid_iterator.202 if called on an iterator which does not belong
20571     to the current JSON value; example: `"iterator does not fit current
20572     value"`
20573     @throw invalid_iterator.205 if called on a primitive type with invalid
20574     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
20575     out of range"`
20576 
20577     @complexity The complexity depends on the type:
20578     - objects: amortized constant
20579     - arrays: linear in distance between @a pos and the end of the container
20580     - strings and binary: linear in the length of the member
20581     - other types: constant
20582 
20583     @liveexample{The example shows the result of `erase()` for different JSON
20584     types.,erase__IteratorType}
20585 
20586     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20587     the given range
20588     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20589     from an object at the given key
20590     @sa @ref erase(const size_type) -- removes the element from an array at
20591     the given index
20592 
20593     @since version 1.0.0
20594     */
20595     template < class IteratorType, typename std::enable_if <
20596                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20597                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20598                = 0 >
20599     IteratorType erase(IteratorType pos)
20600     {
20601         // make sure iterator fits the current value
20602         if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20603         {
20604             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
20605         }
20606 
20607         IteratorType result = end();
20608 
20609         switch (m_type)
20610         {
20611             case value_t::boolean:
20612             case value_t::number_float:
20613             case value_t::number_integer:
20614             case value_t::number_unsigned:
20615             case value_t::string:
20616             case value_t::binary:
20617             {
20618                 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20619                 {
20620                     JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
20621                 }
20622 
20623                 if (is_string())
20624                 {
20625                     AllocatorType<string_t> alloc;
20626                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20627                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20628                     m_value.string = nullptr;
20629                 }
20630                 else if (is_binary())
20631                 {
20632                     AllocatorType<binary_t> alloc;
20633                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20634                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20635                     m_value.binary = nullptr;
20636                 }
20637 
20638                 m_type = value_t::null;
20639                 assert_invariant();
20640                 break;
20641             }
20642 
20643             case value_t::object:
20644             {
20645                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20646                 break;
20647             }
20648 
20649             case value_t::array:
20650             {
20651                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20652                 break;
20653             }
20654 
20655             default:
20656                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20657         }
20658 
20659         return result;
20660     }
20661 
20662     /*!
20663     @brief remove elements given an iterator range
20664 
20665     Removes the element specified by the range `[first; last)`. The iterator
20666     @a first does not need to be dereferenceable if `first == last`: erasing
20667     an empty range is a no-op.
20668 
20669     If called on a primitive type other than `null`, the resulting JSON value
20670     will be `null`.
20671 
20672     @param[in] first iterator to the beginning of the range to remove
20673     @param[in] last iterator past the end of the range to remove
20674     @return Iterator following the last removed element. If the iterator @a
20675     second refers to the last element, the `end()` iterator is returned.
20676 
20677     @tparam IteratorType an @ref iterator or @ref const_iterator
20678 
20679     @post Invalidates iterators and references at or after the point of the
20680     erase, including the `end()` iterator.
20681 
20682     @throw type_error.307 if called on a `null` value; example: `"cannot use
20683     erase() with null"`
20684     @throw invalid_iterator.203 if called on iterators which does not belong
20685     to the current JSON value; example: `"iterators do not fit current value"`
20686     @throw invalid_iterator.204 if called on a primitive type with invalid
20687     iterators (i.e., if `first != begin()` and `last != end()`); example:
20688     `"iterators out of range"`
20689 
20690     @complexity The complexity depends on the type:
20691     - objects: `log(size()) + std::distance(first, last)`
20692     - arrays: linear in the distance between @a first and @a last, plus linear
20693       in the distance between @a last and end of the container
20694     - strings and binary: linear in the length of the member
20695     - other types: constant
20696 
20697     @liveexample{The example shows the result of `erase()` for different JSON
20698     types.,erase__IteratorType_IteratorType}
20699 
20700     @sa @ref erase(IteratorType) -- removes the element at a given position
20701     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20702     from an object at the given key
20703     @sa @ref erase(const size_type) -- removes the element from an array at
20704     the given index
20705 
20706     @since version 1.0.0
20707     */
20708     template < class IteratorType, typename std::enable_if <
20709                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20710                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
20711                = 0 >
20712     IteratorType erase(IteratorType first, IteratorType last)
20713     {
20714         // make sure iterator fits the current value
20715         if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20716         {
20717             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
20718         }
20719 
20720         IteratorType result = end();
20721 
20722         switch (m_type)
20723         {
20724             case value_t::boolean:
20725             case value_t::number_float:
20726             case value_t::number_integer:
20727             case value_t::number_unsigned:
20728             case value_t::string:
20729             case value_t::binary:
20730             {
20731                 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
20732                                        || !last.m_it.primitive_iterator.is_end()))
20733                 {
20734                     JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
20735                 }
20736 
20737                 if (is_string())
20738                 {
20739                     AllocatorType<string_t> alloc;
20740                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20741                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20742                     m_value.string = nullptr;
20743                 }
20744                 else if (is_binary())
20745                 {
20746                     AllocatorType<binary_t> alloc;
20747                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20748                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20749                     m_value.binary = nullptr;
20750                 }
20751 
20752                 m_type = value_t::null;
20753                 assert_invariant();
20754                 break;
20755             }
20756 
20757             case value_t::object:
20758             {
20759                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
20760                                               last.m_it.object_iterator);
20761                 break;
20762             }
20763 
20764             case value_t::array:
20765             {
20766                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
20767                                              last.m_it.array_iterator);
20768                 break;
20769             }
20770 
20771             default:
20772                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20773         }
20774 
20775         return result;
20776     }
20777 
20778     /*!
20779     @brief remove element from a JSON object given a key
20780 
20781     Removes elements from a JSON object with the key value @a key.
20782 
20783     @param[in] key value of the elements to remove
20784 
20785     @return Number of elements removed. If @a ObjectType is the default
20786     `std::map` type, the return value will always be `0` (@a key was not
20787     found) or `1` (@a key was found).
20788 
20789     @post References and iterators to the erased elements are invalidated.
20790     Other references and iterators are not affected.
20791 
20792     @throw type_error.307 when called on a type other than JSON object;
20793     example: `"cannot use erase() with null"`
20794 
20795     @complexity `log(size()) + count(key)`
20796 
20797     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
20798 
20799     @sa @ref erase(IteratorType) -- removes the element at a given position
20800     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20801     the given range
20802     @sa @ref erase(const size_type) -- removes the element from an array at
20803     the given index
20804 
20805     @since version 1.0.0
20806     */
erase(const typename object_t::key_type & key)20807     size_type erase(const typename object_t::key_type& key)
20808     {
20809         // this erase only works for objects
20810         if (JSON_HEDLEY_LIKELY(is_object()))
20811         {
20812             return m_value.object->erase(key);
20813         }
20814 
20815         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20816     }
20817 
20818     /*!
20819     @brief remove element from a JSON array given an index
20820 
20821     Removes element from a JSON array at the index @a idx.
20822 
20823     @param[in] idx index of the element to remove
20824 
20825     @throw type_error.307 when called on a type other than JSON object;
20826     example: `"cannot use erase() with null"`
20827     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
20828     is out of range"`
20829 
20830     @complexity Linear in distance between @a idx and the end of the container.
20831 
20832     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
20833 
20834     @sa @ref erase(IteratorType) -- removes the element at a given position
20835     @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
20836     the given range
20837     @sa @ref erase(const typename object_t::key_type&) -- removes the element
20838     from an object at the given key
20839 
20840     @since version 1.0.0
20841     */
erase(const size_type idx)20842     void erase(const size_type idx)
20843     {
20844         // this erase only works for arrays
20845         if (JSON_HEDLEY_LIKELY(is_array()))
20846         {
20847             if (JSON_HEDLEY_UNLIKELY(idx >= size()))
20848             {
20849                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20850             }
20851 
20852             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
20853         }
20854         else
20855         {
20856             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
20857         }
20858     }
20859 
20860     /// @}
20861 
20862 
20863     ////////////
20864     // lookup //
20865     ////////////
20866 
20867     /// @name lookup
20868     /// @{
20869 
20870     /*!
20871     @brief find an element in a JSON object
20872 
20873     Finds an element in a JSON object with key equivalent to @a key. If the
20874     element is not found or the JSON value is not an object, end() is
20875     returned.
20876 
20877     @note This method always returns @ref end() when executed on a JSON type
20878           that is not an object.
20879 
20880     @param[in] key key value of the element to search for.
20881 
20882     @return Iterator to an element with key equivalent to @a key. If no such
20883     element is found or the JSON value is not an object, past-the-end (see
20884     @ref end()) iterator is returned.
20885 
20886     @complexity Logarithmic in the size of the JSON object.
20887 
20888     @liveexample{The example shows how `find()` is used.,find__key_type}
20889 
20890     @sa @ref contains(KeyT&&) const -- checks whether a key exists
20891 
20892     @since version 1.0.0
20893     */
20894     template<typename KeyT>
find(KeyT && key)20895     iterator find(KeyT&& key)
20896     {
20897         auto result = end();
20898 
20899         if (is_object())
20900         {
20901             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20902         }
20903 
20904         return result;
20905     }
20906 
20907     /*!
20908     @brief find an element in a JSON object
20909     @copydoc find(KeyT&&)
20910     */
20911     template<typename KeyT>
find(KeyT && key) const20912     const_iterator find(KeyT&& key) const
20913     {
20914         auto result = cend();
20915 
20916         if (is_object())
20917         {
20918             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
20919         }
20920 
20921         return result;
20922     }
20923 
20924     /*!
20925     @brief returns the number of occurrences of a key in a JSON object
20926 
20927     Returns the number of elements with key @a key. If ObjectType is the
20928     default `std::map` type, the return value will always be `0` (@a key was
20929     not found) or `1` (@a key was found).
20930 
20931     @note This method always returns `0` when executed on a JSON type that is
20932           not an object.
20933 
20934     @param[in] key key value of the element to count
20935 
20936     @return Number of elements with key @a key. If the JSON value is not an
20937     object, the return value will be `0`.
20938 
20939     @complexity Logarithmic in the size of the JSON object.
20940 
20941     @liveexample{The example shows how `count()` is used.,count}
20942 
20943     @since version 1.0.0
20944     */
20945     template<typename KeyT>
count(KeyT && key) const20946     size_type count(KeyT&& key) const
20947     {
20948         // return 0 for all nonobject types
20949         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
20950     }
20951 
20952     /*!
20953     @brief check the existence of an element in a JSON object
20954 
20955     Check whether an element exists in a JSON object with key equivalent to
20956     @a key. If the element is not found or the JSON value is not an object,
20957     false is returned.
20958 
20959     @note This method always returns false when executed on a JSON type
20960           that is not an object.
20961 
20962     @param[in] key key value to check its existence.
20963 
20964     @return true if an element with specified @a key exists. If no such
20965     element with such key is found or the JSON value is not an object,
20966     false is returned.
20967 
20968     @complexity Logarithmic in the size of the JSON object.
20969 
20970     @liveexample{The following code shows an example for `contains()`.,contains}
20971 
20972     @sa @ref find(KeyT&&) -- returns an iterator to an object element
20973     @sa @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
20974 
20975     @since version 3.6.0
20976     */
20977     template < typename KeyT, typename std::enable_if <
20978                    !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
contains(KeyT && key) const20979     bool contains(KeyT && key) const
20980     {
20981         return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
20982     }
20983 
20984     /*!
20985     @brief check the existence of an element in a JSON object given a JSON pointer
20986 
20987     Check whether the given JSON pointer @a ptr can be resolved in the current
20988     JSON value.
20989 
20990     @note This method can be executed on any JSON value type.
20991 
20992     @param[in] ptr JSON pointer to check its existence.
20993 
20994     @return true if the JSON pointer can be resolved to a stored value, false
20995     otherwise.
20996 
20997     @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
20998 
20999     @throw parse_error.106   if an array index begins with '0'
21000     @throw parse_error.109   if an array index was not a number
21001 
21002     @complexity Logarithmic in the size of the JSON object.
21003 
21004     @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
21005 
21006     @sa @ref contains(KeyT &&) const -- checks the existence of a key
21007 
21008     @since version 3.7.0
21009     */
contains(const json_pointer & ptr) const21010     bool contains(const json_pointer& ptr) const
21011     {
21012         return ptr.contains(this);
21013     }
21014 
21015     /// @}
21016 
21017 
21018     ///////////////
21019     // iterators //
21020     ///////////////
21021 
21022     /// @name iterators
21023     /// @{
21024 
21025     /*!
21026     @brief returns an iterator to the first element
21027 
21028     Returns an iterator to the first element.
21029 
21030     @image html range-begin-end.svg "Illustration from cppreference.com"
21031 
21032     @return iterator to the first element
21033 
21034     @complexity Constant.
21035 
21036     @requirement This function helps `basic_json` satisfying the
21037     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21038     requirements:
21039     - The complexity is constant.
21040 
21041     @liveexample{The following code shows an example for `begin()`.,begin}
21042 
21043     @sa @ref cbegin() -- returns a const iterator to the beginning
21044     @sa @ref end() -- returns an iterator to the end
21045     @sa @ref cend() -- returns a const iterator to the end
21046 
21047     @since version 1.0.0
21048     */
begin()21049     iterator begin() noexcept
21050     {
21051         iterator result(this);
21052         result.set_begin();
21053         return result;
21054     }
21055 
21056     /*!
21057     @copydoc basic_json::cbegin()
21058     */
begin() const21059     const_iterator begin() const noexcept
21060     {
21061         return cbegin();
21062     }
21063 
21064     /*!
21065     @brief returns a const iterator to the first element
21066 
21067     Returns a const iterator to the first element.
21068 
21069     @image html range-begin-end.svg "Illustration from cppreference.com"
21070 
21071     @return const iterator to the first element
21072 
21073     @complexity Constant.
21074 
21075     @requirement This function helps `basic_json` satisfying the
21076     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21077     requirements:
21078     - The complexity is constant.
21079     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
21080 
21081     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
21082 
21083     @sa @ref begin() -- returns an iterator to the beginning
21084     @sa @ref end() -- returns an iterator to the end
21085     @sa @ref cend() -- returns a const iterator to the end
21086 
21087     @since version 1.0.0
21088     */
cbegin() const21089     const_iterator cbegin() const noexcept
21090     {
21091         const_iterator result(this);
21092         result.set_begin();
21093         return result;
21094     }
21095 
21096     /*!
21097     @brief returns an iterator to one past the last element
21098 
21099     Returns an iterator to one past the last element.
21100 
21101     @image html range-begin-end.svg "Illustration from cppreference.com"
21102 
21103     @return iterator one past the last element
21104 
21105     @complexity Constant.
21106 
21107     @requirement This function helps `basic_json` satisfying the
21108     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21109     requirements:
21110     - The complexity is constant.
21111 
21112     @liveexample{The following code shows an example for `end()`.,end}
21113 
21114     @sa @ref cend() -- returns a const iterator to the end
21115     @sa @ref begin() -- returns an iterator to the beginning
21116     @sa @ref cbegin() -- returns a const iterator to the beginning
21117 
21118     @since version 1.0.0
21119     */
end()21120     iterator end() noexcept
21121     {
21122         iterator result(this);
21123         result.set_end();
21124         return result;
21125     }
21126 
21127     /*!
21128     @copydoc basic_json::cend()
21129     */
end() const21130     const_iterator end() const noexcept
21131     {
21132         return cend();
21133     }
21134 
21135     /*!
21136     @brief returns a const iterator to one past the last element
21137 
21138     Returns a const iterator to one past the last element.
21139 
21140     @image html range-begin-end.svg "Illustration from cppreference.com"
21141 
21142     @return const iterator one past the last element
21143 
21144     @complexity Constant.
21145 
21146     @requirement This function helps `basic_json` satisfying the
21147     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21148     requirements:
21149     - The complexity is constant.
21150     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
21151 
21152     @liveexample{The following code shows an example for `cend()`.,cend}
21153 
21154     @sa @ref end() -- returns an iterator to the end
21155     @sa @ref begin() -- returns an iterator to the beginning
21156     @sa @ref cbegin() -- returns a const iterator to the beginning
21157 
21158     @since version 1.0.0
21159     */
cend() const21160     const_iterator cend() const noexcept
21161     {
21162         const_iterator result(this);
21163         result.set_end();
21164         return result;
21165     }
21166 
21167     /*!
21168     @brief returns an iterator to the reverse-beginning
21169 
21170     Returns an iterator to the reverse-beginning; that is, the last element.
21171 
21172     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21173 
21174     @complexity Constant.
21175 
21176     @requirement This function helps `basic_json` satisfying the
21177     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21178     requirements:
21179     - The complexity is constant.
21180     - Has the semantics of `reverse_iterator(end())`.
21181 
21182     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
21183 
21184     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21185     @sa @ref rend() -- returns a reverse iterator to the end
21186     @sa @ref crend() -- returns a const reverse iterator to the end
21187 
21188     @since version 1.0.0
21189     */
rbegin()21190     reverse_iterator rbegin() noexcept
21191     {
21192         return reverse_iterator(end());
21193     }
21194 
21195     /*!
21196     @copydoc basic_json::crbegin()
21197     */
rbegin() const21198     const_reverse_iterator rbegin() const noexcept
21199     {
21200         return crbegin();
21201     }
21202 
21203     /*!
21204     @brief returns an iterator to the reverse-end
21205 
21206     Returns an iterator to the reverse-end; that is, one before the first
21207     element.
21208 
21209     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21210 
21211     @complexity Constant.
21212 
21213     @requirement This function helps `basic_json` satisfying the
21214     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21215     requirements:
21216     - The complexity is constant.
21217     - Has the semantics of `reverse_iterator(begin())`.
21218 
21219     @liveexample{The following code shows an example for `rend()`.,rend}
21220 
21221     @sa @ref crend() -- returns a const reverse iterator to the end
21222     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21223     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21224 
21225     @since version 1.0.0
21226     */
rend()21227     reverse_iterator rend() noexcept
21228     {
21229         return reverse_iterator(begin());
21230     }
21231 
21232     /*!
21233     @copydoc basic_json::crend()
21234     */
rend() const21235     const_reverse_iterator rend() const noexcept
21236     {
21237         return crend();
21238     }
21239 
21240     /*!
21241     @brief returns a const reverse iterator to the last element
21242 
21243     Returns a const iterator to the reverse-beginning; that is, the last
21244     element.
21245 
21246     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21247 
21248     @complexity Constant.
21249 
21250     @requirement This function helps `basic_json` satisfying the
21251     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21252     requirements:
21253     - The complexity is constant.
21254     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
21255 
21256     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
21257 
21258     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21259     @sa @ref rend() -- returns a reverse iterator to the end
21260     @sa @ref crend() -- returns a const reverse iterator to the end
21261 
21262     @since version 1.0.0
21263     */
crbegin() const21264     const_reverse_iterator crbegin() const noexcept
21265     {
21266         return const_reverse_iterator(cend());
21267     }
21268 
21269     /*!
21270     @brief returns a const reverse iterator to one before the first
21271 
21272     Returns a const reverse iterator to the reverse-end; that is, one before
21273     the first element.
21274 
21275     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
21276 
21277     @complexity Constant.
21278 
21279     @requirement This function helps `basic_json` satisfying the
21280     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
21281     requirements:
21282     - The complexity is constant.
21283     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
21284 
21285     @liveexample{The following code shows an example for `crend()`.,crend}
21286 
21287     @sa @ref rend() -- returns a reverse iterator to the end
21288     @sa @ref rbegin() -- returns a reverse iterator to the beginning
21289     @sa @ref crbegin() -- returns a const reverse iterator to the beginning
21290 
21291     @since version 1.0.0
21292     */
crend() const21293     const_reverse_iterator crend() const noexcept
21294     {
21295         return const_reverse_iterator(cbegin());
21296     }
21297 
21298   public:
21299     /*!
21300     @brief wrapper to access iterator member functions in range-based for
21301 
21302     This function allows to access @ref iterator::key() and @ref
21303     iterator::value() during range-based for loops. In these loops, a
21304     reference to the JSON values is returned, so there is no access to the
21305     underlying iterator.
21306 
21307     For loop without iterator_wrapper:
21308 
21309     @code{cpp}
21310     for (auto it = j_object.begin(); it != j_object.end(); ++it)
21311     {
21312         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21313     }
21314     @endcode
21315 
21316     Range-based for loop without iterator proxy:
21317 
21318     @code{cpp}
21319     for (auto it : j_object)
21320     {
21321         // "it" is of type json::reference and has no key() member
21322         std::cout << "value: " << it << '\n';
21323     }
21324     @endcode
21325 
21326     Range-based for loop with iterator proxy:
21327 
21328     @code{cpp}
21329     for (auto it : json::iterator_wrapper(j_object))
21330     {
21331         std::cout << "key: " << it.key() << ", value:" << it.value() << '\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).
21337 
21338     @param[in] ref  reference to a JSON value
21339     @return iteration proxy object wrapping @a ref with an interface to use in
21340             range-based for loops
21341 
21342     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
21343 
21344     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21345     changes in the JSON value.
21346 
21347     @complexity Constant.
21348 
21349     @note The name of this function is not yet final and may change in the
21350     future.
21351 
21352     @deprecated This stream operator is deprecated and will be removed in
21353                 future 4.0.0 of the library. Please use @ref items() instead;
21354                 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
21355     */
items()21356     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21357     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21358     {
21359         return ref.items();
21360     }
21361 
21362     /*!
21363     @copydoc iterator_wrapper(reference)
21364     */
items()21365     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21366     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21367     {
21368         return ref.items();
21369     }
21370 
21371     /*!
21372     @brief helper to access iterator member functions in range-based for
21373 
21374     This function allows to access @ref iterator::key() and @ref
21375     iterator::value() during range-based for loops. In these loops, a
21376     reference to the JSON values is returned, so there is no access to the
21377     underlying iterator.
21378 
21379     For loop without `items()` function:
21380 
21381     @code{cpp}
21382     for (auto it = j_object.begin(); it != j_object.end(); ++it)
21383     {
21384         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
21385     }
21386     @endcode
21387 
21388     Range-based for loop without `items()` function:
21389 
21390     @code{cpp}
21391     for (auto it : j_object)
21392     {
21393         // "it" is of type json::reference and has no key() member
21394         std::cout << "value: " << it << '\n';
21395     }
21396     @endcode
21397 
21398     Range-based for loop with `items()` function:
21399 
21400     @code{cpp}
21401     for (auto& el : j_object.items())
21402     {
21403         std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
21404     }
21405     @endcode
21406 
21407     The `items()` function also allows to use
21408     [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
21409     (C++17):
21410 
21411     @code{cpp}
21412     for (auto& [key, val] : j_object.items())
21413     {
21414         std::cout << "key: " << key << ", value:" << val << '\n';
21415     }
21416     @endcode
21417 
21418     @note When iterating over an array, `key()` will return the index of the
21419           element as string (see example). For primitive types (e.g., numbers),
21420           `key()` returns an empty string.
21421 
21422     @warning Using `items()` on temporary objects is dangerous. Make sure the
21423              object's lifetime exeeds the iteration. See
21424              <https://github.com/nlohmann/json/issues/2040> for more
21425              information.
21426 
21427     @return iteration proxy object wrapping @a ref with an interface to use in
21428             range-based for loops
21429 
21430     @liveexample{The following code shows how the function is used.,items}
21431 
21432     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21433     changes in the JSON value.
21434 
21435     @complexity Constant.
21436 
21437     @since version 3.1.0, structured bindings support since 3.5.0.
21438     */
items()21439     iteration_proxy<iterator> items() noexcept
21440     {
21441         return iteration_proxy<iterator>(*this);
21442     }
21443 
21444     /*!
21445     @copydoc items()
21446     */
items() const21447     iteration_proxy<const_iterator> items() const noexcept
21448     {
21449         return iteration_proxy<const_iterator>(*this);
21450     }
21451 
21452     /// @}
21453 
21454 
21455     //////////////
21456     // capacity //
21457     //////////////
21458 
21459     /// @name capacity
21460     /// @{
21461 
21462     /*!
21463     @brief checks whether the container is empty.
21464 
21465     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
21466 
21467     @return The return value depends on the different types and is
21468             defined as follows:
21469             Value type  | return value
21470             ----------- | -------------
21471             null        | `true`
21472             boolean     | `false`
21473             string      | `false`
21474             number      | `false`
21475             binary      | `false`
21476             object      | result of function `object_t::empty()`
21477             array       | result of function `array_t::empty()`
21478 
21479     @liveexample{The following code uses `empty()` to check if a JSON
21480     object contains any elements.,empty}
21481 
21482     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21483     the Container concept; that is, their `empty()` functions have constant
21484     complexity.
21485 
21486     @iterators No changes.
21487 
21488     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21489 
21490     @note This function does not return whether a string stored as JSON value
21491     is empty - it returns whether the JSON container itself is empty which is
21492     false in the case of a string.
21493 
21494     @requirement This function helps `basic_json` satisfying the
21495     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21496     requirements:
21497     - The complexity is constant.
21498     - Has the semantics of `begin() == end()`.
21499 
21500     @sa @ref size() -- returns the number of elements
21501 
21502     @since version 1.0.0
21503     */
empty() const21504     bool empty() const noexcept
21505     {
21506         switch (m_type)
21507         {
21508             case value_t::null:
21509             {
21510                 // null values are empty
21511                 return true;
21512             }
21513 
21514             case value_t::array:
21515             {
21516                 // delegate call to array_t::empty()
21517                 return m_value.array->empty();
21518             }
21519 
21520             case value_t::object:
21521             {
21522                 // delegate call to object_t::empty()
21523                 return m_value.object->empty();
21524             }
21525 
21526             default:
21527             {
21528                 // all other types are nonempty
21529                 return false;
21530             }
21531         }
21532     }
21533 
21534     /*!
21535     @brief returns the number of elements
21536 
21537     Returns the number of elements in a JSON value.
21538 
21539     @return The return value depends on the different types and is
21540             defined as follows:
21541             Value type  | return value
21542             ----------- | -------------
21543             null        | `0`
21544             boolean     | `1`
21545             string      | `1`
21546             number      | `1`
21547             binary      | `1`
21548             object      | result of function object_t::size()
21549             array       | result of function array_t::size()
21550 
21551     @liveexample{The following code calls `size()` on the different value
21552     types.,size}
21553 
21554     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21555     the Container concept; that is, their size() functions have constant
21556     complexity.
21557 
21558     @iterators No changes.
21559 
21560     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21561 
21562     @note This function does not return the length of a string stored as JSON
21563     value - it returns the number of elements in the JSON value which is 1 in
21564     the case of a string.
21565 
21566     @requirement This function helps `basic_json` satisfying the
21567     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21568     requirements:
21569     - The complexity is constant.
21570     - Has the semantics of `std::distance(begin(), end())`.
21571 
21572     @sa @ref empty() -- checks whether the container is empty
21573     @sa @ref max_size() -- returns the maximal number of elements
21574 
21575     @since version 1.0.0
21576     */
size() const21577     size_type size() const noexcept
21578     {
21579         switch (m_type)
21580         {
21581             case value_t::null:
21582             {
21583                 // null values are empty
21584                 return 0;
21585             }
21586 
21587             case value_t::array:
21588             {
21589                 // delegate call to array_t::size()
21590                 return m_value.array->size();
21591             }
21592 
21593             case value_t::object:
21594             {
21595                 // delegate call to object_t::size()
21596                 return m_value.object->size();
21597             }
21598 
21599             default:
21600             {
21601                 // all other types have size 1
21602                 return 1;
21603             }
21604         }
21605     }
21606 
21607     /*!
21608     @brief returns the maximum possible number of elements
21609 
21610     Returns the maximum number of elements a JSON value is able to hold due to
21611     system or library implementation limitations, i.e. `std::distance(begin(),
21612     end())` for the JSON value.
21613 
21614     @return The return value depends on the different types and is
21615             defined as follows:
21616             Value type  | return value
21617             ----------- | -------------
21618             null        | `0` (same as `size()`)
21619             boolean     | `1` (same as `size()`)
21620             string      | `1` (same as `size()`)
21621             number      | `1` (same as `size()`)
21622             binary      | `1` (same as `size()`)
21623             object      | result of function `object_t::max_size()`
21624             array       | result of function `array_t::max_size()`
21625 
21626     @liveexample{The following code calls `max_size()` on the different value
21627     types. Note the output is implementation specific.,max_size}
21628 
21629     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
21630     the Container concept; that is, their `max_size()` functions have constant
21631     complexity.
21632 
21633     @iterators No changes.
21634 
21635     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21636 
21637     @requirement This function helps `basic_json` satisfying the
21638     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
21639     requirements:
21640     - The complexity is constant.
21641     - Has the semantics of returning `b.size()` where `b` is the largest
21642       possible JSON value.
21643 
21644     @sa @ref size() -- returns the number of elements
21645 
21646     @since version 1.0.0
21647     */
max_size() const21648     size_type max_size() const noexcept
21649     {
21650         switch (m_type)
21651         {
21652             case value_t::array:
21653             {
21654                 // delegate call to array_t::max_size()
21655                 return m_value.array->max_size();
21656             }
21657 
21658             case value_t::object:
21659             {
21660                 // delegate call to object_t::max_size()
21661                 return m_value.object->max_size();
21662             }
21663 
21664             default:
21665             {
21666                 // all other types have max_size() == size()
21667                 return size();
21668             }
21669         }
21670     }
21671 
21672     /// @}
21673 
21674 
21675     ///////////////
21676     // modifiers //
21677     ///////////////
21678 
21679     /// @name modifiers
21680     /// @{
21681 
21682     /*!
21683     @brief clears the contents
21684 
21685     Clears the content of a JSON value and resets it to the default value as
21686     if @ref basic_json(value_t) would have been called with the current value
21687     type from @ref type():
21688 
21689     Value type  | initial value
21690     ----------- | -------------
21691     null        | `null`
21692     boolean     | `false`
21693     string      | `""`
21694     number      | `0`
21695     binary      | An empty byte vector
21696     object      | `{}`
21697     array       | `[]`
21698 
21699     @post Has the same effect as calling
21700     @code {.cpp}
21701     *this = basic_json(type());
21702     @endcode
21703 
21704     @liveexample{The example below shows the effect of `clear()` to different
21705     JSON types.,clear}
21706 
21707     @complexity Linear in the size of the JSON value.
21708 
21709     @iterators All iterators, pointers and references related to this container
21710                are invalidated.
21711 
21712     @exceptionsafety No-throw guarantee: this function never throws exceptions.
21713 
21714     @sa @ref basic_json(value_t) -- constructor that creates an object with the
21715         same value than calling `clear()`
21716 
21717     @since version 1.0.0
21718     */
clear()21719     void clear() noexcept
21720     {
21721         switch (m_type)
21722         {
21723             case value_t::number_integer:
21724             {
21725                 m_value.number_integer = 0;
21726                 break;
21727             }
21728 
21729             case value_t::number_unsigned:
21730             {
21731                 m_value.number_unsigned = 0;
21732                 break;
21733             }
21734 
21735             case value_t::number_float:
21736             {
21737                 m_value.number_float = 0.0;
21738                 break;
21739             }
21740 
21741             case value_t::boolean:
21742             {
21743                 m_value.boolean = false;
21744                 break;
21745             }
21746 
21747             case value_t::string:
21748             {
21749                 m_value.string->clear();
21750                 break;
21751             }
21752 
21753             case value_t::binary:
21754             {
21755                 m_value.binary->clear();
21756                 break;
21757             }
21758 
21759             case value_t::array:
21760             {
21761                 m_value.array->clear();
21762                 break;
21763             }
21764 
21765             case value_t::object:
21766             {
21767                 m_value.object->clear();
21768                 break;
21769             }
21770 
21771             default:
21772                 break;
21773         }
21774     }
21775 
21776     /*!
21777     @brief add an object to an array
21778 
21779     Appends the given element @a val to the end of the JSON value. If the
21780     function is called on a JSON null value, an empty array is created before
21781     appending @a val.
21782 
21783     @param[in] val the value to add to the JSON array
21784 
21785     @throw type_error.308 when called on a type other than JSON array or
21786     null; example: `"cannot use push_back() with number"`
21787 
21788     @complexity Amortized constant.
21789 
21790     @liveexample{The example shows how `push_back()` and `+=` can be used to
21791     add elements to a JSON array. Note how the `null` value was silently
21792     converted to a JSON array.,push_back}
21793 
21794     @since version 1.0.0
21795     */
push_back(basic_json && val)21796     void push_back(basic_json&& val)
21797     {
21798         // push_back only works for null objects or arrays
21799         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21800         {
21801             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21802         }
21803 
21804         // transform null object into an array
21805         if (is_null())
21806         {
21807             m_type = value_t::array;
21808             m_value = value_t::array;
21809             assert_invariant();
21810         }
21811 
21812         // add element to array (move semantics)
21813         m_value.array->push_back(std::move(val));
21814         // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
21815     }
21816 
21817     /*!
21818     @brief add an object to an array
21819     @copydoc push_back(basic_json&&)
21820     */
operator +=(basic_json && val)21821     reference operator+=(basic_json&& val)
21822     {
21823         push_back(std::move(val));
21824         return *this;
21825     }
21826 
21827     /*!
21828     @brief add an object to an array
21829     @copydoc push_back(basic_json&&)
21830     */
push_back(const basic_json & val)21831     void push_back(const basic_json& val)
21832     {
21833         // push_back only works for null objects or arrays
21834         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21835         {
21836             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21837         }
21838 
21839         // transform null object into an array
21840         if (is_null())
21841         {
21842             m_type = value_t::array;
21843             m_value = value_t::array;
21844             assert_invariant();
21845         }
21846 
21847         // add element to array
21848         m_value.array->push_back(val);
21849     }
21850 
21851     /*!
21852     @brief add an object to an array
21853     @copydoc push_back(basic_json&&)
21854     */
operator +=(const basic_json & val)21855     reference operator+=(const basic_json& val)
21856     {
21857         push_back(val);
21858         return *this;
21859     }
21860 
21861     /*!
21862     @brief add an object to an object
21863 
21864     Inserts the given element @a val to the JSON object. If the function is
21865     called on a JSON null value, an empty object is created before inserting
21866     @a val.
21867 
21868     @param[in] val the value to add to the JSON object
21869 
21870     @throw type_error.308 when called on a type other than JSON object or
21871     null; example: `"cannot use push_back() with number"`
21872 
21873     @complexity Logarithmic in the size of the container, O(log(`size()`)).
21874 
21875     @liveexample{The example shows how `push_back()` and `+=` can be used to
21876     add elements to a JSON object. Note how the `null` value was silently
21877     converted to a JSON object.,push_back__object_t__value}
21878 
21879     @since version 1.0.0
21880     */
push_back(const typename object_t::value_type & val)21881     void push_back(const typename object_t::value_type& val)
21882     {
21883         // push_back only works for null objects or objects
21884         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21885         {
21886             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
21887         }
21888 
21889         // transform null object into an object
21890         if (is_null())
21891         {
21892             m_type = value_t::object;
21893             m_value = value_t::object;
21894             assert_invariant();
21895         }
21896 
21897         // add element to array
21898         m_value.object->insert(val);
21899     }
21900 
21901     /*!
21902     @brief add an object to an object
21903     @copydoc push_back(const typename object_t::value_type&)
21904     */
operator +=(const typename object_t::value_type & val)21905     reference operator+=(const typename object_t::value_type& val)
21906     {
21907         push_back(val);
21908         return *this;
21909     }
21910 
21911     /*!
21912     @brief add an object to an object
21913 
21914     This function allows to use `push_back` with an initializer list. In case
21915 
21916     1. the current value is an object,
21917     2. the initializer list @a init contains only two elements, and
21918     3. the first element of @a init is a string,
21919 
21920     @a init is converted into an object element and added using
21921     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
21922     is converted to a JSON value and added using @ref push_back(basic_json&&).
21923 
21924     @param[in] init  an initializer list
21925 
21926     @complexity Linear in the size of the initializer list @a init.
21927 
21928     @note This function is required to resolve an ambiguous overload error,
21929           because pairs like `{"key", "value"}` can be both interpreted as
21930           `object_t::value_type` or `std::initializer_list<basic_json>`, see
21931           https://github.com/nlohmann/json/issues/235 for more information.
21932 
21933     @liveexample{The example shows how initializer lists are treated as
21934     objects when possible.,push_back__initializer_list}
21935     */
push_back(initializer_list_t init)21936     void push_back(initializer_list_t init)
21937     {
21938         if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21939         {
21940             basic_json&& key = init.begin()->moved_or_copied();
21941             push_back(typename object_t::value_type(
21942                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21943         }
21944         else
21945         {
21946             push_back(basic_json(init));
21947         }
21948     }
21949 
21950     /*!
21951     @brief add an object to an object
21952     @copydoc push_back(initializer_list_t)
21953     */
operator +=(initializer_list_t init)21954     reference operator+=(initializer_list_t init)
21955     {
21956         push_back(init);
21957         return *this;
21958     }
21959 
21960     /*!
21961     @brief add an object to an array
21962 
21963     Creates a JSON value from the passed parameters @a args to the end of the
21964     JSON value. If the function is called on a JSON null value, an empty array
21965     is created before appending the value created from @a args.
21966 
21967     @param[in] args arguments to forward to a constructor of @ref basic_json
21968     @tparam Args compatible types to create a @ref basic_json object
21969 
21970     @return reference to the inserted element
21971 
21972     @throw type_error.311 when called on a type other than JSON array or
21973     null; example: `"cannot use emplace_back() with number"`
21974 
21975     @complexity Amortized constant.
21976 
21977     @liveexample{The example shows how `push_back()` can be used to add
21978     elements to a JSON array. Note how the `null` value was silently converted
21979     to a JSON array.,emplace_back}
21980 
21981     @since version 2.0.8, returns reference since 3.7.0
21982     */
21983     template<class... Args>
emplace_back(Args &&...args)21984     reference emplace_back(Args&& ... args)
21985     {
21986         // emplace_back only works for null objects or arrays
21987         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21988         {
21989             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
21990         }
21991 
21992         // transform null object into an array
21993         if (is_null())
21994         {
21995             m_type = value_t::array;
21996             m_value = value_t::array;
21997             assert_invariant();
21998         }
21999 
22000         // add element to array (perfect forwarding)
22001 #ifdef JSON_HAS_CPP_17
22002         return m_value.array->emplace_back(std::forward<Args>(args)...);
22003 #else
22004         m_value.array->emplace_back(std::forward<Args>(args)...);
22005         return m_value.array->back();
22006 #endif
22007     }
22008 
22009     /*!
22010     @brief add an object to an object if key does not exist
22011 
22012     Inserts a new element into a JSON object constructed in-place with the
22013     given @a args if there is no element with the key in the container. If the
22014     function is called on a JSON null value, an empty object is created before
22015     appending the value created from @a args.
22016 
22017     @param[in] args arguments to forward to a constructor of @ref basic_json
22018     @tparam Args compatible types to create a @ref basic_json object
22019 
22020     @return a pair consisting of an iterator to the inserted element, or the
22021             already-existing element if no insertion happened, and a bool
22022             denoting whether the insertion took place.
22023 
22024     @throw type_error.311 when called on a type other than JSON object or
22025     null; example: `"cannot use emplace() with number"`
22026 
22027     @complexity Logarithmic in the size of the container, O(log(`size()`)).
22028 
22029     @liveexample{The example shows how `emplace()` can be used to add elements
22030     to a JSON object. Note how the `null` value was silently converted to a
22031     JSON object. Further note how no value is added if there was already one
22032     value stored with the same key.,emplace}
22033 
22034     @since version 2.0.8
22035     */
22036     template<class... Args>
emplace(Args &&...args)22037     std::pair<iterator, bool> emplace(Args&& ... args)
22038     {
22039         // emplace only works for null objects or arrays
22040         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22041         {
22042             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
22043         }
22044 
22045         // transform null object into an object
22046         if (is_null())
22047         {
22048             m_type = value_t::object;
22049             m_value = value_t::object;
22050             assert_invariant();
22051         }
22052 
22053         // add element to array (perfect forwarding)
22054         auto res = m_value.object->emplace(std::forward<Args>(args)...);
22055         // create result iterator and set iterator to the result of emplace
22056         auto it = begin();
22057         it.m_it.object_iterator = res.first;
22058 
22059         // return pair of iterator and boolean
22060         return {it, res.second};
22061     }
22062 
22063     /// Helper for insertion of an iterator
22064     /// @note: This uses std::distance to support GCC 4.8,
22065     ///        see https://github.com/nlohmann/json/pull/1257
22066     template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)22067     iterator insert_iterator(const_iterator pos, Args&& ... args)
22068     {
22069         iterator result(this);
22070         JSON_ASSERT(m_value.array != nullptr);
22071 
22072         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
22073         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
22074         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
22075 
22076         // This could have been written as:
22077         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
22078         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
22079 
22080         return result;
22081     }
22082 
22083     /*!
22084     @brief inserts element
22085 
22086     Inserts element @a val before iterator @a pos.
22087 
22088     @param[in] pos iterator before which the content will be inserted; may be
22089     the end() iterator
22090     @param[in] val element to insert
22091     @return iterator pointing to the inserted @a val.
22092 
22093     @throw type_error.309 if called on JSON values other than arrays;
22094     example: `"cannot use insert() with string"`
22095     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22096     example: `"iterator does not fit current value"`
22097 
22098     @complexity Constant plus linear in the distance between @a pos and end of
22099     the container.
22100 
22101     @liveexample{The example shows how `insert()` is used.,insert}
22102 
22103     @since version 1.0.0
22104     */
insert(const_iterator pos,const basic_json & val)22105     iterator insert(const_iterator pos, const basic_json& val)
22106     {
22107         // insert only works for arrays
22108         if (JSON_HEDLEY_LIKELY(is_array()))
22109         {
22110             // check if iterator pos fits to this JSON value
22111             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22112             {
22113                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22114             }
22115 
22116             // insert to array and return iterator
22117             return insert_iterator(pos, val);
22118         }
22119 
22120         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22121     }
22122 
22123     /*!
22124     @brief inserts element
22125     @copydoc insert(const_iterator, const basic_json&)
22126     */
insert(const_iterator pos,basic_json && val)22127     iterator insert(const_iterator pos, basic_json&& val)
22128     {
22129         return insert(pos, val);
22130     }
22131 
22132     /*!
22133     @brief inserts elements
22134 
22135     Inserts @a cnt copies of @a val before iterator @a pos.
22136 
22137     @param[in] pos iterator before which the content will be inserted; may be
22138     the end() iterator
22139     @param[in] cnt number of copies of @a val to insert
22140     @param[in] val element to insert
22141     @return iterator pointing to the first element inserted, or @a pos if
22142     `cnt==0`
22143 
22144     @throw type_error.309 if called on JSON values other than arrays; example:
22145     `"cannot use insert() with string"`
22146     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22147     example: `"iterator does not fit current value"`
22148 
22149     @complexity Linear in @a cnt plus linear in the distance between @a pos
22150     and end of the container.
22151 
22152     @liveexample{The example shows how `insert()` is used.,insert__count}
22153 
22154     @since version 1.0.0
22155     */
insert(const_iterator pos,size_type cnt,const basic_json & val)22156     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
22157     {
22158         // insert only works for arrays
22159         if (JSON_HEDLEY_LIKELY(is_array()))
22160         {
22161             // check if iterator pos fits to this JSON value
22162             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22163             {
22164                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22165             }
22166 
22167             // insert to array and return iterator
22168             return insert_iterator(pos, cnt, val);
22169         }
22170 
22171         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22172     }
22173 
22174     /*!
22175     @brief inserts elements
22176 
22177     Inserts elements from range `[first, last)` before iterator @a pos.
22178 
22179     @param[in] pos iterator before which the content will be inserted; may be
22180     the end() iterator
22181     @param[in] first begin of the range of elements to insert
22182     @param[in] last end of the range of elements to insert
22183 
22184     @throw type_error.309 if called on JSON values other than arrays; example:
22185     `"cannot use insert() with string"`
22186     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22187     example: `"iterator does not fit current value"`
22188     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22189     same JSON value; example: `"iterators do not fit"`
22190     @throw invalid_iterator.211 if @a first or @a last are iterators into
22191     container for which insert is called; example: `"passed iterators may not
22192     belong to container"`
22193 
22194     @return iterator pointing to the first element inserted, or @a pos if
22195     `first==last`
22196 
22197     @complexity Linear in `std::distance(first, last)` plus linear in the
22198     distance between @a pos and end of the container.
22199 
22200     @liveexample{The example shows how `insert()` is used.,insert__range}
22201 
22202     @since version 1.0.0
22203     */
insert(const_iterator pos,const_iterator first,const_iterator last)22204     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
22205     {
22206         // insert only works for arrays
22207         if (JSON_HEDLEY_UNLIKELY(!is_array()))
22208         {
22209             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22210         }
22211 
22212         // check if iterator pos fits to this JSON value
22213         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22214         {
22215             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22216         }
22217 
22218         // check if range iterators belong to the same JSON object
22219         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22220         {
22221             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22222         }
22223 
22224         if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
22225         {
22226             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
22227         }
22228 
22229         // insert to array and return iterator
22230         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
22231     }
22232 
22233     /*!
22234     @brief inserts elements
22235 
22236     Inserts elements from initializer list @a ilist before iterator @a pos.
22237 
22238     @param[in] pos iterator before which the content will be inserted; may be
22239     the end() iterator
22240     @param[in] ilist initializer list to insert the values from
22241 
22242     @throw type_error.309 if called on JSON values other than arrays; example:
22243     `"cannot use insert() with string"`
22244     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
22245     example: `"iterator does not fit current value"`
22246 
22247     @return iterator pointing to the first element inserted, or @a pos if
22248     `ilist` is empty
22249 
22250     @complexity Linear in `ilist.size()` plus linear in the distance between
22251     @a pos and end of the container.
22252 
22253     @liveexample{The example shows how `insert()` is used.,insert__ilist}
22254 
22255     @since version 1.0.0
22256     */
insert(const_iterator pos,initializer_list_t ilist)22257     iterator insert(const_iterator pos, initializer_list_t ilist)
22258     {
22259         // insert only works for arrays
22260         if (JSON_HEDLEY_UNLIKELY(!is_array()))
22261         {
22262             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22263         }
22264 
22265         // check if iterator pos fits to this JSON value
22266         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
22267         {
22268             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
22269         }
22270 
22271         // insert to array and return iterator
22272         return insert_iterator(pos, ilist.begin(), ilist.end());
22273     }
22274 
22275     /*!
22276     @brief inserts elements
22277 
22278     Inserts elements from range `[first, last)`.
22279 
22280     @param[in] first begin of the range of elements to insert
22281     @param[in] last end of the range of elements to insert
22282 
22283     @throw type_error.309 if called on JSON values other than objects; example:
22284     `"cannot use insert() with string"`
22285     @throw invalid_iterator.202 if iterator @a first or @a last does does not
22286     point to an object; example: `"iterators first and last must point to
22287     objects"`
22288     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22289     same JSON value; example: `"iterators do not fit"`
22290 
22291     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
22292     of elements to insert.
22293 
22294     @liveexample{The example shows how `insert()` is used.,insert__range_object}
22295 
22296     @since version 3.0.0
22297     */
insert(const_iterator first,const_iterator last)22298     void insert(const_iterator first, const_iterator last)
22299     {
22300         // insert only works for objects
22301         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22302         {
22303             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
22304         }
22305 
22306         // check if range iterators belong to the same JSON object
22307         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22308         {
22309             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22310         }
22311 
22312         // passed iterators must belong to objects
22313         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
22314         {
22315             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22316         }
22317 
22318         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
22319     }
22320 
22321     /*!
22322     @brief updates a JSON object from another object, overwriting existing keys
22323 
22324     Inserts all values from JSON object @a j and overwrites existing keys.
22325 
22326     @param[in] j  JSON object to read values from
22327 
22328     @throw type_error.312 if called on JSON values other than objects; example:
22329     `"cannot use update() with string"`
22330 
22331     @complexity O(N*log(size() + N)), where N is the number of elements to
22332                 insert.
22333 
22334     @liveexample{The example shows how `update()` is used.,update}
22335 
22336     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22337 
22338     @since version 3.0.0
22339     */
update(const_reference j)22340     void update(const_reference j)
22341     {
22342         // implicitly convert null value to an empty object
22343         if (is_null())
22344         {
22345             m_type = value_t::object;
22346             m_value.object = create<object_t>();
22347             assert_invariant();
22348         }
22349 
22350         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22351         {
22352             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22353         }
22354         if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
22355         {
22356             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
22357         }
22358 
22359         for (auto it = j.cbegin(); it != j.cend(); ++it)
22360         {
22361             m_value.object->operator[](it.key()) = it.value();
22362         }
22363     }
22364 
22365     /*!
22366     @brief updates a JSON object from another object, overwriting existing keys
22367 
22368     Inserts all values from from range `[first, last)` and overwrites existing
22369     keys.
22370 
22371     @param[in] first begin of the range of elements to insert
22372     @param[in] last end of the range of elements to insert
22373 
22374     @throw type_error.312 if called on JSON values other than objects; example:
22375     `"cannot use update() with string"`
22376     @throw invalid_iterator.202 if iterator @a first or @a last does does not
22377     point to an object; example: `"iterators first and last must point to
22378     objects"`
22379     @throw invalid_iterator.210 if @a first and @a last do not belong to the
22380     same JSON value; example: `"iterators do not fit"`
22381 
22382     @complexity O(N*log(size() + N)), where N is the number of elements to
22383                 insert.
22384 
22385     @liveexample{The example shows how `update()` is used__range.,update}
22386 
22387     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
22388 
22389     @since version 3.0.0
22390     */
update(const_iterator first,const_iterator last)22391     void update(const_iterator first, const_iterator last)
22392     {
22393         // implicitly convert null value to an empty object
22394         if (is_null())
22395         {
22396             m_type = value_t::object;
22397             m_value.object = create<object_t>();
22398             assert_invariant();
22399         }
22400 
22401         if (JSON_HEDLEY_UNLIKELY(!is_object()))
22402         {
22403             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
22404         }
22405 
22406         // check if range iterators belong to the same JSON object
22407         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
22408         {
22409             JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
22410         }
22411 
22412         // passed iterators must belong to objects
22413         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
22414                                  || !last.m_object->is_object()))
22415         {
22416             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
22417         }
22418 
22419         for (auto it = first; it != last; ++it)
22420         {
22421             m_value.object->operator[](it.key()) = it.value();
22422         }
22423     }
22424 
22425     /*!
22426     @brief exchanges the values
22427 
22428     Exchanges the contents of the JSON value with those of @a other. Does not
22429     invoke any move, copy, or swap operations on individual elements. All
22430     iterators and references remain valid. The past-the-end iterator is
22431     invalidated.
22432 
22433     @param[in,out] other JSON value to exchange the contents with
22434 
22435     @complexity Constant.
22436 
22437     @liveexample{The example below shows how JSON values can be swapped with
22438     `swap()`.,swap__reference}
22439 
22440     @since version 1.0.0
22441     */
swap(reference other)22442     void swap(reference other) noexcept (
22443         std::is_nothrow_move_constructible<value_t>::value&&
22444         std::is_nothrow_move_assignable<value_t>::value&&
22445         std::is_nothrow_move_constructible<json_value>::value&&
22446         std::is_nothrow_move_assignable<json_value>::value
22447     )
22448     {
22449         std::swap(m_type, other.m_type);
22450         std::swap(m_value, other.m_value);
22451         assert_invariant();
22452     }
22453 
22454     /*!
22455     @brief exchanges the values
22456 
22457     Exchanges the contents of the JSON value from @a left with those of @a right. Does not
22458     invoke any move, copy, or swap operations on individual elements. All
22459     iterators and references remain valid. The past-the-end iterator is
22460     invalidated. implemented as a friend function callable via ADL.
22461 
22462     @param[in,out] left JSON value to exchange the contents with
22463     @param[in,out] right JSON value to exchange the contents with
22464 
22465     @complexity Constant.
22466 
22467     @liveexample{The example below shows how JSON values can be swapped with
22468     `swap()`.,swap__reference}
22469 
22470     @since version 1.0.0
22471     */
swap(reference left,reference right)22472     friend void swap(reference left, reference right) noexcept (
22473         std::is_nothrow_move_constructible<value_t>::value&&
22474         std::is_nothrow_move_assignable<value_t>::value&&
22475         std::is_nothrow_move_constructible<json_value>::value&&
22476         std::is_nothrow_move_assignable<json_value>::value
22477     )
22478     {
22479         left.swap(right);
22480     }
22481 
22482     /*!
22483     @brief exchanges the values
22484 
22485     Exchanges the contents of a JSON array with those of @a other. Does not
22486     invoke any move, copy, or swap operations on individual elements. All
22487     iterators and references remain valid. The past-the-end iterator is
22488     invalidated.
22489 
22490     @param[in,out] other array to exchange the contents with
22491 
22492     @throw type_error.310 when JSON value is not an array; example: `"cannot
22493     use swap() with string"`
22494 
22495     @complexity Constant.
22496 
22497     @liveexample{The example below shows how arrays can be swapped with
22498     `swap()`.,swap__array_t}
22499 
22500     @since version 1.0.0
22501     */
swap(array_t & other)22502     void swap(array_t& other)
22503     {
22504         // swap only works for arrays
22505         if (JSON_HEDLEY_LIKELY(is_array()))
22506         {
22507             std::swap(*(m_value.array), other);
22508         }
22509         else
22510         {
22511             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22512         }
22513     }
22514 
22515     /*!
22516     @brief exchanges the values
22517 
22518     Exchanges the contents of a JSON object with those of @a other. Does not
22519     invoke any move, copy, or swap operations on individual elements. All
22520     iterators and references remain valid. The past-the-end iterator is
22521     invalidated.
22522 
22523     @param[in,out] other object to exchange the contents with
22524 
22525     @throw type_error.310 when JSON value is not an object; example:
22526     `"cannot use swap() with string"`
22527 
22528     @complexity Constant.
22529 
22530     @liveexample{The example below shows how objects can be swapped with
22531     `swap()`.,swap__object_t}
22532 
22533     @since version 1.0.0
22534     */
swap(object_t & other)22535     void swap(object_t& other)
22536     {
22537         // swap only works for objects
22538         if (JSON_HEDLEY_LIKELY(is_object()))
22539         {
22540             std::swap(*(m_value.object), other);
22541         }
22542         else
22543         {
22544             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22545         }
22546     }
22547 
22548     /*!
22549     @brief exchanges the values
22550 
22551     Exchanges the contents of a JSON string with those of @a other. Does not
22552     invoke any move, copy, or swap operations on individual elements. All
22553     iterators and references remain valid. The past-the-end iterator is
22554     invalidated.
22555 
22556     @param[in,out] other string to exchange the contents with
22557 
22558     @throw type_error.310 when JSON value is not a string; example: `"cannot
22559     use swap() with boolean"`
22560 
22561     @complexity Constant.
22562 
22563     @liveexample{The example below shows how strings can be swapped with
22564     `swap()`.,swap__string_t}
22565 
22566     @since version 1.0.0
22567     */
swap(string_t & other)22568     void swap(string_t& other)
22569     {
22570         // swap only works for strings
22571         if (JSON_HEDLEY_LIKELY(is_string()))
22572         {
22573             std::swap(*(m_value.string), other);
22574         }
22575         else
22576         {
22577             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22578         }
22579     }
22580 
22581     /*!
22582     @brief exchanges the values
22583 
22584     Exchanges the contents of a JSON string with those of @a other. Does not
22585     invoke any move, copy, or swap operations on individual elements. All
22586     iterators and references remain valid. The past-the-end iterator is
22587     invalidated.
22588 
22589     @param[in,out] other binary to exchange the contents with
22590 
22591     @throw type_error.310 when JSON value is not a string; example: `"cannot
22592     use swap() with boolean"`
22593 
22594     @complexity Constant.
22595 
22596     @liveexample{The example below shows how strings can be swapped with
22597     `swap()`.,swap__binary_t}
22598 
22599     @since version 3.8.0
22600     */
swap(binary_t & other)22601     void swap(binary_t& other)
22602     {
22603         // swap only works for strings
22604         if (JSON_HEDLEY_LIKELY(is_binary()))
22605         {
22606             std::swap(*(m_value.binary), other);
22607         }
22608         else
22609         {
22610             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22611         }
22612     }
22613 
22614     /// @copydoc swap(binary_t)
swap(typename binary_t::container_type & other)22615     void swap(typename binary_t::container_type& other)
22616     {
22617         // swap only works for strings
22618         if (JSON_HEDLEY_LIKELY(is_binary()))
22619         {
22620             std::swap(*(m_value.binary), other);
22621         }
22622         else
22623         {
22624             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
22625         }
22626     }
22627 
22628     /// @}
22629 
22630   public:
22631     //////////////////////////////////////////
22632     // lexicographical comparison operators //
22633     //////////////////////////////////////////
22634 
22635     /// @name lexicographical comparison operators
22636     /// @{
22637 
22638     /*!
22639     @brief comparison: equal
22640 
22641     Compares two JSON values for equality according to the following rules:
22642     - Two JSON values are equal if (1) they are from the same type and (2)
22643       their stored values are the same according to their respective
22644       `operator==`.
22645     - Integer and floating-point numbers are automatically converted before
22646       comparison. Note that two NaN values are always treated as unequal.
22647     - Two JSON null values are equal.
22648 
22649     @note Floating-point inside JSON values numbers are compared with
22650     `json::number_float_t::operator==` which is `double::operator==` by
22651     default. To compare floating-point while respecting an epsilon, an alternative
22652     [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
22653     could be used, for instance
22654     @code {.cpp}
22655     template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
22656     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
22657     {
22658         return std::abs(a - b) <= epsilon;
22659     }
22660     @endcode
22661     Or you can self-defined operator equal function like this:
22662     @code {.cpp}
22663     bool my_equal(const_reference lhs, const_reference rhs) {
22664     const auto lhs_type lhs.type();
22665     const auto rhs_type rhs.type();
22666     if (lhs_type == rhs_type) {
22667         switch(lhs_type)
22668             // self_defined case
22669             case value_t::number_float:
22670                 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
22671             // other cases remain the same with the original
22672             ...
22673     }
22674     ...
22675     }
22676     @endcode
22677 
22678     @note NaN values never compare equal to themselves or to other NaN values.
22679 
22680     @param[in] lhs  first JSON value to consider
22681     @param[in] rhs  second JSON value to consider
22682     @return whether the values @a lhs and @a rhs are equal
22683 
22684     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22685 
22686     @complexity Linear.
22687 
22688     @liveexample{The example demonstrates comparing several JSON
22689     types.,operator__equal}
22690 
22691     @since version 1.0.0
22692     */
operator ==(const_reference lhs,const_reference rhs)22693     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22694     {
22695         const auto lhs_type = lhs.type();
22696         const auto rhs_type = rhs.type();
22697 
22698         if (lhs_type == rhs_type)
22699         {
22700             switch (lhs_type)
22701             {
22702                 case value_t::array:
22703                     return *lhs.m_value.array == *rhs.m_value.array;
22704 
22705                 case value_t::object:
22706                     return *lhs.m_value.object == *rhs.m_value.object;
22707 
22708                 case value_t::null:
22709                     return true;
22710 
22711                 case value_t::string:
22712                     return *lhs.m_value.string == *rhs.m_value.string;
22713 
22714                 case value_t::boolean:
22715                     return lhs.m_value.boolean == rhs.m_value.boolean;
22716 
22717                 case value_t::number_integer:
22718                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
22719 
22720                 case value_t::number_unsigned:
22721                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
22722 
22723                 case value_t::number_float:
22724                     return lhs.m_value.number_float == rhs.m_value.number_float;
22725 
22726                 case value_t::binary:
22727                     return *lhs.m_value.binary == *rhs.m_value.binary;
22728 
22729                 default:
22730                     return false;
22731             }
22732         }
22733         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22734         {
22735             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
22736         }
22737         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22738         {
22739             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
22740         }
22741         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22742         {
22743             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
22744         }
22745         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22746         {
22747             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
22748         }
22749         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22750         {
22751             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
22752         }
22753         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22754         {
22755             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22756         }
22757 
22758         return false;
22759     }
22760 
22761     /*!
22762     @brief comparison: equal
22763     @copydoc operator==(const_reference, const_reference)
22764     */
22765     template<typename ScalarType, typename std::enable_if<
22766                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)22767     friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
22768     {
22769         return lhs == basic_json(rhs);
22770     }
22771 
22772     /*!
22773     @brief comparison: equal
22774     @copydoc operator==(const_reference, const_reference)
22775     */
22776     template<typename ScalarType, typename std::enable_if<
22777                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)22778     friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
22779     {
22780         return basic_json(lhs) == rhs;
22781     }
22782 
22783     /*!
22784     @brief comparison: not equal
22785 
22786     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
22787 
22788     @param[in] lhs  first JSON value to consider
22789     @param[in] rhs  second JSON value to consider
22790     @return whether the values @a lhs and @a rhs are not equal
22791 
22792     @complexity Linear.
22793 
22794     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22795 
22796     @liveexample{The example demonstrates comparing several JSON
22797     types.,operator__notequal}
22798 
22799     @since version 1.0.0
22800     */
operator !=(const_reference lhs,const_reference rhs)22801     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22802     {
22803         return !(lhs == rhs);
22804     }
22805 
22806     /*!
22807     @brief comparison: not equal
22808     @copydoc operator!=(const_reference, const_reference)
22809     */
22810     template<typename ScalarType, typename std::enable_if<
22811                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)22812     friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
22813     {
22814         return lhs != basic_json(rhs);
22815     }
22816 
22817     /*!
22818     @brief comparison: not equal
22819     @copydoc operator!=(const_reference, const_reference)
22820     */
22821     template<typename ScalarType, typename std::enable_if<
22822                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)22823     friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
22824     {
22825         return basic_json(lhs) != rhs;
22826     }
22827 
22828     /*!
22829     @brief comparison: less than
22830 
22831     Compares whether one JSON value @a lhs is less than another JSON value @a
22832     rhs according to the following rules:
22833     - If @a lhs and @a rhs have the same type, the values are compared using
22834       the default `<` operator.
22835     - Integer and floating-point numbers are automatically converted before
22836       comparison
22837     - In case @a lhs and @a rhs have different types, the values are ignored
22838       and the order of the types is considered, see
22839       @ref operator<(const value_t, const value_t).
22840 
22841     @param[in] lhs  first JSON value to consider
22842     @param[in] rhs  second JSON value to consider
22843     @return whether @a lhs is less than @a rhs
22844 
22845     @complexity Linear.
22846 
22847     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22848 
22849     @liveexample{The example demonstrates comparing several JSON
22850     types.,operator__less}
22851 
22852     @since version 1.0.0
22853     */
operator <(const_reference lhs,const_reference rhs)22854     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22855     {
22856         const auto lhs_type = lhs.type();
22857         const auto rhs_type = rhs.type();
22858 
22859         if (lhs_type == rhs_type)
22860         {
22861             switch (lhs_type)
22862             {
22863                 case value_t::array:
22864                     // note parentheses are necessary, see
22865                     // https://github.com/nlohmann/json/issues/1530
22866                     return (*lhs.m_value.array) < (*rhs.m_value.array);
22867 
22868                 case value_t::object:
22869                     return (*lhs.m_value.object) < (*rhs.m_value.object);
22870 
22871                 case value_t::null:
22872                     return false;
22873 
22874                 case value_t::string:
22875                     return (*lhs.m_value.string) < (*rhs.m_value.string);
22876 
22877                 case value_t::boolean:
22878                     return (lhs.m_value.boolean) < (rhs.m_value.boolean);
22879 
22880                 case value_t::number_integer:
22881                     return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
22882 
22883                 case value_t::number_unsigned:
22884                     return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
22885 
22886                 case value_t::number_float:
22887                     return (lhs.m_value.number_float) < (rhs.m_value.number_float);
22888 
22889                 case value_t::binary:
22890                     return (*lhs.m_value.binary) < (*rhs.m_value.binary);
22891 
22892                 default:
22893                     return false;
22894             }
22895         }
22896         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
22897         {
22898             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
22899         }
22900         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
22901         {
22902             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
22903         }
22904         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
22905         {
22906             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
22907         }
22908         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
22909         {
22910             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
22911         }
22912         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
22913         {
22914             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
22915         }
22916         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
22917         {
22918             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
22919         }
22920 
22921         // We only reach this line if we cannot compare values. In that case,
22922         // we compare types. Note we have to call the operator explicitly,
22923         // because MSVC has problems otherwise.
22924         return operator<(lhs_type, rhs_type);
22925     }
22926 
22927     /*!
22928     @brief comparison: less than
22929     @copydoc operator<(const_reference, const_reference)
22930     */
22931     template<typename ScalarType, typename std::enable_if<
22932                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)22933     friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
22934     {
22935         return lhs < basic_json(rhs);
22936     }
22937 
22938     /*!
22939     @brief comparison: less than
22940     @copydoc operator<(const_reference, const_reference)
22941     */
22942     template<typename ScalarType, typename std::enable_if<
22943                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)22944     friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
22945     {
22946         return basic_json(lhs) < rhs;
22947     }
22948 
22949     /*!
22950     @brief comparison: less than or equal
22951 
22952     Compares whether one JSON value @a lhs is less than or equal to another
22953     JSON value by calculating `not (rhs < lhs)`.
22954 
22955     @param[in] lhs  first JSON value to consider
22956     @param[in] rhs  second JSON value to consider
22957     @return whether @a lhs is less than or equal to @a rhs
22958 
22959     @complexity Linear.
22960 
22961     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22962 
22963     @liveexample{The example demonstrates comparing several JSON
22964     types.,operator__greater}
22965 
22966     @since version 1.0.0
22967     */
operator <=(const_reference lhs,const_reference rhs)22968     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22969     {
22970         return !(rhs < lhs);
22971     }
22972 
22973     /*!
22974     @brief comparison: less than or equal
22975     @copydoc operator<=(const_reference, const_reference)
22976     */
22977     template<typename ScalarType, typename std::enable_if<
22978                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)22979     friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
22980     {
22981         return lhs <= basic_json(rhs);
22982     }
22983 
22984     /*!
22985     @brief comparison: less than or equal
22986     @copydoc operator<=(const_reference, const_reference)
22987     */
22988     template<typename ScalarType, typename std::enable_if<
22989                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)22990     friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
22991     {
22992         return basic_json(lhs) <= rhs;
22993     }
22994 
22995     /*!
22996     @brief comparison: greater than
22997 
22998     Compares whether one JSON value @a lhs is greater than another
22999     JSON value by calculating `not (lhs <= rhs)`.
23000 
23001     @param[in] lhs  first JSON value to consider
23002     @param[in] rhs  second JSON value to consider
23003     @return whether @a lhs is greater than to @a rhs
23004 
23005     @complexity Linear.
23006 
23007     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23008 
23009     @liveexample{The example demonstrates comparing several JSON
23010     types.,operator__lessequal}
23011 
23012     @since version 1.0.0
23013     */
operator >(const_reference lhs,const_reference rhs)23014     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
23015     {
23016         return !(lhs <= rhs);
23017     }
23018 
23019     /*!
23020     @brief comparison: greater than
23021     @copydoc operator>(const_reference, const_reference)
23022     */
23023     template<typename ScalarType, typename std::enable_if<
23024                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)23025     friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
23026     {
23027         return lhs > basic_json(rhs);
23028     }
23029 
23030     /*!
23031     @brief comparison: greater than
23032     @copydoc operator>(const_reference, const_reference)
23033     */
23034     template<typename ScalarType, typename std::enable_if<
23035                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)23036     friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
23037     {
23038         return basic_json(lhs) > rhs;
23039     }
23040 
23041     /*!
23042     @brief comparison: greater than or equal
23043 
23044     Compares whether one JSON value @a lhs is greater than or equal to another
23045     JSON value by calculating `not (lhs < rhs)`.
23046 
23047     @param[in] lhs  first JSON value to consider
23048     @param[in] rhs  second JSON value to consider
23049     @return whether @a lhs is greater than or equal to @a rhs
23050 
23051     @complexity Linear.
23052 
23053     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23054 
23055     @liveexample{The example demonstrates comparing several JSON
23056     types.,operator__greaterequal}
23057 
23058     @since version 1.0.0
23059     */
operator >=(const_reference lhs,const_reference rhs)23060     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
23061     {
23062         return !(lhs < rhs);
23063     }
23064 
23065     /*!
23066     @brief comparison: greater than or equal
23067     @copydoc operator>=(const_reference, const_reference)
23068     */
23069     template<typename ScalarType, typename std::enable_if<
23070                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)23071     friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
23072     {
23073         return lhs >= basic_json(rhs);
23074     }
23075 
23076     /*!
23077     @brief comparison: greater than or equal
23078     @copydoc operator>=(const_reference, const_reference)
23079     */
23080     template<typename ScalarType, typename std::enable_if<
23081                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)23082     friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
23083     {
23084         return basic_json(lhs) >= rhs;
23085     }
23086 
23087     /// @}
23088 
23089     ///////////////////
23090     // serialization //
23091     ///////////////////
23092 
23093     /// @name serialization
23094     /// @{
23095 
23096     /*!
23097     @brief serialize to stream
23098 
23099     Serialize the given JSON value @a j to the output stream @a o. The JSON
23100     value will be serialized using the @ref dump member function.
23101 
23102     - The indentation of the output can be controlled with the member variable
23103       `width` of the output stream @a o. For instance, using the manipulator
23104       `std::setw(4)` on @a o sets the indentation level to `4` and the
23105       serialization result is the same as calling `dump(4)`.
23106 
23107     - The indentation character can be controlled with the member variable
23108       `fill` of the output stream @a o. For instance, the manipulator
23109       `std::setfill('\\t')` sets indentation to use a tab character rather than
23110       the default space character.
23111 
23112     @param[in,out] o  stream to serialize to
23113     @param[in] j  JSON value to serialize
23114 
23115     @return the stream @a o
23116 
23117     @throw type_error.316 if a string stored inside the JSON value is not
23118                           UTF-8 encoded
23119 
23120     @complexity Linear.
23121 
23122     @liveexample{The example below shows the serialization with different
23123     parameters to `width` to adjust the indentation level.,operator_serialize}
23124 
23125     @since version 1.0.0; indentation character added in version 3.0.0
23126     */
operator <<(std::ostream & o,const basic_json & j)23127     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
23128     {
23129         // read width member and use it as indentation parameter if nonzero
23130         const bool pretty_print = o.width() > 0;
23131         const auto indentation = pretty_print ? o.width() : 0;
23132 
23133         // reset width to 0 for subsequent calls to this stream
23134         o.width(0);
23135 
23136         // do the actual serialization
23137         serializer s(detail::output_adapter<char>(o), o.fill());
23138         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
23139         return o;
23140     }
23141 
23142     /*!
23143     @brief serialize to stream
23144     @deprecated This stream operator is deprecated and will be removed in
23145                 future 4.0.0 of the library. Please use
23146                 @ref operator<<(std::ostream&, const basic_json&)
23147                 instead; that is, replace calls like `j >> o;` with `o << j;`.
23148     @since version 1.0.0; deprecated since version 3.0.0
23149     */
23150     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
operator >>(const basic_json & j,std::ostream & o)23151     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
23152     {
23153         return o << j;
23154     }
23155 
23156     /// @}
23157 
23158 
23159     /////////////////////
23160     // deserialization //
23161     /////////////////////
23162 
23163     /// @name deserialization
23164     /// @{
23165 
23166     /*!
23167     @brief deserialize from a compatible input
23168 
23169     @tparam InputType A compatible input, for instance
23170     - an std::istream object
23171     - a FILE pointer
23172     - a C-style array of characters
23173     - a pointer to a null-terminated string of single byte characters
23174     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23175       iterators.
23176 
23177     @param[in] i  input to read from
23178     @param[in] cb  a parser callback function of type @ref parser_callback_t
23179     which is used to control the deserialization by filtering unwanted values
23180     (optional)
23181     @param[in] allow_exceptions  whether to throw exceptions in case of a
23182     parse error (optional, true by default)
23183     @param[in] ignore_comments  whether comments should be ignored and treated
23184     like whitespace (true) or yield a parse error (true); (optional, false by
23185     default)
23186 
23187     @return deserialized JSON value; in case of a parse error and
23188             @a allow_exceptions set to `false`, the return value will be
23189             value_t::discarded.
23190 
23191     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23192     of input; expected string literal""`
23193     @throw parse_error.102 if to_unicode fails or surrogate error
23194     @throw parse_error.103 if to_unicode fails
23195 
23196     @complexity Linear in the length of the input. The parser is a predictive
23197     LL(1) parser. The complexity can be higher if the parser callback function
23198     @a cb or reading from the input @a i has a super-linear complexity.
23199 
23200     @note A UTF-8 byte order mark is silently ignored.
23201 
23202     @liveexample{The example below demonstrates the `parse()` function reading
23203     from an array.,parse__array__parser_callback_t}
23204 
23205     @liveexample{The example below demonstrates the `parse()` function with
23206     and without callback function.,parse__string__parser_callback_t}
23207 
23208     @liveexample{The example below demonstrates the `parse()` function with
23209     and without callback function.,parse__istream__parser_callback_t}
23210 
23211     @liveexample{The example below demonstrates the `parse()` function reading
23212     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
23213 
23214     @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
23215     ignore comments.
23216     */
23217     template<typename InputType>
23218     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(InputType && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)23219     static basic_json parse(InputType&& i,
23220                             const parser_callback_t cb = nullptr,
23221                             const bool allow_exceptions = true,
23222                             const bool ignore_comments = false)
23223     {
23224         basic_json result;
23225         parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
23226         return result;
23227     }
23228 
23229     /*!
23230     @brief deserialize from a pair of character iterators
23231 
23232     The value_type of the iterator must be a integral type with size of 1, 2 or
23233     4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
23234 
23235     @param[in] first iterator to start of character range
23236     @param[in] last  iterator to end of character range
23237     @param[in] cb  a parser callback function of type @ref parser_callback_t
23238     which is used to control the deserialization by filtering unwanted values
23239     (optional)
23240     @param[in] allow_exceptions  whether to throw exceptions in case of a
23241     parse error (optional, true by default)
23242     @param[in] ignore_comments  whether comments should be ignored and treated
23243     like whitespace (true) or yield a parse error (true); (optional, false by
23244     default)
23245 
23246     @return deserialized JSON value; in case of a parse error and
23247             @a allow_exceptions set to `false`, the return value will be
23248             value_t::discarded.
23249 
23250     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23251     of input; expected string literal""`
23252     @throw parse_error.102 if to_unicode fails or surrogate error
23253     @throw parse_error.103 if to_unicode fails
23254     */
23255     template<typename IteratorType>
23256     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)23257     static basic_json parse(IteratorType first,
23258                             IteratorType last,
23259                             const parser_callback_t cb = nullptr,
23260                             const bool allow_exceptions = true,
23261                             const bool ignore_comments = false)
23262     {
23263         basic_json result;
23264         parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
23265         return result;
23266     }
23267 
23268     JSON_HEDLEY_WARN_UNUSED_RESULT
23269     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)23270     static basic_json parse(detail::span_input_adapter&& i,
23271                             const parser_callback_t cb = nullptr,
23272                             const bool allow_exceptions = true,
23273                             const bool ignore_comments = false)
23274     {
23275         basic_json result;
23276         parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
23277         return result;
23278     }
23279 
23280     /*!
23281     @brief check if the input is valid JSON
23282 
23283     Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
23284     function, this function neither throws an exception in case of invalid JSON
23285     input (i.e., a parse error) nor creates diagnostic information.
23286 
23287     @tparam InputType A compatible input, for instance
23288     - an std::istream object
23289     - a FILE pointer
23290     - a C-style array of characters
23291     - a pointer to a null-terminated string of single byte characters
23292     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23293       iterators.
23294 
23295     @param[in] i input to read from
23296     @param[in] ignore_comments  whether comments should be ignored and treated
23297     like whitespace (true) or yield a parse error (true); (optional, false by
23298     default)
23299 
23300     @return Whether the input read from @a i is valid JSON.
23301 
23302     @complexity Linear in the length of the input. The parser is a predictive
23303     LL(1) parser.
23304 
23305     @note A UTF-8 byte order mark is silently ignored.
23306 
23307     @liveexample{The example below demonstrates the `accept()` function reading
23308     from a string.,accept__string}
23309     */
23310     template<typename InputType>
accept(InputType && i,const bool ignore_comments=false)23311     static bool accept(InputType&& i,
23312                        const bool ignore_comments = false)
23313     {
23314         return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
23315     }
23316 
23317     template<typename IteratorType>
accept(IteratorType first,IteratorType last,const bool ignore_comments=false)23318     static bool accept(IteratorType first, IteratorType last,
23319                        const bool ignore_comments = false)
23320     {
23321         return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
23322     }
23323 
23324     JSON_HEDLEY_WARN_UNUSED_RESULT
23325     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
accept(detail::span_input_adapter && i,const bool ignore_comments=false)23326     static bool accept(detail::span_input_adapter&& i,
23327                        const bool ignore_comments = false)
23328     {
23329         return parser(i.get(), nullptr, false, ignore_comments).accept(true);
23330     }
23331 
23332     /*!
23333     @brief generate SAX events
23334 
23335     The SAX event lister must follow the interface of @ref json_sax.
23336 
23337     This function reads from a compatible input. Examples are:
23338     - an std::istream object
23339     - a FILE pointer
23340     - a C-style array of characters
23341     - a pointer to a null-terminated string of single byte characters
23342     - an object obj for which begin(obj) and end(obj) produces a valid pair of
23343       iterators.
23344 
23345     @param[in] i  input to read from
23346     @param[in,out] sax  SAX event listener
23347     @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
23348     @param[in] strict  whether the input has to be consumed completely
23349     @param[in] ignore_comments  whether comments should be ignored and treated
23350     like whitespace (true) or yield a parse error (true); (optional, false by
23351     default); only applies to the JSON file format.
23352 
23353     @return return value of the last processed SAX event
23354 
23355     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
23356     of input; expected string literal""`
23357     @throw parse_error.102 if to_unicode fails or surrogate error
23358     @throw parse_error.103 if to_unicode fails
23359 
23360     @complexity Linear in the length of the input. The parser is a predictive
23361     LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
23362     a super-linear complexity.
23363 
23364     @note A UTF-8 byte order mark is silently ignored.
23365 
23366     @liveexample{The example below demonstrates the `sax_parse()` function
23367     reading from string and processing the events with a user-defined SAX
23368     event consumer.,sax_parse}
23369 
23370     @since version 3.2.0
23371     */
23372     template <typename InputType, typename SAX>
23373     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)23374     static bool sax_parse(InputType&& i, SAX* sax,
23375                           input_format_t format = input_format_t::json,
23376                           const bool strict = true,
23377                           const bool ignore_comments = false)
23378     {
23379         auto ia = detail::input_adapter(std::forward<InputType>(i));
23380         return format == input_format_t::json
23381                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23382                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23383     }
23384 
23385     template<class IteratorType, class SAX>
23386     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)23387     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
23388                           input_format_t format = input_format_t::json,
23389                           const bool strict = true,
23390                           const bool ignore_comments = false)
23391     {
23392         auto ia = detail::input_adapter(std::move(first), std::move(last));
23393         return format == input_format_t::json
23394                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23395                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23396     }
23397 
23398     template <typename SAX>
23399     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
23400     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)23401     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
23402                           input_format_t format = input_format_t::json,
23403                           const bool strict = true,
23404                           const bool ignore_comments = false)
23405     {
23406         auto ia = i.get();
23407         return format == input_format_t::json
23408                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
23409                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
23410     }
23411 
23412     /*!
23413     @brief deserialize from stream
23414     @deprecated This stream operator is deprecated and will be removed in
23415                 version 4.0.0 of the library. Please use
23416                 @ref operator>>(std::istream&, basic_json&)
23417                 instead; that is, replace calls like `j << i;` with `i >> j;`.
23418     @since version 1.0.0; deprecated since version 3.0.0
23419     */
23420     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
operator <<(basic_json & j,std::istream & i)23421     friend std::istream& operator<<(basic_json& j, std::istream& i)
23422     {
23423         return operator>>(i, j);
23424     }
23425 
23426     /*!
23427     @brief deserialize from stream
23428 
23429     Deserializes an input stream to a JSON value.
23430 
23431     @param[in,out] i  input stream to read a serialized JSON value from
23432     @param[in,out] j  JSON value to write the deserialized input to
23433 
23434     @throw parse_error.101 in case of an unexpected token
23435     @throw parse_error.102 if to_unicode fails or surrogate error
23436     @throw parse_error.103 if to_unicode fails
23437 
23438     @complexity Linear in the length of the input. The parser is a predictive
23439     LL(1) parser.
23440 
23441     @note A UTF-8 byte order mark is silently ignored.
23442 
23443     @liveexample{The example below shows how a JSON value is constructed by
23444     reading a serialization from a stream.,operator_deserialize}
23445 
23446     @sa parse(std::istream&, const parser_callback_t) for a variant with a
23447     parser callback function to filter values while parsing
23448 
23449     @since version 1.0.0
23450     */
operator >>(std::istream & i,basic_json & j)23451     friend std::istream& operator>>(std::istream& i, basic_json& j)
23452     {
23453         parser(detail::input_adapter(i)).parse(false, j);
23454         return i;
23455     }
23456 
23457     /// @}
23458 
23459     ///////////////////////////
23460     // convenience functions //
23461     ///////////////////////////
23462 
23463     /*!
23464     @brief return the type as string
23465 
23466     Returns the type name as string to be used in error messages - usually to
23467     indicate that a function was called on a wrong JSON type.
23468 
23469     @return a string representation of a the @a m_type member:
23470             Value type  | return value
23471             ----------- | -------------
23472             null        | `"null"`
23473             boolean     | `"boolean"`
23474             string      | `"string"`
23475             number      | `"number"` (for all number types)
23476             object      | `"object"`
23477             array       | `"array"`
23478             binary      | `"binary"`
23479             discarded   | `"discarded"`
23480 
23481     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23482 
23483     @complexity Constant.
23484 
23485     @liveexample{The following code exemplifies `type_name()` for all JSON
23486     types.,type_name}
23487 
23488     @sa @ref type() -- return the type of the JSON value
23489     @sa @ref operator value_t() -- return the type of the JSON value (implicit)
23490 
23491     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
23492     since 3.0.0
23493     */
23494     JSON_HEDLEY_RETURNS_NON_NULL
type_name() const23495     const char* type_name() const noexcept
23496     {
23497         {
23498             switch (m_type)
23499             {
23500                 case value_t::null:
23501                     return "null";
23502                 case value_t::object:
23503                     return "object";
23504                 case value_t::array:
23505                     return "array";
23506                 case value_t::string:
23507                     return "string";
23508                 case value_t::boolean:
23509                     return "boolean";
23510                 case value_t::binary:
23511                     return "binary";
23512                 case value_t::discarded:
23513                     return "discarded";
23514                 default:
23515                     return "number";
23516             }
23517         }
23518     }
23519 
23520 
23521   JSON_PRIVATE_UNLESS_TESTED:
23522     //////////////////////
23523     // member variables //
23524     //////////////////////
23525 
23526     /// the type of the current element
23527     value_t m_type = value_t::null;
23528 
23529     /// the value of the current element
23530     json_value m_value = {};
23531 
23532     //////////////////////////////////////////
23533     // binary serialization/deserialization //
23534     //////////////////////////////////////////
23535 
23536     /// @name binary serialization/deserialization support
23537     /// @{
23538 
23539   public:
23540     /*!
23541     @brief create a CBOR serialization of a given JSON value
23542 
23543     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
23544     Binary Object Representation) serialization format. CBOR is a binary
23545     serialization format which aims to be more compact than JSON itself, yet
23546     more efficient to parse.
23547 
23548     The library uses the following mapping from JSON values types to
23549     CBOR types according to the CBOR specification (RFC 7049):
23550 
23551     JSON value type | value/range                                | CBOR type                          | first byte
23552     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
23553     null            | `null`                                     | Null                               | 0xF6
23554     boolean         | `true`                                     | True                               | 0xF5
23555     boolean         | `false`                                    | False                              | 0xF4
23556     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
23557     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
23558     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
23559     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
23560     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
23561     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
23562     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23563     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23564     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23565     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23566     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
23567     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
23568     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
23569     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
23570     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
23571     number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
23572     number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
23573     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
23574     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
23575     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
23576     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
23577     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
23578     array           | *size*: 0..23                              | array                              | 0x80..0x97
23579     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
23580     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
23581     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
23582     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
23583     object          | *size*: 0..23                              | map                                | 0xA0..0xB7
23584     object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
23585     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
23586     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
23587     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
23588     binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
23589     binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
23590     binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
23591     binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
23592     binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
23593 
23594     @note The mapping is **complete** in the sense that any JSON value type
23595           can be converted to a CBOR value.
23596 
23597     @note If NaN or Infinity are stored inside a JSON number, they are
23598           serialized properly. This behavior differs from the @ref dump()
23599           function which serializes NaN or Infinity to `null`.
23600 
23601     @note The following CBOR types are not used in the conversion:
23602           - UTF-8 strings terminated by "break" (0x7F)
23603           - arrays terminated by "break" (0x9F)
23604           - maps terminated by "break" (0xBF)
23605           - byte strings terminated by "break" (0x5F)
23606           - date/time (0xC0..0xC1)
23607           - bignum (0xC2..0xC3)
23608           - decimal fraction (0xC4)
23609           - bigfloat (0xC5)
23610           - expected conversions (0xD5..0xD7)
23611           - simple values (0xE0..0xF3, 0xF8)
23612           - undefined (0xF7)
23613           - half-precision floats (0xF9)
23614           - break (0xFF)
23615 
23616     @param[in] j  JSON value to serialize
23617     @return CBOR serialization as byte vector
23618 
23619     @complexity Linear in the size of the JSON value @a j.
23620 
23621     @liveexample{The example shows the serialization of a JSON value to a byte
23622     vector in CBOR format.,to_cbor}
23623 
23624     @sa http://cbor.io
23625     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
23626         analogous deserialization
23627     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23628     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23629              related UBJSON format
23630 
23631     @since version 2.0.9; compact representation of floating-point numbers
23632            since version 3.8.0
23633     */
to_cbor(const basic_json & j)23634     static std::vector<uint8_t> to_cbor(const basic_json& j)
23635     {
23636         std::vector<uint8_t> result;
23637         to_cbor(j, result);
23638         return result;
23639     }
23640 
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)23641     static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
23642     {
23643         binary_writer<uint8_t>(o).write_cbor(j);
23644     }
23645 
to_cbor(const basic_json & j,detail::output_adapter<char> o)23646     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
23647     {
23648         binary_writer<char>(o).write_cbor(j);
23649     }
23650 
23651     /*!
23652     @brief create a MessagePack serialization of a given JSON value
23653 
23654     Serializes a given JSON value @a j to a byte vector using the MessagePack
23655     serialization format. MessagePack is a binary serialization format which
23656     aims to be more compact than JSON itself, yet more efficient to parse.
23657 
23658     The library uses the following mapping from JSON values types to
23659     MessagePack types according to the MessagePack specification:
23660 
23661     JSON value type | value/range                       | MessagePack type | first byte
23662     --------------- | --------------------------------- | ---------------- | ----------
23663     null            | `null`                            | nil              | 0xC0
23664     boolean         | `true`                            | true             | 0xC3
23665     boolean         | `false`                           | false            | 0xC2
23666     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
23667     number_integer  | -2147483648..-32769               | int32            | 0xD2
23668     number_integer  | -32768..-129                      | int16            | 0xD1
23669     number_integer  | -128..-33                         | int8             | 0xD0
23670     number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
23671     number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
23672     number_integer  | 128..255                          | uint 8           | 0xCC
23673     number_integer  | 256..65535                        | uint 16          | 0xCD
23674     number_integer  | 65536..4294967295                 | uint 32          | 0xCE
23675     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
23676     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
23677     number_unsigned | 128..255                          | uint 8           | 0xCC
23678     number_unsigned | 256..65535                        | uint 16          | 0xCD
23679     number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
23680     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
23681     number_float    | *any value representable by a float*     | float 32 | 0xCA
23682     number_float    | *any value NOT representable by a float* | float 64 | 0xCB
23683     string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
23684     string          | *length*: 32..255                 | str 8            | 0xD9
23685     string          | *length*: 256..65535              | str 16           | 0xDA
23686     string          | *length*: 65536..4294967295       | str 32           | 0xDB
23687     array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
23688     array           | *size*: 16..65535                 | array 16         | 0xDC
23689     array           | *size*: 65536..4294967295         | array 32         | 0xDD
23690     object          | *size*: 0..15                     | fix map          | 0x80..0x8F
23691     object          | *size*: 16..65535                 | map 16           | 0xDE
23692     object          | *size*: 65536..4294967295         | map 32           | 0xDF
23693     binary          | *size*: 0..255                    | bin 8            | 0xC4
23694     binary          | *size*: 256..65535                | bin 16           | 0xC5
23695     binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
23696 
23697     @note The mapping is **complete** in the sense that any JSON value type
23698           can be converted to a MessagePack value.
23699 
23700     @note The following values can **not** be converted to a MessagePack value:
23701           - strings with more than 4294967295 bytes
23702           - byte strings with more than 4294967295 bytes
23703           - arrays with more than 4294967295 elements
23704           - objects with more than 4294967295 elements
23705 
23706     @note Any MessagePack output created @ref to_msgpack can be successfully
23707           parsed by @ref from_msgpack.
23708 
23709     @note If NaN or Infinity are stored inside a JSON number, they are
23710           serialized properly. This behavior differs from the @ref dump()
23711           function which serializes NaN or Infinity to `null`.
23712 
23713     @param[in] j  JSON value to serialize
23714     @return MessagePack serialization as byte vector
23715 
23716     @complexity Linear in the size of the JSON value @a j.
23717 
23718     @liveexample{The example shows the serialization of a JSON value to a byte
23719     vector in MessagePack format.,to_msgpack}
23720 
23721     @sa http://msgpack.org
23722     @sa @ref from_msgpack for the analogous deserialization
23723     @sa @ref to_cbor(const basic_json& for the related CBOR format
23724     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23725              related UBJSON format
23726 
23727     @since version 2.0.9
23728     */
to_msgpack(const basic_json & j)23729     static std::vector<uint8_t> to_msgpack(const basic_json& j)
23730     {
23731         std::vector<uint8_t> result;
23732         to_msgpack(j, result);
23733         return result;
23734     }
23735 
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)23736     static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
23737     {
23738         binary_writer<uint8_t>(o).write_msgpack(j);
23739     }
23740 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)23741     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
23742     {
23743         binary_writer<char>(o).write_msgpack(j);
23744     }
23745 
23746     /*!
23747     @brief create a UBJSON serialization of a given JSON value
23748 
23749     Serializes a given JSON value @a j to a byte vector using the UBJSON
23750     (Universal Binary JSON) serialization format. UBJSON aims to be more compact
23751     than JSON itself, yet more efficient to parse.
23752 
23753     The library uses the following mapping from JSON values types to
23754     UBJSON types according to the UBJSON specification:
23755 
23756     JSON value type | value/range                       | UBJSON type | marker
23757     --------------- | --------------------------------- | ----------- | ------
23758     null            | `null`                            | null        | `Z`
23759     boolean         | `true`                            | true        | `T`
23760     boolean         | `false`                           | false       | `F`
23761     number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
23762     number_integer  | -2147483648..-32769               | int32       | `l`
23763     number_integer  | -32768..-129                      | int16       | `I`
23764     number_integer  | -128..127                         | int8        | `i`
23765     number_integer  | 128..255                          | uint8       | `U`
23766     number_integer  | 256..32767                        | int16       | `I`
23767     number_integer  | 32768..2147483647                 | int32       | `l`
23768     number_integer  | 2147483648..9223372036854775807   | int64       | `L`
23769     number_unsigned | 0..127                            | int8        | `i`
23770     number_unsigned | 128..255                          | uint8       | `U`
23771     number_unsigned | 256..32767                        | int16       | `I`
23772     number_unsigned | 32768..2147483647                 | int32       | `l`
23773     number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
23774     number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
23775     number_float    | *any value*                       | float64     | `D`
23776     string          | *with shortest length indicator*  | string      | `S`
23777     array           | *see notes on optimized format*   | array       | `[`
23778     object          | *see notes on optimized format*   | map         | `{`
23779 
23780     @note The mapping is **complete** in the sense that any JSON value type
23781           can be converted to a UBJSON value.
23782 
23783     @note The following values can **not** be converted to a UBJSON value:
23784           - strings with more than 9223372036854775807 bytes (theoretical)
23785 
23786     @note The following markers are not used in the conversion:
23787           - `Z`: no-op values are not created.
23788           - `C`: single-byte strings are serialized with `S` markers.
23789 
23790     @note Any UBJSON output created @ref to_ubjson can be successfully parsed
23791           by @ref from_ubjson.
23792 
23793     @note If NaN or Infinity are stored inside a JSON number, they are
23794           serialized properly. This behavior differs from the @ref dump()
23795           function which serializes NaN or Infinity to `null`.
23796 
23797     @note The optimized formats for containers are supported: Parameter
23798           @a use_size adds size information to the beginning of a container and
23799           removes the closing marker. Parameter @a use_type further checks
23800           whether all elements of a container have the same type and adds the
23801           type marker to the beginning of the container. The @a use_type
23802           parameter must only be used together with @a use_size = true. Note
23803           that @a use_size = true alone may result in larger representations -
23804           the benefit of this parameter is that the receiving side is
23805           immediately informed on the number of elements of the container.
23806 
23807     @note If the JSON data contains the binary type, the value stored is a list
23808           of integers, as suggested by the UBJSON documentation.  In particular,
23809           this means that serialization and the deserialization of a JSON
23810           containing binary values into UBJSON and back will result in a
23811           different JSON object.
23812 
23813     @param[in] j  JSON value to serialize
23814     @param[in] use_size  whether to add size annotations to container types
23815     @param[in] use_type  whether to add type annotations to container types
23816                          (must be combined with @a use_size = true)
23817     @return UBJSON serialization as byte vector
23818 
23819     @complexity Linear in the size of the JSON value @a j.
23820 
23821     @liveexample{The example shows the serialization of a JSON value to a byte
23822     vector in UBJSON format.,to_ubjson}
23823 
23824     @sa http://ubjson.org
23825     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
23826         analogous deserialization
23827     @sa @ref to_cbor(const basic_json& for the related CBOR format
23828     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23829 
23830     @since version 3.1.0
23831     */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)23832     static std::vector<uint8_t> to_ubjson(const basic_json& j,
23833                                           const bool use_size = false,
23834                                           const bool use_type = false)
23835     {
23836         std::vector<uint8_t> result;
23837         to_ubjson(j, result, use_size, use_type);
23838         return result;
23839     }
23840 
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)23841     static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
23842                           const bool use_size = false, const bool use_type = false)
23843     {
23844         binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
23845     }
23846 
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)23847     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
23848                           const bool use_size = false, const bool use_type = false)
23849     {
23850         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
23851     }
23852 
23853 
23854     /*!
23855     @brief Serializes the given JSON object `j` to BSON and returns a vector
23856            containing the corresponding BSON-representation.
23857 
23858     BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
23859     stored as a single entity (a so-called document).
23860 
23861     The library uses the following mapping from JSON values types to BSON types:
23862 
23863     JSON value type | value/range                       | BSON type   | marker
23864     --------------- | --------------------------------- | ----------- | ------
23865     null            | `null`                            | null        | 0x0A
23866     boolean         | `true`, `false`                   | boolean     | 0x08
23867     number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
23868     number_integer  | -2147483648..2147483647           | int32       | 0x10
23869     number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
23870     number_unsigned | 0..2147483647                     | int32       | 0x10
23871     number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
23872     number_unsigned | 9223372036854775808..18446744073709551615| --   | --
23873     number_float    | *any value*                       | double      | 0x01
23874     string          | *any value*                       | string      | 0x02
23875     array           | *any value*                       | document    | 0x04
23876     object          | *any value*                       | document    | 0x03
23877     binary          | *any value*                       | binary      | 0x05
23878 
23879     @warning The mapping is **incomplete**, since only JSON-objects (and things
23880     contained therein) can be serialized to BSON.
23881     Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
23882     and the keys may not contain U+0000, since they are serialized a
23883     zero-terminated c-strings.
23884 
23885     @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
23886     @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
23887     @throw type_error.317    if `!j.is_object()`
23888 
23889     @pre The input `j` is required to be an object: `j.is_object() == true`.
23890 
23891     @note Any BSON output created via @ref to_bson can be successfully parsed
23892           by @ref from_bson.
23893 
23894     @param[in] j  JSON value to serialize
23895     @return BSON serialization as byte vector
23896 
23897     @complexity Linear in the size of the JSON value @a j.
23898 
23899     @liveexample{The example shows the serialization of a JSON value to a byte
23900     vector in BSON format.,to_bson}
23901 
23902     @sa http://bsonspec.org/spec.html
23903     @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
23904         analogous deserialization
23905     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
23906              related UBJSON format
23907     @sa @ref to_cbor(const basic_json&) for the related CBOR format
23908     @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
23909     */
to_bson(const basic_json & j)23910     static std::vector<uint8_t> to_bson(const basic_json& j)
23911     {
23912         std::vector<uint8_t> result;
23913         to_bson(j, result);
23914         return result;
23915     }
23916 
23917     /*!
23918     @brief Serializes the given JSON object `j` to BSON and forwards the
23919            corresponding BSON-representation to the given output_adapter `o`.
23920     @param j The JSON object to convert to BSON.
23921     @param o The output adapter that receives the binary BSON representation.
23922     @pre The input `j` shall be an object: `j.is_object() == true`
23923     @sa @ref to_bson(const basic_json&)
23924     */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)23925     static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
23926     {
23927         binary_writer<uint8_t>(o).write_bson(j);
23928     }
23929 
23930     /*!
23931     @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
23932     */
to_bson(const basic_json & j,detail::output_adapter<char> o)23933     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
23934     {
23935         binary_writer<char>(o).write_bson(j);
23936     }
23937 
23938 
23939     /*!
23940     @brief create a JSON value from an input in CBOR format
23941 
23942     Deserializes a given input @a i to a JSON value using the CBOR (Concise
23943     Binary Object Representation) serialization format.
23944 
23945     The library maps CBOR types to JSON value types as follows:
23946 
23947     CBOR type              | JSON value type | first byte
23948     ---------------------- | --------------- | ----------
23949     Integer                | number_unsigned | 0x00..0x17
23950     Unsigned integer       | number_unsigned | 0x18
23951     Unsigned integer       | number_unsigned | 0x19
23952     Unsigned integer       | number_unsigned | 0x1A
23953     Unsigned integer       | number_unsigned | 0x1B
23954     Negative integer       | number_integer  | 0x20..0x37
23955     Negative integer       | number_integer  | 0x38
23956     Negative integer       | number_integer  | 0x39
23957     Negative integer       | number_integer  | 0x3A
23958     Negative integer       | number_integer  | 0x3B
23959     Byte string            | binary          | 0x40..0x57
23960     Byte string            | binary          | 0x58
23961     Byte string            | binary          | 0x59
23962     Byte string            | binary          | 0x5A
23963     Byte string            | binary          | 0x5B
23964     UTF-8 string           | string          | 0x60..0x77
23965     UTF-8 string           | string          | 0x78
23966     UTF-8 string           | string          | 0x79
23967     UTF-8 string           | string          | 0x7A
23968     UTF-8 string           | string          | 0x7B
23969     UTF-8 string           | string          | 0x7F
23970     array                  | array           | 0x80..0x97
23971     array                  | array           | 0x98
23972     array                  | array           | 0x99
23973     array                  | array           | 0x9A
23974     array                  | array           | 0x9B
23975     array                  | array           | 0x9F
23976     map                    | object          | 0xA0..0xB7
23977     map                    | object          | 0xB8
23978     map                    | object          | 0xB9
23979     map                    | object          | 0xBA
23980     map                    | object          | 0xBB
23981     map                    | object          | 0xBF
23982     False                  | `false`         | 0xF4
23983     True                   | `true`          | 0xF5
23984     Null                   | `null`          | 0xF6
23985     Half-Precision Float   | number_float    | 0xF9
23986     Single-Precision Float | number_float    | 0xFA
23987     Double-Precision Float | number_float    | 0xFB
23988 
23989     @warning The mapping is **incomplete** in the sense that not all CBOR
23990              types can be converted to a JSON value. The following CBOR types
23991              are not supported and will yield parse errors (parse_error.112):
23992              - date/time (0xC0..0xC1)
23993              - bignum (0xC2..0xC3)
23994              - decimal fraction (0xC4)
23995              - bigfloat (0xC5)
23996              - expected conversions (0xD5..0xD7)
23997              - simple values (0xE0..0xF3, 0xF8)
23998              - undefined (0xF7)
23999 
24000     @warning CBOR allows map keys of any type, whereas JSON only allows
24001              strings as keys in object values. Therefore, CBOR maps with keys
24002              other than UTF-8 strings are rejected (parse_error.113).
24003 
24004     @note Any CBOR output created @ref to_cbor can be successfully parsed by
24005           @ref from_cbor.
24006 
24007     @param[in] i  an input in CBOR format convertible to an input adapter
24008     @param[in] strict  whether to expect the input to be consumed until EOF
24009                        (true by default)
24010     @param[in] allow_exceptions  whether to throw exceptions in case of a
24011     parse error (optional, true by default)
24012     @param[in] tag_handler how to treat CBOR tags (optional, error by default)
24013 
24014     @return deserialized JSON value; in case of a parse error and
24015             @a allow_exceptions set to `false`, the return value will be
24016             value_t::discarded.
24017 
24018     @throw parse_error.110 if the given input ends prematurely or the end of
24019     file was not reached when @a strict was set to true
24020     @throw parse_error.112 if unsupported features from CBOR were
24021     used in the given input @a v or if the input is not valid CBOR
24022     @throw parse_error.113 if a string was expected as map key, but not found
24023 
24024     @complexity Linear in the size of the input @a i.
24025 
24026     @liveexample{The example shows the deserialization of a byte vector in CBOR
24027     format to a JSON value.,from_cbor}
24028 
24029     @sa http://cbor.io
24030     @sa @ref to_cbor(const basic_json&) for the analogous serialization
24031     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
24032         related MessagePack format
24033     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
24034         related UBJSON format
24035 
24036     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
24037            consume input adapters, removed start_index parameter, and added
24038            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
24039            since 3.2.0; added @a tag_handler parameter since 3.9.0.
24040     */
24041     template<typename InputType>
24042     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)24043     static basic_json from_cbor(InputType&& i,
24044                                 const bool strict = true,
24045                                 const bool allow_exceptions = true,
24046                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24047     {
24048         basic_json result;
24049         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24050         auto ia = detail::input_adapter(std::forward<InputType>(i));
24051         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24052         return res ? result : basic_json(value_t::discarded);
24053     }
24054 
24055     /*!
24056     @copydoc from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t)
24057     */
24058     template<typename IteratorType>
24059     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)24060     static basic_json from_cbor(IteratorType first, IteratorType last,
24061                                 const bool strict = true,
24062                                 const bool allow_exceptions = true,
24063                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24064     {
24065         basic_json result;
24066         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24067         auto ia = detail::input_adapter(std::move(first), std::move(last));
24068         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24069         return res ? result : basic_json(value_t::discarded);
24070     }
24071 
24072     template<typename T>
24073     JSON_HEDLEY_WARN_UNUSED_RESULT
24074     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)24075     static basic_json from_cbor(const T* ptr, std::size_t len,
24076                                 const bool strict = true,
24077                                 const bool allow_exceptions = true,
24078                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24079     {
24080         return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
24081     }
24082 
24083 
24084     JSON_HEDLEY_WARN_UNUSED_RESULT
24085     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)24086     static basic_json from_cbor(detail::span_input_adapter&& i,
24087                                 const bool strict = true,
24088                                 const bool allow_exceptions = true,
24089                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
24090     {
24091         basic_json result;
24092         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24093         auto ia = i.get();
24094         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
24095         return res ? result : basic_json(value_t::discarded);
24096     }
24097 
24098     /*!
24099     @brief create a JSON value from an input in MessagePack format
24100 
24101     Deserializes a given input @a i to a JSON value using the MessagePack
24102     serialization format.
24103 
24104     The library maps MessagePack types to JSON value types as follows:
24105 
24106     MessagePack type | JSON value type | first byte
24107     ---------------- | --------------- | ----------
24108     positive fixint  | number_unsigned | 0x00..0x7F
24109     fixmap           | object          | 0x80..0x8F
24110     fixarray         | array           | 0x90..0x9F
24111     fixstr           | string          | 0xA0..0xBF
24112     nil              | `null`          | 0xC0
24113     false            | `false`         | 0xC2
24114     true             | `true`          | 0xC3
24115     float 32         | number_float    | 0xCA
24116     float 64         | number_float    | 0xCB
24117     uint 8           | number_unsigned | 0xCC
24118     uint 16          | number_unsigned | 0xCD
24119     uint 32          | number_unsigned | 0xCE
24120     uint 64          | number_unsigned | 0xCF
24121     int 8            | number_integer  | 0xD0
24122     int 16           | number_integer  | 0xD1
24123     int 32           | number_integer  | 0xD2
24124     int 64           | number_integer  | 0xD3
24125     str 8            | string          | 0xD9
24126     str 16           | string          | 0xDA
24127     str 32           | string          | 0xDB
24128     array 16         | array           | 0xDC
24129     array 32         | array           | 0xDD
24130     map 16           | object          | 0xDE
24131     map 32           | object          | 0xDF
24132     bin 8            | binary          | 0xC4
24133     bin 16           | binary          | 0xC5
24134     bin 32           | binary          | 0xC6
24135     ext 8            | binary          | 0xC7
24136     ext 16           | binary          | 0xC8
24137     ext 32           | binary          | 0xC9
24138     fixext 1         | binary          | 0xD4
24139     fixext 2         | binary          | 0xD5
24140     fixext 4         | binary          | 0xD6
24141     fixext 8         | binary          | 0xD7
24142     fixext 16        | binary          | 0xD8
24143     negative fixint  | number_integer  | 0xE0-0xFF
24144 
24145     @note Any MessagePack output created @ref to_msgpack can be successfully
24146           parsed by @ref from_msgpack.
24147 
24148     @param[in] i  an input in MessagePack format convertible to an input
24149                   adapter
24150     @param[in] strict  whether to expect the input to be consumed until EOF
24151                        (true by default)
24152     @param[in] allow_exceptions  whether to throw exceptions in case of a
24153     parse error (optional, true by default)
24154 
24155     @return deserialized JSON value; in case of a parse error and
24156             @a allow_exceptions set to `false`, the return value will be
24157             value_t::discarded.
24158 
24159     @throw parse_error.110 if the given input ends prematurely or the end of
24160     file was not reached when @a strict was set to true
24161     @throw parse_error.112 if unsupported features from MessagePack were
24162     used in the given input @a i or if the input is not valid MessagePack
24163     @throw parse_error.113 if a string was expected as map key, but not found
24164 
24165     @complexity Linear in the size of the input @a i.
24166 
24167     @liveexample{The example shows the deserialization of a byte vector in
24168     MessagePack format to a JSON value.,from_msgpack}
24169 
24170     @sa http://msgpack.org
24171     @sa @ref to_msgpack(const basic_json&) for the analogous serialization
24172     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24173         related CBOR format
24174     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
24175         the related UBJSON format
24176     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24177         the related BSON format
24178 
24179     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
24180            consume input adapters, removed start_index parameter, and added
24181            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
24182            since 3.2.0
24183     */
24184     template<typename InputType>
24185     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(InputType && i,const bool strict=true,const bool allow_exceptions=true)24186     static basic_json from_msgpack(InputType&& i,
24187                                    const bool strict = true,
24188                                    const bool allow_exceptions = true)
24189     {
24190         basic_json result;
24191         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24192         auto ia = detail::input_adapter(std::forward<InputType>(i));
24193         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24194         return res ? result : basic_json(value_t::discarded);
24195     }
24196 
24197     /*!
24198     @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
24199     */
24200     template<typename IteratorType>
24201     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24202     static basic_json from_msgpack(IteratorType first, IteratorType last,
24203                                    const bool strict = true,
24204                                    const bool allow_exceptions = true)
24205     {
24206         basic_json result;
24207         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24208         auto ia = detail::input_adapter(std::move(first), std::move(last));
24209         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24210         return res ? result : basic_json(value_t::discarded);
24211     }
24212 
24213 
24214     template<typename T>
24215     JSON_HEDLEY_WARN_UNUSED_RESULT
24216     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)24217     static basic_json from_msgpack(const T* ptr, std::size_t len,
24218                                    const bool strict = true,
24219                                    const bool allow_exceptions = true)
24220     {
24221         return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
24222     }
24223 
24224     JSON_HEDLEY_WARN_UNUSED_RESULT
24225     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)24226     static basic_json from_msgpack(detail::span_input_adapter&& i,
24227                                    const bool strict = true,
24228                                    const bool allow_exceptions = true)
24229     {
24230         basic_json result;
24231         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24232         auto ia = i.get();
24233         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
24234         return res ? result : basic_json(value_t::discarded);
24235     }
24236 
24237 
24238     /*!
24239     @brief create a JSON value from an input in UBJSON format
24240 
24241     Deserializes a given input @a i to a JSON value using the UBJSON (Universal
24242     Binary JSON) serialization format.
24243 
24244     The library maps UBJSON types to JSON value types as follows:
24245 
24246     UBJSON type | JSON value type                         | marker
24247     ----------- | --------------------------------------- | ------
24248     no-op       | *no value, next value is read*          | `N`
24249     null        | `null`                                  | `Z`
24250     false       | `false`                                 | `F`
24251     true        | `true`                                  | `T`
24252     float32     | number_float                            | `d`
24253     float64     | number_float                            | `D`
24254     uint8       | number_unsigned                         | `U`
24255     int8        | number_integer                          | `i`
24256     int16       | number_integer                          | `I`
24257     int32       | number_integer                          | `l`
24258     int64       | number_integer                          | `L`
24259     high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
24260     string      | string                                  | `S`
24261     char        | string                                  | `C`
24262     array       | array (optimized values are supported)  | `[`
24263     object      | object (optimized values are supported) | `{`
24264 
24265     @note The mapping is **complete** in the sense that any UBJSON value can
24266           be converted to a JSON value.
24267 
24268     @param[in] i  an input in UBJSON format convertible to an input adapter
24269     @param[in] strict  whether to expect the input to be consumed until EOF
24270                        (true by default)
24271     @param[in] allow_exceptions  whether to throw exceptions in case of a
24272     parse error (optional, true by default)
24273 
24274     @return deserialized JSON value; in case of a parse error and
24275             @a allow_exceptions set to `false`, the return value will be
24276             value_t::discarded.
24277 
24278     @throw parse_error.110 if the given input ends prematurely or the end of
24279     file was not reached when @a strict was set to true
24280     @throw parse_error.112 if a parse error occurs
24281     @throw parse_error.113 if a string could not be parsed successfully
24282 
24283     @complexity Linear in the size of the input @a i.
24284 
24285     @liveexample{The example shows the deserialization of a byte vector in
24286     UBJSON format to a JSON value.,from_ubjson}
24287 
24288     @sa http://ubjson.org
24289     @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
24290              analogous serialization
24291     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24292         related CBOR format
24293     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24294         the related MessagePack format
24295     @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
24296         the related BSON format
24297 
24298     @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
24299     */
24300     template<typename InputType>
24301     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(InputType && i,const bool strict=true,const bool allow_exceptions=true)24302     static basic_json from_ubjson(InputType&& i,
24303                                   const bool strict = true,
24304                                   const bool allow_exceptions = true)
24305     {
24306         basic_json result;
24307         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24308         auto ia = detail::input_adapter(std::forward<InputType>(i));
24309         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24310         return res ? result : basic_json(value_t::discarded);
24311     }
24312 
24313     /*!
24314     @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
24315     */
24316     template<typename IteratorType>
24317     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24318     static basic_json from_ubjson(IteratorType first, IteratorType last,
24319                                   const bool strict = true,
24320                                   const bool allow_exceptions = true)
24321     {
24322         basic_json result;
24323         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24324         auto ia = detail::input_adapter(std::move(first), std::move(last));
24325         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24326         return res ? result : basic_json(value_t::discarded);
24327     }
24328 
24329     template<typename T>
24330     JSON_HEDLEY_WARN_UNUSED_RESULT
24331     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)24332     static basic_json from_ubjson(const T* ptr, std::size_t len,
24333                                   const bool strict = true,
24334                                   const bool allow_exceptions = true)
24335     {
24336         return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
24337     }
24338 
24339     JSON_HEDLEY_WARN_UNUSED_RESULT
24340     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)24341     static basic_json from_ubjson(detail::span_input_adapter&& i,
24342                                   const bool strict = true,
24343                                   const bool allow_exceptions = true)
24344     {
24345         basic_json result;
24346         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24347         auto ia = i.get();
24348         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
24349         return res ? result : basic_json(value_t::discarded);
24350     }
24351 
24352 
24353     /*!
24354     @brief Create a JSON value from an input in BSON format
24355 
24356     Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
24357     serialization format.
24358 
24359     The library maps BSON record types to JSON value types as follows:
24360 
24361     BSON type       | BSON marker byte | JSON value type
24362     --------------- | ---------------- | ---------------------------
24363     double          | 0x01             | number_float
24364     string          | 0x02             | string
24365     document        | 0x03             | object
24366     array           | 0x04             | array
24367     binary          | 0x05             | binary
24368     undefined       | 0x06             | still unsupported
24369     ObjectId        | 0x07             | still unsupported
24370     boolean         | 0x08             | boolean
24371     UTC Date-Time   | 0x09             | still unsupported
24372     null            | 0x0A             | null
24373     Regular Expr.   | 0x0B             | still unsupported
24374     DB Pointer      | 0x0C             | still unsupported
24375     JavaScript Code | 0x0D             | still unsupported
24376     Symbol          | 0x0E             | still unsupported
24377     JavaScript Code | 0x0F             | still unsupported
24378     int32           | 0x10             | number_integer
24379     Timestamp       | 0x11             | still unsupported
24380     128-bit decimal float | 0x13       | still unsupported
24381     Max Key         | 0x7F             | still unsupported
24382     Min Key         | 0xFF             | still unsupported
24383 
24384     @warning The mapping is **incomplete**. The unsupported mappings
24385              are indicated in the table above.
24386 
24387     @param[in] i  an input in BSON format convertible to an input adapter
24388     @param[in] strict  whether to expect the input to be consumed until EOF
24389                        (true by default)
24390     @param[in] allow_exceptions  whether to throw exceptions in case of a
24391     parse error (optional, true by default)
24392 
24393     @return deserialized JSON value; in case of a parse error and
24394             @a allow_exceptions set to `false`, the return value will be
24395             value_t::discarded.
24396 
24397     @throw parse_error.114 if an unsupported BSON record type is encountered
24398 
24399     @complexity Linear in the size of the input @a i.
24400 
24401     @liveexample{The example shows the deserialization of a byte vector in
24402     BSON format to a JSON value.,from_bson}
24403 
24404     @sa http://bsonspec.org/spec.html
24405     @sa @ref to_bson(const basic_json&) for the analogous serialization
24406     @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool, const cbor_tag_handler_t) for the
24407         related CBOR format
24408     @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
24409         the related MessagePack format
24410     @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
24411         related UBJSON format
24412     */
24413     template<typename InputType>
24414     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(InputType && i,const bool strict=true,const bool allow_exceptions=true)24415     static basic_json from_bson(InputType&& i,
24416                                 const bool strict = true,
24417                                 const bool allow_exceptions = true)
24418     {
24419         basic_json result;
24420         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24421         auto ia = detail::input_adapter(std::forward<InputType>(i));
24422         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24423         return res ? result : basic_json(value_t::discarded);
24424     }
24425 
24426     /*!
24427     @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
24428     */
24429     template<typename IteratorType>
24430     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)24431     static basic_json from_bson(IteratorType first, IteratorType last,
24432                                 const bool strict = true,
24433                                 const bool allow_exceptions = true)
24434     {
24435         basic_json result;
24436         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24437         auto ia = detail::input_adapter(std::move(first), std::move(last));
24438         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24439         return res ? result : basic_json(value_t::discarded);
24440     }
24441 
24442     template<typename T>
24443     JSON_HEDLEY_WARN_UNUSED_RESULT
24444     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)24445     static basic_json from_bson(const T* ptr, std::size_t len,
24446                                 const bool strict = true,
24447                                 const bool allow_exceptions = true)
24448     {
24449         return from_bson(ptr, ptr + len, strict, allow_exceptions);
24450     }
24451 
24452     JSON_HEDLEY_WARN_UNUSED_RESULT
24453     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)24454     static basic_json from_bson(detail::span_input_adapter&& i,
24455                                 const bool strict = true,
24456                                 const bool allow_exceptions = true)
24457     {
24458         basic_json result;
24459         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
24460         auto ia = i.get();
24461         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
24462         return res ? result : basic_json(value_t::discarded);
24463     }
24464     /// @}
24465 
24466     //////////////////////////
24467     // JSON Pointer support //
24468     //////////////////////////
24469 
24470     /// @name JSON Pointer functions
24471     /// @{
24472 
24473     /*!
24474     @brief access specified element via JSON Pointer
24475 
24476     Uses a JSON pointer to retrieve a reference to the respective JSON value.
24477     No bound checking is performed. Similar to @ref operator[](const typename
24478     object_t::key_type&), `null` values are created in arrays and objects if
24479     necessary.
24480 
24481     In particular:
24482     - If the JSON pointer points to an object key that does not exist, it
24483       is created an filled with a `null` value before a reference to it
24484       is returned.
24485     - If the JSON pointer points to an array index that does not exist, it
24486       is created an filled with a `null` value before a reference to it
24487       is returned. All indices between the current maximum and the given
24488       index are also filled with `null`.
24489     - The special value `-` is treated as a synonym for the index past the
24490       end.
24491 
24492     @param[in] ptr  a JSON pointer
24493 
24494     @return reference to the element pointed to by @a ptr
24495 
24496     @complexity Constant.
24497 
24498     @throw parse_error.106   if an array index begins with '0'
24499     @throw parse_error.109   if an array index was not a number
24500     @throw out_of_range.404  if the JSON pointer can not be resolved
24501 
24502     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
24503 
24504     @since version 2.0.0
24505     */
operator [](const json_pointer & ptr)24506     reference operator[](const json_pointer& ptr)
24507     {
24508         return ptr.get_unchecked(this);
24509     }
24510 
24511     /*!
24512     @brief access specified element via JSON Pointer
24513 
24514     Uses a JSON pointer to retrieve a reference to the respective JSON value.
24515     No bound checking is performed. The function does not change the JSON
24516     value; no `null` values are created. In particular, the special value
24517     `-` yields an exception.
24518 
24519     @param[in] ptr  JSON pointer to the desired element
24520 
24521     @return const reference to the element pointed to by @a ptr
24522 
24523     @complexity Constant.
24524 
24525     @throw parse_error.106   if an array index begins with '0'
24526     @throw parse_error.109   if an array index was not a number
24527     @throw out_of_range.402  if the array index '-' is used
24528     @throw out_of_range.404  if the JSON pointer can not be resolved
24529 
24530     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
24531 
24532     @since version 2.0.0
24533     */
operator [](const json_pointer & ptr) const24534     const_reference operator[](const json_pointer& ptr) const
24535     {
24536         return ptr.get_unchecked(this);
24537     }
24538 
24539     /*!
24540     @brief access specified element via JSON Pointer
24541 
24542     Returns a reference to the element at with specified JSON pointer @a ptr,
24543     with bounds checking.
24544 
24545     @param[in] ptr  JSON pointer to the desired element
24546 
24547     @return reference to the element pointed to by @a ptr
24548 
24549     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24550     begins with '0'. See example below.
24551 
24552     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24553     is not a number. See example below.
24554 
24555     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24556     is out of range. See example below.
24557 
24558     @throw out_of_range.402 if the array index '-' is used in the passed JSON
24559     pointer @a ptr. As `at` provides checked access (and no elements are
24560     implicitly inserted), the index '-' is always invalid. See example below.
24561 
24562     @throw out_of_range.403 if the JSON pointer describes a key of an object
24563     which cannot be found. See example below.
24564 
24565     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24566     See example below.
24567 
24568     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24569     changes in the JSON value.
24570 
24571     @complexity Constant.
24572 
24573     @since version 2.0.0
24574 
24575     @liveexample{The behavior is shown in the example.,at_json_pointer}
24576     */
at(const json_pointer & ptr)24577     reference at(const json_pointer& ptr)
24578     {
24579         return ptr.get_checked(this);
24580     }
24581 
24582     /*!
24583     @brief access specified element via JSON Pointer
24584 
24585     Returns a const reference to the element at with specified JSON pointer @a
24586     ptr, with bounds checking.
24587 
24588     @param[in] ptr  JSON pointer to the desired element
24589 
24590     @return reference to the element pointed to by @a ptr
24591 
24592     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
24593     begins with '0'. See example below.
24594 
24595     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
24596     is not a number. See example below.
24597 
24598     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
24599     is out of range. See example below.
24600 
24601     @throw out_of_range.402 if the array index '-' is used in the passed JSON
24602     pointer @a ptr. As `at` provides checked access (and no elements are
24603     implicitly inserted), the index '-' is always invalid. See example below.
24604 
24605     @throw out_of_range.403 if the JSON pointer describes a key of an object
24606     which cannot be found. See example below.
24607 
24608     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
24609     See example below.
24610 
24611     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
24612     changes in the JSON value.
24613 
24614     @complexity Constant.
24615 
24616     @since version 2.0.0
24617 
24618     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
24619     */
at(const json_pointer & ptr) const24620     const_reference at(const json_pointer& ptr) const
24621     {
24622         return ptr.get_checked(this);
24623     }
24624 
24625     /*!
24626     @brief return flattened JSON value
24627 
24628     The function creates a JSON object whose keys are JSON pointers (see [RFC
24629     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
24630     primitive. The original JSON value can be restored using the @ref
24631     unflatten() function.
24632 
24633     @return an object that maps JSON pointers to primitive values
24634 
24635     @note Empty objects and arrays are flattened to `null` and will not be
24636           reconstructed correctly by the @ref unflatten() function.
24637 
24638     @complexity Linear in the size the JSON value.
24639 
24640     @liveexample{The following code shows how a JSON object is flattened to an
24641     object whose keys consist of JSON pointers.,flatten}
24642 
24643     @sa @ref unflatten() for the reverse function
24644 
24645     @since version 2.0.0
24646     */
flatten() const24647     basic_json flatten() const
24648     {
24649         basic_json result(value_t::object);
24650         json_pointer::flatten("", *this, result);
24651         return result;
24652     }
24653 
24654     /*!
24655     @brief unflatten a previously flattened JSON value
24656 
24657     The function restores the arbitrary nesting of a JSON value that has been
24658     flattened before using the @ref flatten() function. The JSON value must
24659     meet certain constraints:
24660     1. The value must be an object.
24661     2. The keys must be JSON pointers (see
24662        [RFC 6901](https://tools.ietf.org/html/rfc6901))
24663     3. The mapped values must be primitive JSON types.
24664 
24665     @return the original JSON from a flattened version
24666 
24667     @note Empty objects and arrays are flattened by @ref flatten() to `null`
24668           values and can not unflattened to their original type. Apart from
24669           this example, for a JSON value `j`, the following is always true:
24670           `j == j.flatten().unflatten()`.
24671 
24672     @complexity Linear in the size the JSON value.
24673 
24674     @throw type_error.314  if value is not an object
24675     @throw type_error.315  if object values are not primitive
24676 
24677     @liveexample{The following code shows how a flattened JSON object is
24678     unflattened into the original nested JSON object.,unflatten}
24679 
24680     @sa @ref flatten() for the reverse function
24681 
24682     @since version 2.0.0
24683     */
unflatten() const24684     basic_json unflatten() const
24685     {
24686         return json_pointer::unflatten(*this);
24687     }
24688 
24689     /// @}
24690 
24691     //////////////////////////
24692     // JSON Patch functions //
24693     //////////////////////////
24694 
24695     /// @name JSON Patch functions
24696     /// @{
24697 
24698     /*!
24699     @brief applies a JSON patch
24700 
24701     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
24702     expressing a sequence of operations to apply to a JSON) document. With
24703     this function, a JSON Patch is applied to the current JSON value by
24704     executing all operations from the patch.
24705 
24706     @param[in] json_patch  JSON patch document
24707     @return patched document
24708 
24709     @note The application of a patch is atomic: Either all operations succeed
24710           and the patched document is returned or an exception is thrown. In
24711           any case, the original value is not changed: the patch is applied
24712           to a copy of the value.
24713 
24714     @throw parse_error.104 if the JSON patch does not consist of an array of
24715     objects
24716 
24717     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
24718     attributes are missing); example: `"operation add must have member path"`
24719 
24720     @throw out_of_range.401 if an array index is out of range.
24721 
24722     @throw out_of_range.403 if a JSON pointer inside the patch could not be
24723     resolved successfully in the current JSON value; example: `"key baz not
24724     found"`
24725 
24726     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
24727     "move")
24728 
24729     @throw other_error.501 if "test" operation was unsuccessful
24730 
24731     @complexity Linear in the size of the JSON value and the length of the
24732     JSON patch. As usually only a fraction of the JSON value is affected by
24733     the patch, the complexity can usually be neglected.
24734 
24735     @liveexample{The following code shows how a JSON patch is applied to a
24736     value.,patch}
24737 
24738     @sa @ref diff -- create a JSON patch by comparing two JSON values
24739 
24740     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
24741     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
24742 
24743     @since version 2.0.0
24744     */
patch(const basic_json & json_patch) const24745     basic_json patch(const basic_json& json_patch) const
24746     {
24747         // make a working copy to apply the patch to
24748         basic_json result = *this;
24749 
24750         // the valid JSON Patch operations
24751         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
24752 
24753         const auto get_op = [](const std::string & op)
24754         {
24755             if (op == "add")
24756             {
24757                 return patch_operations::add;
24758             }
24759             if (op == "remove")
24760             {
24761                 return patch_operations::remove;
24762             }
24763             if (op == "replace")
24764             {
24765                 return patch_operations::replace;
24766             }
24767             if (op == "move")
24768             {
24769                 return patch_operations::move;
24770             }
24771             if (op == "copy")
24772             {
24773                 return patch_operations::copy;
24774             }
24775             if (op == "test")
24776             {
24777                 return patch_operations::test;
24778             }
24779 
24780             return patch_operations::invalid;
24781         };
24782 
24783         // wrapper for "add" operation; add value at ptr
24784         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
24785         {
24786             // adding to the root of the target document means replacing it
24787             if (ptr.empty())
24788             {
24789                 result = val;
24790                 return;
24791             }
24792 
24793             // make sure the top element of the pointer exists
24794             json_pointer top_pointer = ptr.top();
24795             if (top_pointer != ptr)
24796             {
24797                 result.at(top_pointer);
24798             }
24799 
24800             // get reference to parent of JSON pointer ptr
24801             const auto last_path = ptr.back();
24802             ptr.pop_back();
24803             basic_json& parent = result[ptr];
24804 
24805             switch (parent.m_type)
24806             {
24807                 case value_t::null:
24808                 case value_t::object:
24809                 {
24810                     // use operator[] to add value
24811                     parent[last_path] = val;
24812                     break;
24813                 }
24814 
24815                 case value_t::array:
24816                 {
24817                     if (last_path == "-")
24818                     {
24819                         // special case: append to back
24820                         parent.push_back(val);
24821                     }
24822                     else
24823                     {
24824                         const auto idx = json_pointer::array_index(last_path);
24825                         if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
24826                         {
24827                             // avoid undefined behavior
24828                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
24829                         }
24830 
24831                         // default case: insert add offset
24832                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
24833                     }
24834                     break;
24835                 }
24836 
24837                 // if there exists a parent it cannot be primitive
24838                 default:            // LCOV_EXCL_LINE
24839                     JSON_ASSERT(false);  // LCOV_EXCL_LINE
24840             }
24841         };
24842 
24843         // wrapper for "remove" operation; remove value at ptr
24844         const auto operation_remove = [&result](json_pointer & ptr)
24845         {
24846             // get reference to parent of JSON pointer ptr
24847             const auto last_path = ptr.back();
24848             ptr.pop_back();
24849             basic_json& parent = result.at(ptr);
24850 
24851             // remove child
24852             if (parent.is_object())
24853             {
24854                 // perform range check
24855                 auto it = parent.find(last_path);
24856                 if (JSON_HEDLEY_LIKELY(it != parent.end()))
24857                 {
24858                     parent.erase(it);
24859                 }
24860                 else
24861                 {
24862                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
24863                 }
24864             }
24865             else if (parent.is_array())
24866             {
24867                 // note erase performs range check
24868                 parent.erase(json_pointer::array_index(last_path));
24869             }
24870         };
24871 
24872         // type check: top level value must be an array
24873         if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
24874         {
24875             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24876         }
24877 
24878         // iterate and apply the operations
24879         for (const auto& val : json_patch)
24880         {
24881             // wrapper to get a value for an operation
24882             const auto get_value = [&val](const std::string & op,
24883                                           const std::string & member,
24884                                           bool string_type) -> basic_json &
24885             {
24886                 // find value
24887                 auto it = val.m_value.object->find(member);
24888 
24889                 // context-sensitive error message
24890                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
24891 
24892                 // check if desired value is present
24893                 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
24894                 {
24895                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
24896                 }
24897 
24898                 // check if result is of type string
24899                 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
24900                 {
24901                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
24902                 }
24903 
24904                 // no error: return value
24905                 return it->second;
24906             };
24907 
24908             // type check: every element of the array must be an object
24909             if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
24910             {
24911                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
24912             }
24913 
24914             // collect mandatory members
24915             const auto op = get_value("op", "op", true).template get<std::string>();
24916             const auto path = get_value(op, "path", true).template get<std::string>();
24917             json_pointer ptr(path);
24918 
24919             switch (get_op(op))
24920             {
24921                 case patch_operations::add:
24922                 {
24923                     operation_add(ptr, get_value("add", "value", false));
24924                     break;
24925                 }
24926 
24927                 case patch_operations::remove:
24928                 {
24929                     operation_remove(ptr);
24930                     break;
24931                 }
24932 
24933                 case patch_operations::replace:
24934                 {
24935                     // the "path" location must exist - use at()
24936                     result.at(ptr) = get_value("replace", "value", false);
24937                     break;
24938                 }
24939 
24940                 case patch_operations::move:
24941                 {
24942                     const auto from_path = get_value("move", "from", true).template get<std::string>();
24943                     json_pointer from_ptr(from_path);
24944 
24945                     // the "from" location must exist - use at()
24946                     basic_json v = result.at(from_ptr);
24947 
24948                     // The move operation is functionally identical to a
24949                     // "remove" operation on the "from" location, followed
24950                     // immediately by an "add" operation at the target
24951                     // location with the value that was just removed.
24952                     operation_remove(from_ptr);
24953                     operation_add(ptr, v);
24954                     break;
24955                 }
24956 
24957                 case patch_operations::copy:
24958                 {
24959                     const auto from_path = get_value("copy", "from", true).template get<std::string>();
24960                     const json_pointer from_ptr(from_path);
24961 
24962                     // the "from" location must exist - use at()
24963                     basic_json v = result.at(from_ptr);
24964 
24965                     // The copy is functionally identical to an "add"
24966                     // operation at the target location using the value
24967                     // specified in the "from" member.
24968                     operation_add(ptr, v);
24969                     break;
24970                 }
24971 
24972                 case patch_operations::test:
24973                 {
24974                     bool success = false;
24975                     JSON_TRY
24976                     {
24977                         // check if "value" matches the one at "path"
24978                         // the "path" location must exist - use at()
24979                         success = (result.at(ptr) == get_value("test", "value", false));
24980                     }
24981                     JSON_INTERNAL_CATCH (out_of_range&)
24982                     {
24983                         // ignore out of range errors: success remains false
24984                     }
24985 
24986                     // throw an exception if test fails
24987                     if (JSON_HEDLEY_UNLIKELY(!success))
24988                     {
24989                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
24990                     }
24991 
24992                     break;
24993                 }
24994 
24995                 default:
24996                 {
24997                     // op must be "add", "remove", "replace", "move", "copy", or
24998                     // "test"
24999                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
25000                 }
25001             }
25002         }
25003 
25004         return result;
25005     }
25006 
25007     /*!
25008     @brief creates a diff as a JSON patch
25009 
25010     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
25011     be changed into the value @a target by calling @ref patch function.
25012 
25013     @invariant For two JSON values @a source and @a target, the following code
25014     yields always `true`:
25015     @code {.cpp}
25016     source.patch(diff(source, target)) == target;
25017     @endcode
25018 
25019     @note Currently, only `remove`, `add`, and `replace` operations are
25020           generated.
25021 
25022     @param[in] source  JSON value to compare from
25023     @param[in] target  JSON value to compare against
25024     @param[in] path    helper value to create JSON pointers
25025 
25026     @return a JSON patch to convert the @a source to @a target
25027 
25028     @complexity Linear in the lengths of @a source and @a target.
25029 
25030     @liveexample{The following code shows how a JSON patch is created as a
25031     diff for two JSON values.,diff}
25032 
25033     @sa @ref patch -- apply a JSON patch
25034     @sa @ref merge_patch -- apply a JSON Merge Patch
25035 
25036     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25037 
25038     @since version 2.0.0
25039     */
25040     JSON_HEDLEY_WARN_UNUSED_RESULT
diff(const basic_json & source,const basic_json & target,const std::string & path="")25041     static basic_json diff(const basic_json& source, const basic_json& target,
25042                            const std::string& path = "")
25043     {
25044         // the patch
25045         basic_json result(value_t::array);
25046 
25047         // if the values are the same, return empty patch
25048         if (source == target)
25049         {
25050             return result;
25051         }
25052 
25053         if (source.type() != target.type())
25054         {
25055             // different types: replace value
25056             result.push_back(
25057             {
25058                 {"op", "replace"}, {"path", path}, {"value", target}
25059             });
25060             return result;
25061         }
25062 
25063         switch (source.type())
25064         {
25065             case value_t::array:
25066             {
25067                 // first pass: traverse common elements
25068                 std::size_t i = 0;
25069                 while (i < source.size() && i < target.size())
25070                 {
25071                     // recursive call to compare array values at index i
25072                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
25073                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25074                     ++i;
25075                 }
25076 
25077                 // i now reached the end of at least one array
25078                 // in a second pass, traverse the remaining elements
25079 
25080                 // remove my remaining elements
25081                 const auto end_index = static_cast<difference_type>(result.size());
25082                 while (i < source.size())
25083                 {
25084                     // add operations in reverse order to avoid invalid
25085                     // indices
25086                     result.insert(result.begin() + end_index, object(
25087                     {
25088                         {"op", "remove"},
25089                         {"path", path + "/" + std::to_string(i)}
25090                     }));
25091                     ++i;
25092                 }
25093 
25094                 // add other remaining elements
25095                 while (i < target.size())
25096                 {
25097                     result.push_back(
25098                     {
25099                         {"op", "add"},
25100                         {"path", path + "/-"},
25101                         {"value", target[i]}
25102                     });
25103                     ++i;
25104                 }
25105 
25106                 break;
25107             }
25108 
25109             case value_t::object:
25110             {
25111                 // first pass: traverse this object's elements
25112                 for (auto it = source.cbegin(); it != source.cend(); ++it)
25113                 {
25114                     // escape the key name to be used in a JSON patch
25115                     const auto key = json_pointer::escape(it.key());
25116 
25117                     if (target.find(it.key()) != target.end())
25118                     {
25119                         // recursive call to compare object values at key it
25120                         auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
25121                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
25122                     }
25123                     else
25124                     {
25125                         // found a key that is not in o -> remove it
25126                         result.push_back(object(
25127                         {
25128                             {"op", "remove"}, {"path", path + "/" + key}
25129                         }));
25130                     }
25131                 }
25132 
25133                 // second pass: traverse other object's elements
25134                 for (auto it = target.cbegin(); it != target.cend(); ++it)
25135                 {
25136                     if (source.find(it.key()) == source.end())
25137                     {
25138                         // found a key that is not in this -> add it
25139                         const auto key = json_pointer::escape(it.key());
25140                         result.push_back(
25141                         {
25142                             {"op", "add"}, {"path", path + "/" + key},
25143                             {"value", it.value()}
25144                         });
25145                     }
25146                 }
25147 
25148                 break;
25149             }
25150 
25151             default:
25152             {
25153                 // both primitive type: replace value
25154                 result.push_back(
25155                 {
25156                     {"op", "replace"}, {"path", path}, {"value", target}
25157                 });
25158                 break;
25159             }
25160         }
25161 
25162         return result;
25163     }
25164 
25165     /// @}
25166 
25167     ////////////////////////////////
25168     // JSON Merge Patch functions //
25169     ////////////////////////////////
25170 
25171     /// @name JSON Merge Patch functions
25172     /// @{
25173 
25174     /*!
25175     @brief applies a JSON Merge Patch
25176 
25177     The merge patch format is primarily intended for use with the HTTP PATCH
25178     method as a means of describing a set of modifications to a target
25179     resource's content. This function applies a merge patch to the current
25180     JSON value.
25181 
25182     The function implements the following algorithm from Section 2 of
25183     [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
25184 
25185     ```
25186     define MergePatch(Target, Patch):
25187       if Patch is an Object:
25188         if Target is not an Object:
25189           Target = {} // Ignore the contents and set it to an empty Object
25190         for each Name/Value pair in Patch:
25191           if Value is null:
25192             if Name exists in Target:
25193               remove the Name/Value pair from Target
25194           else:
25195             Target[Name] = MergePatch(Target[Name], Value)
25196         return Target
25197       else:
25198         return Patch
25199     ```
25200 
25201     Thereby, `Target` is the current object; that is, the patch is applied to
25202     the current value.
25203 
25204     @param[in] apply_patch  the patch to apply
25205 
25206     @complexity Linear in the lengths of @a patch.
25207 
25208     @liveexample{The following code shows how a JSON Merge Patch is applied to
25209     a JSON document.,merge_patch}
25210 
25211     @sa @ref patch -- apply a JSON patch
25212     @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
25213 
25214     @since version 3.0.0
25215     */
merge_patch(const basic_json & apply_patch)25216     void merge_patch(const basic_json& apply_patch)
25217     {
25218         if (apply_patch.is_object())
25219         {
25220             if (!is_object())
25221             {
25222                 *this = object();
25223             }
25224             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
25225             {
25226                 if (it.value().is_null())
25227                 {
25228                     erase(it.key());
25229                 }
25230                 else
25231                 {
25232                     operator[](it.key()).merge_patch(it.value());
25233                 }
25234             }
25235         }
25236         else
25237         {
25238             *this = apply_patch;
25239         }
25240     }
25241 
25242     /// @}
25243 };
25244 
25245 /*!
25246 @brief user-defined to_string function for JSON values
25247 
25248 This function implements a user-defined to_string  for JSON objects.
25249 
25250 @param[in] j  a JSON object
25251 @return a std::string object
25252 */
25253 
25254 NLOHMANN_BASIC_JSON_TPL_DECLARATION
to_string(const NLOHMANN_BASIC_JSON_TPL & j)25255 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
25256 {
25257     return j.dump();
25258 }
25259 } // namespace nlohmann
25260 
25261 ///////////////////////
25262 // nonmember support //
25263 ///////////////////////
25264 
25265 // specialization of std::swap, and std::hash
25266 namespace std
25267 {
25268 
25269 /// hash value for JSON objects
25270 template<>
25271 struct hash<nlohmann::json>
25272 {
25273     /*!
25274     @brief return a hash value for a JSON object
25275 
25276     @since version 1.0.0
25277     */
operator ()std::hash25278     std::size_t operator()(const nlohmann::json& j) const
25279     {
25280         return nlohmann::detail::hash(j);
25281     }
25282 };
25283 
25284 /// specialization for std::less<value_t>
25285 /// @note: do not remove the space after '<',
25286 ///        see https://github.com/nlohmann/json/pull/679
25287 template<>
25288 struct less<::nlohmann::detail::value_t>
25289 {
25290     /*!
25291     @brief compare two value_t enum values
25292     @since version 3.0.0
25293     */
operator ()std::less25294     bool operator()(nlohmann::detail::value_t lhs,
25295                     nlohmann::detail::value_t rhs) const noexcept
25296     {
25297         return nlohmann::detail::operator<(lhs, rhs);
25298     }
25299 };
25300 
25301 // C++20 prohibit function specialization in the std namespace.
25302 #ifndef JSON_HAS_CPP_20
25303 
25304 /*!
25305 @brief exchanges the values of two JSON objects
25306 
25307 @since version 1.0.0
25308 */
25309 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)25310 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
25311     is_nothrow_move_constructible<nlohmann::json>::value&&
25312     is_nothrow_move_assignable<nlohmann::json>::value
25313                               )
25314 {
25315     j1.swap(j2);
25316 }
25317 
25318 #endif
25319 
25320 } // namespace std
25321 
25322 /*!
25323 @brief user-defined string literal for JSON values
25324 
25325 This operator implements a user-defined string literal for JSON objects. It
25326 can be used by adding `"_json"` to a string literal and returns a JSON object
25327 if no parse error occurred.
25328 
25329 @param[in] s  a string representation of a JSON object
25330 @param[in] n  the length of string @a s
25331 @return a JSON object
25332 
25333 @since version 1.0.0
25334 */
25335 JSON_HEDLEY_NON_NULL(1)
operator ""_json(const char * s,std::size_t n)25336 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
25337 {
25338     return nlohmann::json::parse(s, s + n);
25339 }
25340 
25341 /*!
25342 @brief user-defined string literal for JSON pointer
25343 
25344 This operator implements a user-defined string literal for JSON Pointers. It
25345 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
25346 object if no parse error occurred.
25347 
25348 @param[in] s  a string representation of a JSON Pointer
25349 @param[in] n  the length of string @a s
25350 @return a JSON pointer object
25351 
25352 @since version 2.0.0
25353 */
25354 JSON_HEDLEY_NON_NULL(1)
operator ""_json_pointer(const char * s,std::size_t n)25355 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
25356 {
25357     return nlohmann::json::json_pointer(std::string(s, n));
25358 }
25359 
25360 // #include <nlohmann/detail/macro_unscope.hpp>
25361 
25362 
25363 // restore GCC/clang diagnostic settings
25364 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
25365     #pragma GCC diagnostic pop
25366 #endif
25367 #if defined(__clang__)
25368     #pragma GCC diagnostic pop
25369 #endif
25370 
25371 // clean up
25372 #undef JSON_ASSERT
25373 #undef JSON_INTERNAL_CATCH
25374 #undef JSON_CATCH
25375 #undef JSON_THROW
25376 #undef JSON_TRY
25377 #undef JSON_PRIVATE_UNLESS_TESTED
25378 #undef JSON_HAS_CPP_14
25379 #undef JSON_HAS_CPP_17
25380 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
25381 #undef NLOHMANN_BASIC_JSON_TPL
25382 #undef JSON_EXPLICIT
25383 
25384 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
25385 #undef JSON_HEDLEY_ALWAYS_INLINE
25386 #undef JSON_HEDLEY_ARM_VERSION
25387 #undef JSON_HEDLEY_ARM_VERSION_CHECK
25388 #undef JSON_HEDLEY_ARRAY_PARAM
25389 #undef JSON_HEDLEY_ASSUME
25390 #undef JSON_HEDLEY_BEGIN_C_DECLS
25391 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
25392 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
25393 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
25394 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
25395 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
25396 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
25397 #undef JSON_HEDLEY_CLANG_HAS_WARNING
25398 #undef JSON_HEDLEY_COMPCERT_VERSION
25399 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
25400 #undef JSON_HEDLEY_CONCAT
25401 #undef JSON_HEDLEY_CONCAT3
25402 #undef JSON_HEDLEY_CONCAT3_EX
25403 #undef JSON_HEDLEY_CONCAT_EX
25404 #undef JSON_HEDLEY_CONST
25405 #undef JSON_HEDLEY_CONSTEXPR
25406 #undef JSON_HEDLEY_CONST_CAST
25407 #undef JSON_HEDLEY_CPP_CAST
25408 #undef JSON_HEDLEY_CRAY_VERSION
25409 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
25410 #undef JSON_HEDLEY_C_DECL
25411 #undef JSON_HEDLEY_DEPRECATED
25412 #undef JSON_HEDLEY_DEPRECATED_FOR
25413 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
25414 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
25415 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
25416 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
25417 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
25418 #undef JSON_HEDLEY_DIAGNOSTIC_POP
25419 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
25420 #undef JSON_HEDLEY_DMC_VERSION
25421 #undef JSON_HEDLEY_DMC_VERSION_CHECK
25422 #undef JSON_HEDLEY_EMPTY_BASES
25423 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
25424 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
25425 #undef JSON_HEDLEY_END_C_DECLS
25426 #undef JSON_HEDLEY_FLAGS
25427 #undef JSON_HEDLEY_FLAGS_CAST
25428 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
25429 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
25430 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
25431 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
25432 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
25433 #undef JSON_HEDLEY_GCC_HAS_FEATURE
25434 #undef JSON_HEDLEY_GCC_HAS_WARNING
25435 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
25436 #undef JSON_HEDLEY_GCC_VERSION
25437 #undef JSON_HEDLEY_GCC_VERSION_CHECK
25438 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
25439 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
25440 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
25441 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
25442 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
25443 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
25444 #undef JSON_HEDLEY_GNUC_HAS_WARNING
25445 #undef JSON_HEDLEY_GNUC_VERSION
25446 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
25447 #undef JSON_HEDLEY_HAS_ATTRIBUTE
25448 #undef JSON_HEDLEY_HAS_BUILTIN
25449 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
25450 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
25451 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
25452 #undef JSON_HEDLEY_HAS_EXTENSION
25453 #undef JSON_HEDLEY_HAS_FEATURE
25454 #undef JSON_HEDLEY_HAS_WARNING
25455 #undef JSON_HEDLEY_IAR_VERSION
25456 #undef JSON_HEDLEY_IAR_VERSION_CHECK
25457 #undef JSON_HEDLEY_IBM_VERSION
25458 #undef JSON_HEDLEY_IBM_VERSION_CHECK
25459 #undef JSON_HEDLEY_IMPORT
25460 #undef JSON_HEDLEY_INLINE
25461 #undef JSON_HEDLEY_INTEL_CL_VERSION
25462 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
25463 #undef JSON_HEDLEY_INTEL_VERSION
25464 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
25465 #undef JSON_HEDLEY_IS_CONSTANT
25466 #undef JSON_HEDLEY_IS_CONSTEXPR_
25467 #undef JSON_HEDLEY_LIKELY
25468 #undef JSON_HEDLEY_MALLOC
25469 #undef JSON_HEDLEY_MESSAGE
25470 #undef JSON_HEDLEY_MSVC_VERSION
25471 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
25472 #undef JSON_HEDLEY_NEVER_INLINE
25473 #undef JSON_HEDLEY_NON_NULL
25474 #undef JSON_HEDLEY_NO_ESCAPE
25475 #undef JSON_HEDLEY_NO_RETURN
25476 #undef JSON_HEDLEY_NO_THROW
25477 #undef JSON_HEDLEY_NULL
25478 #undef JSON_HEDLEY_PELLES_VERSION
25479 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
25480 #undef JSON_HEDLEY_PGI_VERSION
25481 #undef JSON_HEDLEY_PGI_VERSION_CHECK
25482 #undef JSON_HEDLEY_PREDICT
25483 #undef JSON_HEDLEY_PRINTF_FORMAT
25484 #undef JSON_HEDLEY_PRIVATE
25485 #undef JSON_HEDLEY_PUBLIC
25486 #undef JSON_HEDLEY_PURE
25487 #undef JSON_HEDLEY_REINTERPRET_CAST
25488 #undef JSON_HEDLEY_REQUIRE
25489 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
25490 #undef JSON_HEDLEY_REQUIRE_MSG
25491 #undef JSON_HEDLEY_RESTRICT
25492 #undef JSON_HEDLEY_RETURNS_NON_NULL
25493 #undef JSON_HEDLEY_SENTINEL
25494 #undef JSON_HEDLEY_STATIC_ASSERT
25495 #undef JSON_HEDLEY_STATIC_CAST
25496 #undef JSON_HEDLEY_STRINGIFY
25497 #undef JSON_HEDLEY_STRINGIFY_EX
25498 #undef JSON_HEDLEY_SUNPRO_VERSION
25499 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
25500 #undef JSON_HEDLEY_TINYC_VERSION
25501 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
25502 #undef JSON_HEDLEY_TI_ARMCL_VERSION
25503 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
25504 #undef JSON_HEDLEY_TI_CL2000_VERSION
25505 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
25506 #undef JSON_HEDLEY_TI_CL430_VERSION
25507 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
25508 #undef JSON_HEDLEY_TI_CL6X_VERSION
25509 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
25510 #undef JSON_HEDLEY_TI_CL7X_VERSION
25511 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
25512 #undef JSON_HEDLEY_TI_CLPRU_VERSION
25513 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
25514 #undef JSON_HEDLEY_TI_VERSION
25515 #undef JSON_HEDLEY_TI_VERSION_CHECK
25516 #undef JSON_HEDLEY_UNAVAILABLE
25517 #undef JSON_HEDLEY_UNLIKELY
25518 #undef JSON_HEDLEY_UNPREDICTABLE
25519 #undef JSON_HEDLEY_UNREACHABLE
25520 #undef JSON_HEDLEY_UNREACHABLE_RETURN
25521 #undef JSON_HEDLEY_VERSION
25522 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
25523 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
25524 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
25525 #undef JSON_HEDLEY_VERSION_ENCODE
25526 #undef JSON_HEDLEY_WARNING
25527 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
25528 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
25529 #undef JSON_HEDLEY_FALL_THROUGH
25530 
25531 
25532 
25533 #endif  // INCLUDE_NLOHMANN_JSON_HPP_
25534