1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.6.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 6
35 #define NLOHMANN_JSON_VERSION_PATCH 1
36
37 #include <algorithm> // all_of, find, for_each
38 #include <cassert> // assert
39 #include <ciso646> // and, not, or
40 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
41 #include <functional> // hash, less
42 #include <initializer_list> // initializer_list
43 #include <iosfwd> // istream, ostream
44 #include <iterator> // random_access_iterator_tag
45 #include <memory> // unique_ptr
46 #include <numeric> // accumulate
47 #include <string> // string, stoi, to_string
48 #include <utility> // declval, forward, move, pair, swap
49 #include <vector> // vector
50
51 // #include <nlohmann/adl_serializer.hpp>
52
53
54 #include <utility>
55
56 // #include <nlohmann/detail/conversions/from_json.hpp>
57
58
59 #include <algorithm> // transform
60 #include <array> // array
61 #include <ciso646> // and, not
62 #include <forward_list> // forward_list
63 #include <iterator> // inserter, front_inserter, end
64 #include <map> // map
65 #include <string> // string
66 #include <tuple> // tuple, make_tuple
67 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68 #include <unordered_map> // unordered_map
69 #include <utility> // pair, declval
70 #include <valarray> // valarray
71
72 // #include <nlohmann/detail/exceptions.hpp>
73
74
75 #include <exception> // exception
76 #include <stdexcept> // runtime_error
77 #include <string> // to_string
78
79 // #include <nlohmann/detail/input/position_t.hpp>
80
81
82 #include <cstddef> // size_t
83
84 namespace nlohmann
85 {
86 namespace detail
87 {
88 /// struct to capture the start position of the current token
89 struct position_t
90 {
91 /// the total number of characters read
92 std::size_t chars_read_total = 0;
93 /// the number of characters read in the current line
94 std::size_t chars_read_current_line = 0;
95 /// the number of lines read
96 std::size_t lines_read = 0;
97
98 /// conversion to size_t to preserve SAX interface
operator size_tnlohmann::detail::position_t99 constexpr operator size_t() const
100 {
101 return chars_read_total;
102 }
103 };
104
105 } // namespace detail
106 } // namespace nlohmann
107
108
109 namespace nlohmann
110 {
111 namespace detail
112 {
113 ////////////////
114 // exceptions //
115 ////////////////
116
117 /*!
118 @brief general exception of the @ref basic_json class
119
120 This class is an extension of `std::exception` objects with a member @a id for
121 exception ids. It is used as the base class for all exceptions thrown by the
122 @ref basic_json class. This class can hence be used as "wildcard" to catch
123 exceptions.
124
125 Subclasses:
126 - @ref parse_error for exceptions indicating a parse error
127 - @ref invalid_iterator for exceptions indicating errors with iterators
128 - @ref type_error for exceptions indicating executing a member function with
129 a wrong type
130 - @ref out_of_range for exceptions indicating access out of the defined range
131 - @ref other_error for exceptions indicating other library errors
132
133 @internal
134 @note To have nothrow-copy-constructible exceptions, we internally use
135 `std::runtime_error` which can cope with arbitrary-length error messages.
136 Intermediate strings are built with static functions and then passed to
137 the actual constructor.
138 @endinternal
139
140 @liveexample{The following code shows how arbitrary library exceptions can be
141 caught.,exception}
142
143 @since version 3.0.0
144 */
145 class exception : public std::exception
146 {
147 public:
148 /// returns the explanatory string
what() const149 const char* what() const noexcept override
150 {
151 return m.what();
152 }
153
154 /// the id of the exception
155 const int id;
156
157 protected:
exception(int id_,const char * what_arg)158 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
159
name(const std::string & ename,int id_)160 static std::string name(const std::string& ename, int id_)
161 {
162 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
163 }
164
165 private:
166 /// an exception object as storage for error messages
167 std::runtime_error m;
168 };
169
170 /*!
171 @brief exception indicating a parse error
172
173 This exception is thrown by the library when a parse error occurs. Parse errors
174 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
175 as when using JSON Patch.
176
177 Member @a byte holds the byte index of the last read character in the input
178 file.
179
180 Exceptions have ids 1xx.
181
182 name / id | example message | description
183 ------------------------------ | --------------- | -------------------------
184 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.
185 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.
186 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.
187 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.
188 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.
189 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`.
190 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.
191 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.
192 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
193 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.
194 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.
195 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.
196 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
197
198 @note For an input with n bytes, 1 is the index of the first character and n+1
199 is the index of the terminating null byte or the end of file. This also
200 holds true when reading a byte vector (CBOR or MessagePack).
201
202 @liveexample{The following code shows how a `parse_error` exception can be
203 caught.,parse_error}
204
205 @sa - @ref exception for the base class of the library exceptions
206 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
207 @sa - @ref type_error for exceptions indicating executing a member function with
208 a wrong type
209 @sa - @ref out_of_range for exceptions indicating access out of the defined range
210 @sa - @ref other_error for exceptions indicating other library errors
211
212 @since version 3.0.0
213 */
214 class parse_error : public exception
215 {
216 public:
217 /*!
218 @brief create a parse error exception
219 @param[in] id_ the id of the exception
220 @param[in] pos the position where the error occurred (or with
221 chars_read_total=0 if the position cannot be
222 determined)
223 @param[in] what_arg the explanatory string
224 @return parse_error object
225 */
create(int id_,const position_t & pos,const std::string & what_arg)226 static parse_error create(int id_, const position_t& pos, const std::string& what_arg)
227 {
228 std::string w = exception::name("parse_error", id_) + "parse error" +
229 position_string(pos) + ": " + what_arg;
230 return parse_error(id_, pos.chars_read_total, w.c_str());
231 }
232
create(int id_,std::size_t byte_,const std::string & what_arg)233 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
234 {
235 std::string w = exception::name("parse_error", id_) + "parse error" +
236 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
237 ": " + what_arg;
238 return parse_error(id_, byte_, w.c_str());
239 }
240
241 /*!
242 @brief byte index of the parse error
243
244 The byte index of the last read character in the input file.
245
246 @note For an input with n bytes, 1 is the index of the first character and
247 n+1 is the index of the terminating null byte or the end of file.
248 This also holds true when reading a byte vector (CBOR or MessagePack).
249 */
250 const std::size_t byte;
251
252 private:
parse_error(int id_,std::size_t byte_,const char * what_arg)253 parse_error(int id_, std::size_t byte_, const char* what_arg)
254 : exception(id_, what_arg), byte(byte_) {}
255
position_string(const position_t & pos)256 static std::string position_string(const position_t& pos)
257 {
258 return " at line " + std::to_string(pos.lines_read + 1) +
259 ", column " + std::to_string(pos.chars_read_current_line);
260 }
261 };
262
263 /*!
264 @brief exception indicating errors with iterators
265
266 This exception is thrown if iterators passed to a library function do not match
267 the expected semantics.
268
269 Exceptions have ids 2xx.
270
271 name / id | example message | description
272 ----------------------------------- | --------------- | -------------------------
273 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.
274 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.
275 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.
276 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.
277 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.
278 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.
279 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.
280 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.
281 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.
282 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.
283 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.
284 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
285 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
286 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().
287
288 @liveexample{The following code shows how an `invalid_iterator` exception can be
289 caught.,invalid_iterator}
290
291 @sa - @ref exception for the base class of the library exceptions
292 @sa - @ref parse_error for exceptions indicating a parse error
293 @sa - @ref type_error for exceptions indicating executing a member function with
294 a wrong type
295 @sa - @ref out_of_range for exceptions indicating access out of the defined range
296 @sa - @ref other_error for exceptions indicating other library errors
297
298 @since version 3.0.0
299 */
300 class invalid_iterator : public exception
301 {
302 public:
create(int id_,const std::string & what_arg)303 static invalid_iterator create(int id_, const std::string& what_arg)
304 {
305 std::string w = exception::name("invalid_iterator", id_) + what_arg;
306 return invalid_iterator(id_, w.c_str());
307 }
308
309 private:
invalid_iterator(int id_,const char * what_arg)310 invalid_iterator(int id_, const char* what_arg)
311 : exception(id_, what_arg) {}
312 };
313
314 /*!
315 @brief exception indicating executing a member function with a wrong type
316
317 This exception is thrown in case of a type error; that is, a library function is
318 executed on a JSON value whose type does not match the expected semantics.
319
320 Exceptions have ids 3xx.
321
322 name / id | example message | description
323 ----------------------------- | --------------- | -------------------------
324 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.
325 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.
326 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 &.
327 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
328 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
329 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
330 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
331 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.
332 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
333 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
334 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.
335 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
336 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.
337 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
338 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.
339 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. |
340 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) |
341
342 @liveexample{The following code shows how a `type_error` exception can be
343 caught.,type_error}
344
345 @sa - @ref exception for the base class of the library exceptions
346 @sa - @ref parse_error for exceptions indicating a parse error
347 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
348 @sa - @ref out_of_range for exceptions indicating access out of the defined range
349 @sa - @ref other_error for exceptions indicating other library errors
350
351 @since version 3.0.0
352 */
353 class type_error : public exception
354 {
355 public:
create(int id_,const std::string & what_arg)356 static type_error create(int id_, const std::string& what_arg)
357 {
358 std::string w = exception::name("type_error", id_) + what_arg;
359 return type_error(id_, w.c_str());
360 }
361
362 private:
type_error(int id_,const char * what_arg)363 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
364 };
365
366 /*!
367 @brief exception indicating access out of the defined range
368
369 This exception is thrown in case a library function is called on an input
370 parameter that exceeds the expected range, for instance in case of array
371 indices or nonexisting object keys.
372
373 Exceptions have ids 4xx.
374
375 name / id | example message | description
376 ------------------------------- | --------------- | -------------------------
377 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.
378 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.
379 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
380 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
381 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.
382 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.
383 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. |
384 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
385 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 |
386
387 @liveexample{The following code shows how an `out_of_range` exception can be
388 caught.,out_of_range}
389
390 @sa - @ref exception for the base class of the library exceptions
391 @sa - @ref parse_error for exceptions indicating a parse error
392 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
393 @sa - @ref type_error for exceptions indicating executing a member function with
394 a wrong type
395 @sa - @ref other_error for exceptions indicating other library errors
396
397 @since version 3.0.0
398 */
399 class out_of_range : public exception
400 {
401 public:
create(int id_,const std::string & what_arg)402 static out_of_range create(int id_, const std::string& what_arg)
403 {
404 std::string w = exception::name("out_of_range", id_) + what_arg;
405 return out_of_range(id_, w.c_str());
406 }
407
408 private:
out_of_range(int id_,const char * what_arg)409 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
410 };
411
412 /*!
413 @brief exception indicating other library errors
414
415 This exception is thrown in case of errors that cannot be classified with the
416 other exception types.
417
418 Exceptions have ids 5xx.
419
420 name / id | example message | description
421 ------------------------------ | --------------- | -------------------------
422 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
423
424 @sa - @ref exception for the base class of the library exceptions
425 @sa - @ref parse_error for exceptions indicating a parse error
426 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
427 @sa - @ref type_error for exceptions indicating executing a member function with
428 a wrong type
429 @sa - @ref out_of_range for exceptions indicating access out of the defined range
430
431 @liveexample{The following code shows how an `other_error` exception can be
432 caught.,other_error}
433
434 @since version 3.0.0
435 */
436 class other_error : public exception
437 {
438 public:
create(int id_,const std::string & what_arg)439 static other_error create(int id_, const std::string& what_arg)
440 {
441 std::string w = exception::name("other_error", id_) + what_arg;
442 return other_error(id_, w.c_str());
443 }
444
445 private:
other_error(int id_,const char * what_arg)446 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
447 };
448 } // namespace detail
449 } // namespace nlohmann
450
451 // #include <nlohmann/detail/macro_scope.hpp>
452
453
454 #include <utility> // pair
455
456 // This file contains all internal macro definitions
457 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
458
459 // exclude unsupported compilers
460 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
461 #if defined(__clang__)
462 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
463 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
464 #endif
465 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
466 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
467 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
468 #endif
469 #endif
470 #endif
471
472 // disable float-equal warnings on GCC/clang
473 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
474 #pragma GCC diagnostic push
475 #pragma GCC diagnostic ignored "-Wfloat-equal"
476 #endif
477
478 // disable documentation warnings on clang
479 #if defined(__clang__)
480 #pragma GCC diagnostic push
481 #pragma GCC diagnostic ignored "-Wdocumentation"
482 #endif
483
484 // allow for portable deprecation warnings
485 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
486 #define JSON_DEPRECATED __attribute__((deprecated))
487 #elif defined(_MSC_VER)
488 #define JSON_DEPRECATED __declspec(deprecated)
489 #else
490 #define JSON_DEPRECATED
491 #endif
492
493 // allow for portable nodiscard warnings
494 #if defined(__has_cpp_attribute)
495 #if __has_cpp_attribute(nodiscard)
496 #define JSON_NODISCARD [[nodiscard]]
497 #elif __has_cpp_attribute(gnu::warn_unused_result)
498 #define JSON_NODISCARD [[gnu::warn_unused_result]]
499 #else
500 #define JSON_NODISCARD
501 #endif
502 #else
503 #define JSON_NODISCARD
504 #endif
505
506 // allow to disable exceptions
507 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
508 #define JSON_THROW(exception) throw exception
509 #define JSON_TRY try
510 #define JSON_CATCH(exception) catch(exception)
511 #define JSON_INTERNAL_CATCH(exception) catch(exception)
512 #else
513 #include <cstdlib>
514 #define JSON_THROW(exception) std::abort()
515 #define JSON_TRY if(true)
516 #define JSON_CATCH(exception) if(false)
517 #define JSON_INTERNAL_CATCH(exception) if(false)
518 #endif
519
520 // override exception macros
521 #if defined(JSON_THROW_USER)
522 #undef JSON_THROW
523 #define JSON_THROW JSON_THROW_USER
524 #endif
525 #if defined(JSON_TRY_USER)
526 #undef JSON_TRY
527 #define JSON_TRY JSON_TRY_USER
528 #endif
529 #if defined(JSON_CATCH_USER)
530 #undef JSON_CATCH
531 #define JSON_CATCH JSON_CATCH_USER
532 #undef JSON_INTERNAL_CATCH
533 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
534 #endif
535 #if defined(JSON_INTERNAL_CATCH_USER)
536 #undef JSON_INTERNAL_CATCH
537 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
538 #endif
539
540 // manual branch prediction
541 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
542 #define JSON_LIKELY(x) __builtin_expect(x, 1)
543 #define JSON_UNLIKELY(x) __builtin_expect(x, 0)
544 #else
545 #define JSON_LIKELY(x) x
546 #define JSON_UNLIKELY(x) x
547 #endif
548
549 // C++ language standard detection
550 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
551 #define JSON_HAS_CPP_17
552 #define JSON_HAS_CPP_14
553 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
554 #define JSON_HAS_CPP_14
555 #endif
556
557 /*!
558 @brief macro to briefly define a mapping between an enum and JSON
559 @def NLOHMANN_JSON_SERIALIZE_ENUM
560 @since version 3.4.0
561 */
562 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
563 template<typename BasicJsonType> \
564 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
565 { \
566 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
567 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
568 auto it = std::find_if(std::begin(m), std::end(m), \
569 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
570 { \
571 return ej_pair.first == e; \
572 }); \
573 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
574 } \
575 template<typename BasicJsonType> \
576 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
577 { \
578 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
579 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
580 auto it = std::find_if(std::begin(m), std::end(m), \
581 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
582 { \
583 return ej_pair.second == j; \
584 }); \
585 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
586 }
587
588 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
589 // may be removed in the future once the class is split.
590
591 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
592 template<template<typename, typename, typename...> class ObjectType, \
593 template<typename, typename...> class ArrayType, \
594 class StringType, class BooleanType, class NumberIntegerType, \
595 class NumberUnsignedType, class NumberFloatType, \
596 template<typename> class AllocatorType, \
597 template<typename, typename = void> class JSONSerializer>
598
599 #define NLOHMANN_BASIC_JSON_TPL \
600 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
601 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
602 AllocatorType, JSONSerializer>
603
604 // #include <nlohmann/detail/meta/cpp_future.hpp>
605
606
607 #include <ciso646> // not
608 #include <cstddef> // size_t
609 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
610
611 namespace nlohmann
612 {
613 namespace detail
614 {
615 // alias templates to reduce boilerplate
616 template<bool B, typename T = void>
617 using enable_if_t = typename std::enable_if<B, T>::type;
618
619 template<typename T>
620 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
621
622 // implementation of C++14 index_sequence and affiliates
623 // source: https://stackoverflow.com/a/32223343
624 template<std::size_t... Ints>
625 struct index_sequence
626 {
627 using type = index_sequence;
628 using value_type = std::size_t;
sizenlohmann::detail::index_sequence629 static constexpr std::size_t size() noexcept
630 {
631 return sizeof...(Ints);
632 }
633 };
634
635 template<class Sequence1, class Sequence2>
636 struct merge_and_renumber;
637
638 template<std::size_t... I1, std::size_t... I2>
639 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
640 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
641
642 template<std::size_t N>
643 struct make_index_sequence
644 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
645 typename make_index_sequence < N - N / 2 >::type > {};
646
647 template<> struct make_index_sequence<0> : index_sequence<> {};
648 template<> struct make_index_sequence<1> : index_sequence<0> {};
649
650 template<typename... Ts>
651 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
652
653 // dispatch utility (taken from ranges-v3)
654 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
655 template<> struct priority_tag<0> {};
656
657 // taken from ranges-v3
658 template<typename T>
659 struct static_const
660 {
661 static constexpr T value{};
662 };
663
664 template<typename T>
665 constexpr T static_const<T>::value;
666 } // namespace detail
667 } // namespace nlohmann
668
669 // #include <nlohmann/detail/meta/type_traits.hpp>
670
671
672 #include <ciso646> // not
673 #include <limits> // numeric_limits
674 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
675 #include <utility> // declval
676
677 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
678
679
680 #include <iterator> // random_access_iterator_tag
681
682 // #include <nlohmann/detail/meta/void_t.hpp>
683
684
685 namespace nlohmann
686 {
687 namespace detail
688 {
689 template <typename ...Ts> struct make_void
690 {
691 using type = void;
692 };
693 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
694 } // namespace detail
695 } // namespace nlohmann
696
697 // #include <nlohmann/detail/meta/cpp_future.hpp>
698
699
700 namespace nlohmann
701 {
702 namespace detail
703 {
704 template <typename It, typename = void>
705 struct iterator_types {};
706
707 template <typename It>
708 struct iterator_types <
709 It,
710 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
711 typename It::reference, typename It::iterator_category >>
712 {
713 using difference_type = typename It::difference_type;
714 using value_type = typename It::value_type;
715 using pointer = typename It::pointer;
716 using reference = typename It::reference;
717 using iterator_category = typename It::iterator_category;
718 };
719
720 // This is required as some compilers implement std::iterator_traits in a way that
721 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
722 template <typename T, typename = void>
723 struct iterator_traits
724 {
725 };
726
727 template <typename T>
728 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
729 : iterator_types<T>
730 {
731 };
732
733 template <typename T>
734 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
735 {
736 using iterator_category = std::random_access_iterator_tag;
737 using value_type = T;
738 using difference_type = ptrdiff_t;
739 using pointer = T*;
740 using reference = T&;
741 };
742 } // namespace detail
743 } // namespace nlohmann
744
745 // #include <nlohmann/detail/macro_scope.hpp>
746
747 // #include <nlohmann/detail/meta/cpp_future.hpp>
748
749 // #include <nlohmann/detail/meta/detected.hpp>
750
751
752 #include <type_traits>
753
754 // #include <nlohmann/detail/meta/void_t.hpp>
755
756
757 // http://en.cppreference.com/w/cpp/experimental/is_detected
758 namespace nlohmann
759 {
760 namespace detail
761 {
762 struct nonesuch
763 {
764 nonesuch() = delete;
765 ~nonesuch() = delete;
766 nonesuch(nonesuch const&) = delete;
767 nonesuch(nonesuch const&&) = delete;
768 void operator=(nonesuch const&) = delete;
769 void operator=(nonesuch&&) = delete;
770 };
771
772 template <class Default,
773 class AlwaysVoid,
774 template <class...> class Op,
775 class... Args>
776 struct detector
777 {
778 using value_t = std::false_type;
779 using type = Default;
780 };
781
782 template <class Default, template <class...> class Op, class... Args>
783 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
784 {
785 using value_t = std::true_type;
786 using type = Op<Args...>;
787 };
788
789 template <template <class...> class Op, class... Args>
790 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
791
792 template <template <class...> class Op, class... Args>
793 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
794
795 template <class Default, template <class...> class Op, class... Args>
796 using detected_or = detector<Default, void, Op, Args...>;
797
798 template <class Default, template <class...> class Op, class... Args>
799 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
800
801 template <class Expected, template <class...> class Op, class... Args>
802 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
803
804 template <class To, template <class...> class Op, class... Args>
805 using is_detected_convertible =
806 std::is_convertible<detected_t<Op, Args...>, To>;
807 } // namespace detail
808 } // namespace nlohmann
809
810 // #include <nlohmann/json_fwd.hpp>
811 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
812 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
813
814 #include <cstdint> // int64_t, uint64_t
815 #include <map> // map
816 #include <memory> // allocator
817 #include <string> // string
818 #include <vector> // vector
819
820 /*!
821 @brief namespace for Niels Lohmann
822 @see https://github.com/nlohmann
823 @since version 1.0.0
824 */
825 namespace nlohmann
826 {
827 /*!
828 @brief default JSONSerializer template argument
829
830 This serializer ignores the template arguments and uses ADL
831 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
832 for serialization.
833 */
834 template<typename T = void, typename SFINAE = void>
835 struct adl_serializer;
836
837 template<template<typename U, typename V, typename... Args> class ObjectType =
838 std::map,
839 template<typename U, typename... Args> class ArrayType = std::vector,
840 class StringType = std::string, class BooleanType = bool,
841 class NumberIntegerType = std::int64_t,
842 class NumberUnsignedType = std::uint64_t,
843 class NumberFloatType = double,
844 template<typename U> class AllocatorType = std::allocator,
845 template<typename T, typename SFINAE = void> class JSONSerializer =
846 adl_serializer>
847 class basic_json;
848
849 /*!
850 @brief JSON Pointer
851
852 A JSON pointer defines a string syntax for identifying a specific value
853 within a JSON document. It can be used with functions `at` and
854 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
855
856 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
857
858 @since version 2.0.0
859 */
860 template<typename BasicJsonType>
861 class json_pointer;
862
863 /*!
864 @brief default JSON class
865
866 This type is the default specialization of the @ref basic_json class which
867 uses the standard template types.
868
869 @since version 1.0.0
870 */
871 using json = basic_json<>;
872 } // namespace nlohmann
873
874 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
875
876
877 namespace nlohmann
878 {
879 /*!
880 @brief detail namespace with internal helper functions
881
882 This namespace collects functions that should not be exposed,
883 implementations of some @ref basic_json methods, and meta-programming helpers.
884
885 @since version 2.1.0
886 */
887 namespace detail
888 {
889 /////////////
890 // helpers //
891 /////////////
892
893 // Note to maintainers:
894 //
895 // Every trait in this file expects a non CV-qualified type.
896 // The only exceptions are in the 'aliases for detected' section
897 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
898 //
899 // In this case, T has to be properly CV-qualified to constraint the function arguments
900 // (e.g. to_json(BasicJsonType&, const T&))
901
902 template<typename> struct is_basic_json : std::false_type {};
903
904 NLOHMANN_BASIC_JSON_TPL_DECLARATION
905 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
906
907 //////////////////////////
908 // aliases for detected //
909 //////////////////////////
910
911 template <typename T>
912 using mapped_type_t = typename T::mapped_type;
913
914 template <typename T>
915 using key_type_t = typename T::key_type;
916
917 template <typename T>
918 using value_type_t = typename T::value_type;
919
920 template <typename T>
921 using difference_type_t = typename T::difference_type;
922
923 template <typename T>
924 using pointer_t = typename T::pointer;
925
926 template <typename T>
927 using reference_t = typename T::reference;
928
929 template <typename T>
930 using iterator_category_t = typename T::iterator_category;
931
932 template <typename T>
933 using iterator_t = typename T::iterator;
934
935 template <typename T, typename... Args>
936 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
937
938 template <typename T, typename... Args>
939 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
940
941 template <typename T, typename U>
942 using get_template_function = decltype(std::declval<T>().template get<U>());
943
944 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
945 template <typename BasicJsonType, typename T, typename = void>
946 struct has_from_json : std::false_type {};
947
948 template <typename BasicJsonType, typename T>
949 struct has_from_json<BasicJsonType, T,
950 enable_if_t<not is_basic_json<T>::value>>
951 {
952 using serializer = typename BasicJsonType::template json_serializer<T, void>;
953
954 static constexpr bool value =
955 is_detected_exact<void, from_json_function, serializer,
956 const BasicJsonType&, T&>::value;
957 };
958
959 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
960 // this overload is used for non-default-constructible user-defined-types
961 template <typename BasicJsonType, typename T, typename = void>
962 struct has_non_default_from_json : std::false_type {};
963
964 template<typename BasicJsonType, typename T>
965 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
966 {
967 using serializer = typename BasicJsonType::template json_serializer<T, void>;
968
969 static constexpr bool value =
970 is_detected_exact<T, from_json_function, serializer,
971 const BasicJsonType&>::value;
972 };
973
974 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
975 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
976 template <typename BasicJsonType, typename T, typename = void>
977 struct has_to_json : std::false_type {};
978
979 template <typename BasicJsonType, typename T>
980 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
981 {
982 using serializer = typename BasicJsonType::template json_serializer<T, void>;
983
984 static constexpr bool value =
985 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
986 T>::value;
987 };
988
989
990 ///////////////////
991 // is_ functions //
992 ///////////////////
993
994 template <typename T, typename = void>
995 struct is_iterator_traits : std::false_type {};
996
997 template <typename T>
998 struct is_iterator_traits<iterator_traits<T>>
999 {
1000 private:
1001 using traits = iterator_traits<T>;
1002
1003 public:
1004 static constexpr auto value =
1005 is_detected<value_type_t, traits>::value &&
1006 is_detected<difference_type_t, traits>::value &&
1007 is_detected<pointer_t, traits>::value &&
1008 is_detected<iterator_category_t, traits>::value &&
1009 is_detected<reference_t, traits>::value;
1010 };
1011
1012 // source: https://stackoverflow.com/a/37193089/4116453
1013
1014 template <typename T, typename = void>
1015 struct is_complete_type : std::false_type {};
1016
1017 template <typename T>
1018 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
1019
1020 template <typename BasicJsonType, typename CompatibleObjectType,
1021 typename = void>
1022 struct is_compatible_object_type_impl : std::false_type {};
1023
1024 template <typename BasicJsonType, typename CompatibleObjectType>
1025 struct is_compatible_object_type_impl <
1026 BasicJsonType, CompatibleObjectType,
1027 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
1028 is_detected<key_type_t, CompatibleObjectType>::value >>
1029 {
1030
1031 using object_t = typename BasicJsonType::object_t;
1032
1033 // macOS's is_constructible does not play well with nonesuch...
1034 static constexpr bool value =
1035 std::is_constructible<typename object_t::key_type,
1036 typename CompatibleObjectType::key_type>::value and
1037 std::is_constructible<typename object_t::mapped_type,
1038 typename CompatibleObjectType::mapped_type>::value;
1039 };
1040
1041 template <typename BasicJsonType, typename CompatibleObjectType>
1042 struct is_compatible_object_type
1043 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
1044
1045 template <typename BasicJsonType, typename ConstructibleObjectType,
1046 typename = void>
1047 struct is_constructible_object_type_impl : std::false_type {};
1048
1049 template <typename BasicJsonType, typename ConstructibleObjectType>
1050 struct is_constructible_object_type_impl <
1051 BasicJsonType, ConstructibleObjectType,
1052 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
1053 is_detected<key_type_t, ConstructibleObjectType>::value >>
1054 {
1055 using object_t = typename BasicJsonType::object_t;
1056
1057 static constexpr bool value =
1058 (std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
1059 std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
1060 (has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value or
1061 has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type >::value);
1062 };
1063
1064 template <typename BasicJsonType, typename ConstructibleObjectType>
1065 struct is_constructible_object_type
1066 : is_constructible_object_type_impl<BasicJsonType,
1067 ConstructibleObjectType> {};
1068
1069 template <typename BasicJsonType, typename CompatibleStringType,
1070 typename = void>
1071 struct is_compatible_string_type_impl : std::false_type {};
1072
1073 template <typename BasicJsonType, typename CompatibleStringType>
1074 struct is_compatible_string_type_impl <
1075 BasicJsonType, CompatibleStringType,
1076 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
1077 value_type_t, CompatibleStringType>::value >>
1078 {
1079 static constexpr auto value =
1080 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
1081 };
1082
1083 template <typename BasicJsonType, typename ConstructibleStringType>
1084 struct is_compatible_string_type
1085 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1086
1087 template <typename BasicJsonType, typename ConstructibleStringType,
1088 typename = void>
1089 struct is_constructible_string_type_impl : std::false_type {};
1090
1091 template <typename BasicJsonType, typename ConstructibleStringType>
1092 struct is_constructible_string_type_impl <
1093 BasicJsonType, ConstructibleStringType,
1094 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
1095 value_type_t, ConstructibleStringType>::value >>
1096 {
1097 static constexpr auto value =
1098 std::is_constructible<ConstructibleStringType,
1099 typename BasicJsonType::string_t>::value;
1100 };
1101
1102 template <typename BasicJsonType, typename ConstructibleStringType>
1103 struct is_constructible_string_type
1104 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1105
1106 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
1107 struct is_compatible_array_type_impl : std::false_type {};
1108
1109 template <typename BasicJsonType, typename CompatibleArrayType>
1110 struct is_compatible_array_type_impl <
1111 BasicJsonType, CompatibleArrayType,
1112 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
1113 is_detected<iterator_t, CompatibleArrayType>::value and
1114 // This is needed because json_reverse_iterator has a ::iterator type...
1115 // Therefore it is detected as a CompatibleArrayType.
1116 // The real fix would be to have an Iterable concept.
1117 not is_iterator_traits<
1118 iterator_traits<CompatibleArrayType>>::value >>
1119 {
1120 static constexpr bool value =
1121 std::is_constructible<BasicJsonType,
1122 typename CompatibleArrayType::value_type>::value;
1123 };
1124
1125 template <typename BasicJsonType, typename CompatibleArrayType>
1126 struct is_compatible_array_type
1127 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
1128
1129 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
1130 struct is_constructible_array_type_impl : std::false_type {};
1131
1132 template <typename BasicJsonType, typename ConstructibleArrayType>
1133 struct is_constructible_array_type_impl <
1134 BasicJsonType, ConstructibleArrayType,
1135 enable_if_t<std::is_same<ConstructibleArrayType,
1136 typename BasicJsonType::value_type>::value >>
1137 : std::true_type {};
1138
1139 template <typename BasicJsonType, typename ConstructibleArrayType>
1140 struct is_constructible_array_type_impl <
1141 BasicJsonType, ConstructibleArrayType,
1142 enable_if_t<not std::is_same<ConstructibleArrayType,
1143 typename BasicJsonType::value_type>::value and
1144 is_detected<value_type_t, ConstructibleArrayType>::value and
1145 is_detected<iterator_t, ConstructibleArrayType>::value and
1146 is_complete_type<
1147 detected_t<value_type_t, ConstructibleArrayType>>::value >>
1148 {
1149 static constexpr bool value =
1150 // This is needed because json_reverse_iterator has a ::iterator type,
1151 // furthermore, std::back_insert_iterator (and other iterators) have a base class `iterator`...
1152 // Therefore it is detected as a ConstructibleArrayType.
1153 // The real fix would be to have an Iterable concept.
1154 not is_iterator_traits <
1155 iterator_traits<ConstructibleArrayType >>::value and
1156
1157 (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
1158 has_from_json<BasicJsonType,
1159 typename ConstructibleArrayType::value_type>::value or
1160 has_non_default_from_json <
1161 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
1162 };
1163
1164 template <typename BasicJsonType, typename ConstructibleArrayType>
1165 struct is_constructible_array_type
1166 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
1167
1168 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
1169 typename = void>
1170 struct is_compatible_integer_type_impl : std::false_type {};
1171
1172 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
1173 struct is_compatible_integer_type_impl <
1174 RealIntegerType, CompatibleNumberIntegerType,
1175 enable_if_t<std::is_integral<RealIntegerType>::value and
1176 std::is_integral<CompatibleNumberIntegerType>::value and
1177 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
1178 {
1179 // is there an assert somewhere on overflows?
1180 using RealLimits = std::numeric_limits<RealIntegerType>;
1181 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
1182
1183 static constexpr auto value =
1184 std::is_constructible<RealIntegerType,
1185 CompatibleNumberIntegerType>::value and
1186 CompatibleLimits::is_integer and
1187 RealLimits::is_signed == CompatibleLimits::is_signed;
1188 };
1189
1190 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
1191 struct is_compatible_integer_type
1192 : is_compatible_integer_type_impl<RealIntegerType,
1193 CompatibleNumberIntegerType> {};
1194
1195 template <typename BasicJsonType, typename CompatibleType, typename = void>
1196 struct is_compatible_type_impl: std::false_type {};
1197
1198 template <typename BasicJsonType, typename CompatibleType>
1199 struct is_compatible_type_impl <
1200 BasicJsonType, CompatibleType,
1201 enable_if_t<is_complete_type<CompatibleType>::value >>
1202 {
1203 static constexpr bool value =
1204 has_to_json<BasicJsonType, CompatibleType>::value;
1205 };
1206
1207 template <typename BasicJsonType, typename CompatibleType>
1208 struct is_compatible_type
1209 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
1210 } // namespace detail
1211 } // namespace nlohmann
1212
1213 // #include <nlohmann/detail/value_t.hpp>
1214
1215
1216 #include <array> // array
1217 #include <ciso646> // and
1218 #include <cstddef> // size_t
1219 #include <cstdint> // uint8_t
1220 #include <string> // string
1221
1222 namespace nlohmann
1223 {
1224 namespace detail
1225 {
1226 ///////////////////////////
1227 // JSON type enumeration //
1228 ///////////////////////////
1229
1230 /*!
1231 @brief the JSON type enumeration
1232
1233 This enumeration collects the different JSON types. It is internally used to
1234 distinguish the stored values, and the functions @ref basic_json::is_null(),
1235 @ref basic_json::is_object(), @ref basic_json::is_array(),
1236 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
1237 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
1238 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
1239 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
1240 @ref basic_json::is_structured() rely on it.
1241
1242 @note There are three enumeration entries (number_integer, number_unsigned, and
1243 number_float), because the library distinguishes these three types for numbers:
1244 @ref basic_json::number_unsigned_t is used for unsigned integers,
1245 @ref basic_json::number_integer_t is used for signed integers, and
1246 @ref basic_json::number_float_t is used for floating-point numbers or to
1247 approximate integers which do not fit in the limits of their respective type.
1248
1249 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
1250 value with the default value for a given type
1251
1252 @since version 1.0.0
1253 */
1254 enum class value_t : std::uint8_t
1255 {
1256 null, ///< null value
1257 object, ///< object (unordered set of name/value pairs)
1258 array, ///< array (ordered collection of values)
1259 string, ///< string value
1260 boolean, ///< boolean value
1261 number_integer, ///< number value (signed integer)
1262 number_unsigned, ///< number value (unsigned integer)
1263 number_float, ///< number value (floating-point)
1264 discarded ///< discarded by the the parser callback function
1265 };
1266
1267 /*!
1268 @brief comparison operator for JSON types
1269
1270 Returns an ordering that is similar to Python:
1271 - order: null < boolean < number < object < array < string
1272 - furthermore, each type is not smaller than itself
1273 - discarded values are not comparable
1274
1275 @since version 1.0.0
1276 */
operator <(const value_t lhs,const value_t rhs)1277 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
1278 {
1279 static constexpr std::array<std::uint8_t, 8> order = {{
1280 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1281 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
1282 }
1283 };
1284
1285 const auto l_index = static_cast<std::size_t>(lhs);
1286 const auto r_index = static_cast<std::size_t>(rhs);
1287 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1288 }
1289 } // namespace detail
1290 } // namespace nlohmann
1291
1292
1293 namespace nlohmann
1294 {
1295 namespace detail
1296 {
1297 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)1298 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
1299 {
1300 if (JSON_UNLIKELY(not j.is_null()))
1301 {
1302 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
1303 }
1304 n = nullptr;
1305 }
1306
1307 // overloads for basic_json template parameters
1308 template<typename BasicJsonType, typename ArithmeticType,
1309 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1310 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1311 int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1312 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1313 {
1314 switch (static_cast<value_t>(j))
1315 {
1316 case value_t::number_unsigned:
1317 {
1318 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1319 break;
1320 }
1321 case value_t::number_integer:
1322 {
1323 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1324 break;
1325 }
1326 case value_t::number_float:
1327 {
1328 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1329 break;
1330 }
1331
1332 default:
1333 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1334 }
1335 }
1336
1337 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1338 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1339 {
1340 if (JSON_UNLIKELY(not j.is_boolean()))
1341 {
1342 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1343 }
1344 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1345 }
1346
1347 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1348 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1349 {
1350 if (JSON_UNLIKELY(not j.is_string()))
1351 {
1352 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1353 }
1354 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1355 }
1356
1357 template <
1358 typename BasicJsonType, typename ConstructibleStringType,
1359 enable_if_t <
1360 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
1361 not std::is_same<typename BasicJsonType::string_t,
1362 ConstructibleStringType>::value,
1363 int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)1364 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
1365 {
1366 if (JSON_UNLIKELY(not j.is_string()))
1367 {
1368 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1369 }
1370
1371 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1372 }
1373
1374 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1375 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1376 {
1377 get_arithmetic_value(j, val);
1378 }
1379
1380 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1381 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1382 {
1383 get_arithmetic_value(j, val);
1384 }
1385
1386 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1387 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1388 {
1389 get_arithmetic_value(j, val);
1390 }
1391
1392 template<typename BasicJsonType, typename EnumType,
1393 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1394 void from_json(const BasicJsonType& j, EnumType& e)
1395 {
1396 typename std::underlying_type<EnumType>::type val;
1397 get_arithmetic_value(j, val);
1398 e = static_cast<EnumType>(val);
1399 }
1400
1401 // forward_list doesn't have an insert method
1402 template<typename BasicJsonType, typename T, typename Allocator,
1403 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1404 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1405 {
1406 if (JSON_UNLIKELY(not j.is_array()))
1407 {
1408 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1409 }
1410 std::transform(j.rbegin(), j.rend(),
1411 std::front_inserter(l), [](const BasicJsonType & i)
1412 {
1413 return i.template get<T>();
1414 });
1415 }
1416
1417 // valarray doesn't have an insert method
1418 template<typename BasicJsonType, typename T,
1419 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1420 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1421 {
1422 if (JSON_UNLIKELY(not j.is_array()))
1423 {
1424 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1425 }
1426 l.resize(j.size());
1427 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1428 }
1429
1430 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)1431 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
1432 {
1433 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1434 }
1435
1436 template <typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1437 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
1438 priority_tag<2> /*unused*/)
1439 -> decltype(j.template get<T>(), void())
1440 {
1441 for (std::size_t i = 0; i < N; ++i)
1442 {
1443 arr[i] = j.at(i).template get<T>();
1444 }
1445 }
1446
1447 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)1448 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
1449 -> decltype(
1450 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1451 j.template get<typename ConstructibleArrayType::value_type>(),
1452 void())
1453 {
1454 using std::end;
1455
1456 arr.reserve(j.size());
1457 std::transform(j.begin(), j.end(),
1458 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1459 {
1460 // get<BasicJsonType>() returns *this, this won't call a from_json
1461 // method when value_type is BasicJsonType
1462 return i.template get<typename ConstructibleArrayType::value_type>();
1463 });
1464 }
1465
1466 template <typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)1467 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
1468 priority_tag<0> /*unused*/)
1469 {
1470 using std::end;
1471
1472 std::transform(
1473 j.begin(), j.end(), std::inserter(arr, end(arr)),
1474 [](const BasicJsonType & i)
1475 {
1476 // get<BasicJsonType>() returns *this, this won't call a from_json
1477 // method when value_type is BasicJsonType
1478 return i.template get<typename ConstructibleArrayType::value_type>();
1479 });
1480 }
1481
1482 template <typename BasicJsonType, typename ConstructibleArrayType,
1483 enable_if_t <
1484 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
1485 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
1486 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
1487 not is_basic_json<ConstructibleArrayType>::value,
1488 int > = 0 >
1489
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)1490 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
1491 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1492 j.template get<typename ConstructibleArrayType::value_type>(),
1493 void())
1494 {
1495 if (JSON_UNLIKELY(not j.is_array()))
1496 {
1497 JSON_THROW(type_error::create(302, "type must be array, but is " +
1498 std::string(j.type_name())));
1499 }
1500
1501 from_json_array_impl(j, arr, priority_tag<3> {});
1502 }
1503
1504 template<typename BasicJsonType, typename ConstructibleObjectType,
1505 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)1506 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
1507 {
1508 if (JSON_UNLIKELY(not j.is_object()))
1509 {
1510 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1511 }
1512
1513 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1514 using value_type = typename ConstructibleObjectType::value_type;
1515 std::transform(
1516 inner_object->begin(), inner_object->end(),
1517 std::inserter(obj, obj.begin()),
1518 [](typename BasicJsonType::object_t::value_type const & p)
1519 {
1520 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1521 });
1522 }
1523
1524 // overload for arithmetic types, not chosen for basic_json template arguments
1525 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1526 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1527 // an arithmetic type?
1528 template<typename BasicJsonType, typename ArithmeticType,
1529 enable_if_t <
1530 std::is_arithmetic<ArithmeticType>::value and
1531 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1532 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1533 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1534 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1535 int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1536 void from_json(const BasicJsonType& j, ArithmeticType& val)
1537 {
1538 switch (static_cast<value_t>(j))
1539 {
1540 case value_t::number_unsigned:
1541 {
1542 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1543 break;
1544 }
1545 case value_t::number_integer:
1546 {
1547 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1548 break;
1549 }
1550 case value_t::number_float:
1551 {
1552 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1553 break;
1554 }
1555 case value_t::boolean:
1556 {
1557 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1558 break;
1559 }
1560
1561 default:
1562 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1563 }
1564 }
1565
1566 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1567 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1568 {
1569 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1570 }
1571
1572 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1573 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
1574 {
1575 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1576 }
1577
1578 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1579 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1580 {
1581 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1582 }
1583
1584 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1585 typename = enable_if_t<not std::is_constructible<
1586 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)1587 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1588 {
1589 if (JSON_UNLIKELY(not j.is_array()))
1590 {
1591 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1592 }
1593 for (const auto& p : j)
1594 {
1595 if (JSON_UNLIKELY(not p.is_array()))
1596 {
1597 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1598 }
1599 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1600 }
1601 }
1602
1603 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1604 typename = enable_if_t<not std::is_constructible<
1605 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)1606 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1607 {
1608 if (JSON_UNLIKELY(not j.is_array()))
1609 {
1610 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1611 }
1612 for (const auto& p : j)
1613 {
1614 if (JSON_UNLIKELY(not p.is_array()))
1615 {
1616 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1617 }
1618 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1619 }
1620 }
1621
1622 struct from_json_fn
1623 {
1624 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1625 auto operator()(const BasicJsonType& j, T& val) const
1626 noexcept(noexcept(from_json(j, val)))
1627 -> decltype(from_json(j, val), void())
1628 {
1629 return from_json(j, val);
1630 }
1631 };
1632 } // namespace detail
1633
1634 /// namespace to hold default `from_json` function
1635 /// to see why this is required:
1636 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1637 namespace
1638 {
1639 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1640 } // namespace
1641 } // namespace nlohmann
1642
1643 // #include <nlohmann/detail/conversions/to_json.hpp>
1644
1645
1646 #include <algorithm> // copy
1647 #include <ciso646> // or, and, not
1648 #include <iterator> // begin, end
1649 #include <string> // string
1650 #include <tuple> // tuple, get
1651 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1652 #include <utility> // move, forward, declval, pair
1653 #include <valarray> // valarray
1654 #include <vector> // vector
1655
1656 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1657
1658
1659 #include <cstddef> // size_t
1660 #include <iterator> // input_iterator_tag
1661 #include <string> // string, to_string
1662 #include <tuple> // tuple_size, get, tuple_element
1663
1664 // #include <nlohmann/detail/meta/type_traits.hpp>
1665
1666 // #include <nlohmann/detail/value_t.hpp>
1667
1668
1669 namespace nlohmann
1670 {
1671 namespace detail
1672 {
1673 template <typename IteratorType> class iteration_proxy_value
1674 {
1675 public:
1676 using difference_type = std::ptrdiff_t;
1677 using value_type = iteration_proxy_value;
1678 using pointer = value_type * ;
1679 using reference = value_type & ;
1680 using iterator_category = std::input_iterator_tag;
1681
1682 private:
1683 /// the iterator
1684 IteratorType anchor;
1685 /// an index for arrays (used to create key names)
1686 std::size_t array_index = 0;
1687 /// last stringified array index
1688 mutable std::size_t array_index_last = 0;
1689 /// a string representation of the array index
1690 mutable std::string array_index_str = "0";
1691 /// an empty string (to return a reference for primitive values)
1692 const std::string empty_str = "";
1693
1694 public:
iteration_proxy_value(IteratorType it)1695 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
1696
1697 /// dereference operator (needed for range-based for)
operator *()1698 iteration_proxy_value& operator*()
1699 {
1700 return *this;
1701 }
1702
1703 /// increment operator (needed for range-based for)
operator ++()1704 iteration_proxy_value& operator++()
1705 {
1706 ++anchor;
1707 ++array_index;
1708
1709 return *this;
1710 }
1711
1712 /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const1713 bool operator==(const iteration_proxy_value& o) const
1714 {
1715 return anchor == o.anchor;
1716 }
1717
1718 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const1719 bool operator!=(const iteration_proxy_value& o) const
1720 {
1721 return anchor != o.anchor;
1722 }
1723
1724 /// return key of the iterator
key() const1725 const std::string& key() const
1726 {
1727 assert(anchor.m_object != nullptr);
1728
1729 switch (anchor.m_object->type())
1730 {
1731 // use integer array index as key
1732 case value_t::array:
1733 {
1734 if (array_index != array_index_last)
1735 {
1736 array_index_str = std::to_string(array_index);
1737 array_index_last = array_index;
1738 }
1739 return array_index_str;
1740 }
1741
1742 // use key from the object
1743 case value_t::object:
1744 return anchor.key();
1745
1746 // use an empty key for all primitive types
1747 default:
1748 return empty_str;
1749 }
1750 }
1751
1752 /// return value of the iterator
value() const1753 typename IteratorType::reference value() const
1754 {
1755 return anchor.value();
1756 }
1757 };
1758
1759 /// proxy class for the items() function
1760 template<typename IteratorType> class iteration_proxy
1761 {
1762 private:
1763 /// the container to iterate
1764 typename IteratorType::reference container;
1765
1766 public:
1767 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)1768 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1769 : container(cont) {}
1770
1771 /// return iterator begin (needed for range-based for)
begin()1772 iteration_proxy_value<IteratorType> begin() noexcept
1773 {
1774 return iteration_proxy_value<IteratorType>(container.begin());
1775 }
1776
1777 /// return iterator end (needed for range-based for)
end()1778 iteration_proxy_value<IteratorType> end() noexcept
1779 {
1780 return iteration_proxy_value<IteratorType>(container.end());
1781 }
1782 };
1783 // Structured Bindings Support
1784 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1785 // And see https://github.com/nlohmann/json/pull/1391
1786 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)1787 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
1788 {
1789 return i.key();
1790 }
1791 // Structured Bindings Support
1792 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1793 // And see https://github.com/nlohmann/json/pull/1391
1794 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)1795 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
1796 {
1797 return i.value();
1798 }
1799 } // namespace detail
1800 } // namespace nlohmann
1801
1802 // The Addition to the STD Namespace is required to add
1803 // Structured Bindings Support to the iteration_proxy_value class
1804 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1805 // And see https://github.com/nlohmann/json/pull/1391
1806 namespace std
1807 {
1808 #if defined(__clang__)
1809 // Fix: https://github.com/nlohmann/json/issues/1401
1810 #pragma clang diagnostic push
1811 #pragma clang diagnostic ignored "-Wmismatched-tags"
1812 #endif
1813 template <typename IteratorType>
1814 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
1815 : public std::integral_constant<std::size_t, 2> {};
1816
1817 template <std::size_t N, typename IteratorType>
1818 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
1819 {
1820 public:
1821 using type = decltype(
1822 get<N>(std::declval <
1823 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
1824 };
1825 #if defined(__clang__)
1826 #pragma clang diagnostic pop
1827 #endif
1828 } // namespace std
1829
1830 // #include <nlohmann/detail/meta/cpp_future.hpp>
1831
1832 // #include <nlohmann/detail/meta/type_traits.hpp>
1833
1834 // #include <nlohmann/detail/value_t.hpp>
1835
1836
1837 namespace nlohmann
1838 {
1839 namespace detail
1840 {
1841 //////////////////
1842 // constructors //
1843 //////////////////
1844
1845 template<value_t> struct external_constructor;
1846
1847 template<>
1848 struct external_constructor<value_t::boolean>
1849 {
1850 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1851 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1852 {
1853 j.m_type = value_t::boolean;
1854 j.m_value = b;
1855 j.assert_invariant();
1856 }
1857 };
1858
1859 template<>
1860 struct external_constructor<value_t::string>
1861 {
1862 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1863 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1864 {
1865 j.m_type = value_t::string;
1866 j.m_value = s;
1867 j.assert_invariant();
1868 }
1869
1870 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1871 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1872 {
1873 j.m_type = value_t::string;
1874 j.m_value = std::move(s);
1875 j.assert_invariant();
1876 }
1877
1878 template<typename BasicJsonType, typename CompatibleStringType,
1879 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1880 int> = 0>
constructnlohmann::detail::external_constructor1881 static void construct(BasicJsonType& j, const CompatibleStringType& str)
1882 {
1883 j.m_type = value_t::string;
1884 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1885 j.assert_invariant();
1886 }
1887 };
1888
1889 template<>
1890 struct external_constructor<value_t::number_float>
1891 {
1892 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1893 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1894 {
1895 j.m_type = value_t::number_float;
1896 j.m_value = val;
1897 j.assert_invariant();
1898 }
1899 };
1900
1901 template<>
1902 struct external_constructor<value_t::number_unsigned>
1903 {
1904 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1905 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1906 {
1907 j.m_type = value_t::number_unsigned;
1908 j.m_value = val;
1909 j.assert_invariant();
1910 }
1911 };
1912
1913 template<>
1914 struct external_constructor<value_t::number_integer>
1915 {
1916 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1917 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1918 {
1919 j.m_type = value_t::number_integer;
1920 j.m_value = val;
1921 j.assert_invariant();
1922 }
1923 };
1924
1925 template<>
1926 struct external_constructor<value_t::array>
1927 {
1928 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1929 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1930 {
1931 j.m_type = value_t::array;
1932 j.m_value = arr;
1933 j.assert_invariant();
1934 }
1935
1936 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1937 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1938 {
1939 j.m_type = value_t::array;
1940 j.m_value = std::move(arr);
1941 j.assert_invariant();
1942 }
1943
1944 template<typename BasicJsonType, typename CompatibleArrayType,
1945 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1946 int> = 0>
constructnlohmann::detail::external_constructor1947 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1948 {
1949 using std::begin;
1950 using std::end;
1951 j.m_type = value_t::array;
1952 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1953 j.assert_invariant();
1954 }
1955
1956 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1957 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1958 {
1959 j.m_type = value_t::array;
1960 j.m_value = value_t::array;
1961 j.m_value.array->reserve(arr.size());
1962 for (const bool x : arr)
1963 {
1964 j.m_value.array->push_back(x);
1965 }
1966 j.assert_invariant();
1967 }
1968
1969 template<typename BasicJsonType, typename T,
1970 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor1971 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
1972 {
1973 j.m_type = value_t::array;
1974 j.m_value = value_t::array;
1975 j.m_value.array->resize(arr.size());
1976 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
1977 j.assert_invariant();
1978 }
1979 };
1980
1981 template<>
1982 struct external_constructor<value_t::object>
1983 {
1984 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1985 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
1986 {
1987 j.m_type = value_t::object;
1988 j.m_value = obj;
1989 j.assert_invariant();
1990 }
1991
1992 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1993 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1994 {
1995 j.m_type = value_t::object;
1996 j.m_value = std::move(obj);
1997 j.assert_invariant();
1998 }
1999
2000 template<typename BasicJsonType, typename CompatibleObjectType,
2001 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor2002 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
2003 {
2004 using std::begin;
2005 using std::end;
2006
2007 j.m_type = value_t::object;
2008 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
2009 j.assert_invariant();
2010 }
2011 };
2012
2013 /////////////
2014 // to_json //
2015 /////////////
2016
2017 template<typename BasicJsonType, typename T,
2018 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)2019 void to_json(BasicJsonType& j, T b) noexcept
2020 {
2021 external_constructor<value_t::boolean>::construct(j, b);
2022 }
2023
2024 template<typename BasicJsonType, typename CompatibleString,
2025 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)2026 void to_json(BasicJsonType& j, const CompatibleString& s)
2027 {
2028 external_constructor<value_t::string>::construct(j, s);
2029 }
2030
2031 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)2032 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
2033 {
2034 external_constructor<value_t::string>::construct(j, std::move(s));
2035 }
2036
2037 template<typename BasicJsonType, typename FloatType,
2038 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)2039 void to_json(BasicJsonType& j, FloatType val) noexcept
2040 {
2041 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
2042 }
2043
2044 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
2045 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)2046 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
2047 {
2048 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
2049 }
2050
2051 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
2052 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)2053 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
2054 {
2055 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
2056 }
2057
2058 template<typename BasicJsonType, typename EnumType,
2059 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)2060 void to_json(BasicJsonType& j, EnumType e) noexcept
2061 {
2062 using underlying_type = typename std::underlying_type<EnumType>::type;
2063 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
2064 }
2065
2066 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)2067 void to_json(BasicJsonType& j, const std::vector<bool>& e)
2068 {
2069 external_constructor<value_t::array>::construct(j, e);
2070 }
2071
2072 template <typename BasicJsonType, typename CompatibleArrayType,
2073 enable_if_t<is_compatible_array_type<BasicJsonType,
2074 CompatibleArrayType>::value and
2075 not is_compatible_object_type<
2076 BasicJsonType, CompatibleArrayType>::value and
2077 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
2078 not is_basic_json<CompatibleArrayType>::value,
2079 int> = 0>
to_json(BasicJsonType & j,const CompatibleArrayType & arr)2080 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
2081 {
2082 external_constructor<value_t::array>::construct(j, arr);
2083 }
2084
2085 template<typename BasicJsonType, typename T,
2086 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)2087 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
2088 {
2089 external_constructor<value_t::array>::construct(j, std::move(arr));
2090 }
2091
2092 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)2093 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
2094 {
2095 external_constructor<value_t::array>::construct(j, std::move(arr));
2096 }
2097
2098 template<typename BasicJsonType, typename CompatibleObjectType,
2099 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleObjectType & obj)2100 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
2101 {
2102 external_constructor<value_t::object>::construct(j, obj);
2103 }
2104
2105 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)2106 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
2107 {
2108 external_constructor<value_t::object>::construct(j, std::move(obj));
2109 }
2110
2111 template <
2112 typename BasicJsonType, typename T, std::size_t N,
2113 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
2114 const T(&)[N]>::value,
2115 int> = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])2116 void to_json(BasicJsonType& j, const T(&arr)[N])
2117 {
2118 external_constructor<value_t::array>::construct(j, arr);
2119 }
2120
2121 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)2122 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
2123 {
2124 j = { p.first, p.second };
2125 }
2126
2127 // for https://github.com/nlohmann/json/pull/1134
2128 template < typename BasicJsonType, typename T,
2129 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)2130 void to_json(BasicJsonType& j, const T& b)
2131 {
2132 j = { {b.key(), b.value()} };
2133 }
2134
2135 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)2136 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
2137 {
2138 j = { std::get<Idx>(t)... };
2139 }
2140
2141 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)2142 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
2143 {
2144 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
2145 }
2146
2147 struct to_json_fn
2148 {
2149 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn2150 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
2151 -> decltype(to_json(j, std::forward<T>(val)), void())
2152 {
2153 return to_json(j, std::forward<T>(val));
2154 }
2155 };
2156 } // namespace detail
2157
2158 /// namespace to hold default `to_json` function
2159 namespace
2160 {
2161 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
2162 } // namespace
2163 } // namespace nlohmann
2164
2165
2166 namespace nlohmann
2167 {
2168
2169 template<typename, typename>
2170 struct adl_serializer
2171 {
2172 /*!
2173 @brief convert a JSON value to any value type
2174
2175 This function is usually called by the `get()` function of the
2176 @ref basic_json class (either explicit or via conversion operators).
2177
2178 @param[in] j JSON value to read from
2179 @param[in,out] val value to write to
2180 */
2181 template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer2182 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
2183 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
2184 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
2185 {
2186 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
2187 }
2188
2189 /*!
2190 @brief convert any value type to a JSON value
2191
2192 This function is usually called by the constructors of the @ref basic_json
2193 class.
2194
2195 @param[in,out] j JSON value to write to
2196 @param[in] val value to read from
2197 */
2198 template <typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer2199 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
2200 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
2201 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
2202 {
2203 ::nlohmann::to_json(j, std::forward<ValueType>(val));
2204 }
2205 };
2206
2207 } // namespace nlohmann
2208
2209 // #include <nlohmann/detail/conversions/from_json.hpp>
2210
2211 // #include <nlohmann/detail/conversions/to_json.hpp>
2212
2213 // #include <nlohmann/detail/exceptions.hpp>
2214
2215 // #include <nlohmann/detail/input/binary_reader.hpp>
2216
2217
2218 #include <algorithm> // generate_n
2219 #include <array> // array
2220 #include <cassert> // assert
2221 #include <cmath> // ldexp
2222 #include <cstddef> // size_t
2223 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
2224 #include <cstdio> // snprintf
2225 #include <cstring> // memcpy
2226 #include <iterator> // back_inserter
2227 #include <limits> // numeric_limits
2228 #include <string> // char_traits, string
2229 #include <utility> // make_pair, move
2230
2231 // #include <nlohmann/detail/exceptions.hpp>
2232
2233 // #include <nlohmann/detail/input/input_adapters.hpp>
2234
2235
2236 #include <array> // array
2237 #include <cassert> // assert
2238 #include <cstddef> // size_t
2239 #include <cstdio> //FILE *
2240 #include <cstring> // strlen
2241 #include <istream> // istream
2242 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
2243 #include <memory> // shared_ptr, make_shared, addressof
2244 #include <numeric> // accumulate
2245 #include <string> // string, char_traits
2246 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
2247 #include <utility> // pair, declval
2248
2249 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2250
2251 // #include <nlohmann/detail/macro_scope.hpp>
2252
2253
2254 namespace nlohmann
2255 {
2256 namespace detail
2257 {
2258 /// the supported input formats
2259 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
2260
2261 ////////////////////
2262 // input adapters //
2263 ////////////////////
2264
2265 /*!
2266 @brief abstract input adapter interface
2267
2268 Produces a stream of std::char_traits<char>::int_type characters from a
2269 std::istream, a buffer, or some other input type. Accepts the return of
2270 exactly one non-EOF character for future input. The int_type characters
2271 returned consist of all valid char values as positive values (typically
2272 unsigned char), plus an EOF value outside that range, specified by the value
2273 of the function std::char_traits<char>::eof(). This value is typically -1, but
2274 could be any arbitrary value which is not a valid char value.
2275 */
2276 struct input_adapter_protocol
2277 {
2278 /// get a character [0,255] or std::char_traits<char>::eof().
2279 virtual std::char_traits<char>::int_type get_character() = 0;
2280 virtual ~input_adapter_protocol() = default;
2281 };
2282
2283 /// a type to simplify interfaces
2284 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2285
2286 /*!
2287 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
2288 buffer. This adapter is a very low level adapter.
2289 */
2290 class file_input_adapter : public input_adapter_protocol
2291 {
2292 public:
file_input_adapter(std::FILE * f)2293 explicit file_input_adapter(std::FILE* f) noexcept
2294 : m_file(f)
2295 {}
2296
2297 // make class move-only
2298 file_input_adapter(const file_input_adapter&) = delete;
2299 file_input_adapter(file_input_adapter&&) = default;
2300 file_input_adapter& operator=(const file_input_adapter&) = delete;
2301 file_input_adapter& operator=(file_input_adapter&&) = default;
2302 ~file_input_adapter() override = default;
2303
get_character()2304 std::char_traits<char>::int_type get_character() noexcept override
2305 {
2306 return std::fgetc(m_file);
2307 }
2308
2309 private:
2310 /// the file pointer to read from
2311 std::FILE* m_file;
2312 };
2313
2314
2315 /*!
2316 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
2317 beginning of input. Does not support changing the underlying std::streambuf
2318 in mid-input. Maintains underlying std::istream and std::streambuf to support
2319 subsequent use of standard std::istream operations to process any input
2320 characters following those used in parsing the JSON input. Clears the
2321 std::istream flags; any input errors (e.g., EOF) will be detected by the first
2322 subsequent call for input from the std::istream.
2323 */
2324 class input_stream_adapter : public input_adapter_protocol
2325 {
2326 public:
~input_stream_adapter()2327 ~input_stream_adapter() override
2328 {
2329 // clear stream flags; we use underlying streambuf I/O, do not
2330 // maintain ifstream flags, except eof
2331 is.clear(is.rdstate() & std::ios::eofbit);
2332 }
2333
input_stream_adapter(std::istream & i)2334 explicit input_stream_adapter(std::istream& i)
2335 : is(i), sb(*i.rdbuf())
2336 {}
2337
2338 // delete because of pointer members
2339 input_stream_adapter(const input_stream_adapter&) = delete;
2340 input_stream_adapter& operator=(input_stream_adapter&) = delete;
2341 input_stream_adapter(input_stream_adapter&&) = delete;
2342 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
2343
2344 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
2345 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
2346 // end up as the same value, eg. 0xFFFFFFFF.
get_character()2347 std::char_traits<char>::int_type get_character() override
2348 {
2349 auto res = sb.sbumpc();
2350 // set eof manually, as we don't use the istream interface.
2351 if (res == EOF)
2352 {
2353 is.clear(is.rdstate() | std::ios::eofbit);
2354 }
2355 return res;
2356 }
2357
2358 private:
2359 /// the associated input stream
2360 std::istream& is;
2361 std::streambuf& sb;
2362 };
2363
2364 /// input adapter for buffer input
2365 class input_buffer_adapter : public input_adapter_protocol
2366 {
2367 public:
input_buffer_adapter(const char * b,const std::size_t l)2368 input_buffer_adapter(const char* b, const std::size_t l) noexcept
2369 : cursor(b), limit(b + l)
2370 {}
2371
2372 // delete because of pointer members
2373 input_buffer_adapter(const input_buffer_adapter&) = delete;
2374 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
2375 input_buffer_adapter(input_buffer_adapter&&) = delete;
2376 input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
2377 ~input_buffer_adapter() override = default;
2378
get_character()2379 std::char_traits<char>::int_type get_character() noexcept override
2380 {
2381 if (JSON_LIKELY(cursor < limit))
2382 {
2383 return std::char_traits<char>::to_int_type(*(cursor++));
2384 }
2385
2386 return std::char_traits<char>::eof();
2387 }
2388
2389 private:
2390 /// pointer to the current character
2391 const char* cursor;
2392 /// pointer past the last character
2393 const char* const limit;
2394 };
2395
2396 template<typename WideStringType, size_t T>
2397 struct wide_string_input_helper
2398 {
2399 // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper2400 static void fill_buffer(const WideStringType& str,
2401 size_t& current_wchar,
2402 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2403 size_t& utf8_bytes_index,
2404 size_t& utf8_bytes_filled)
2405 {
2406 utf8_bytes_index = 0;
2407
2408 if (current_wchar == str.size())
2409 {
2410 utf8_bytes[0] = std::char_traits<char>::eof();
2411 utf8_bytes_filled = 1;
2412 }
2413 else
2414 {
2415 // get the current character
2416 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2417
2418 // UTF-32 to UTF-8 encoding
2419 if (wc < 0x80)
2420 {
2421 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2422 utf8_bytes_filled = 1;
2423 }
2424 else if (wc <= 0x7FF)
2425 {
2426 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
2427 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2428 utf8_bytes_filled = 2;
2429 }
2430 else if (wc <= 0xFFFF)
2431 {
2432 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
2433 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2434 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2435 utf8_bytes_filled = 3;
2436 }
2437 else if (wc <= 0x10FFFF)
2438 {
2439 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
2440 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
2441 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2442 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2443 utf8_bytes_filled = 4;
2444 }
2445 else
2446 {
2447 // unknown character
2448 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2449 utf8_bytes_filled = 1;
2450 }
2451 }
2452 }
2453 };
2454
2455 template<typename WideStringType>
2456 struct wide_string_input_helper<WideStringType, 2>
2457 {
2458 // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper2459 static void fill_buffer(const WideStringType& str,
2460 size_t& current_wchar,
2461 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2462 size_t& utf8_bytes_index,
2463 size_t& utf8_bytes_filled)
2464 {
2465 utf8_bytes_index = 0;
2466
2467 if (current_wchar == str.size())
2468 {
2469 utf8_bytes[0] = std::char_traits<char>::eof();
2470 utf8_bytes_filled = 1;
2471 }
2472 else
2473 {
2474 // get the current character
2475 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2476
2477 // UTF-16 to UTF-8 encoding
2478 if (wc < 0x80)
2479 {
2480 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2481 utf8_bytes_filled = 1;
2482 }
2483 else if (wc <= 0x7FF)
2484 {
2485 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
2486 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2487 utf8_bytes_filled = 2;
2488 }
2489 else if (0xD800 > wc or wc >= 0xE000)
2490 {
2491 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
2492 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2493 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2494 utf8_bytes_filled = 3;
2495 }
2496 else
2497 {
2498 if (current_wchar < str.size())
2499 {
2500 const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
2501 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2502 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
2503 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
2504 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
2505 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
2506 utf8_bytes_filled = 4;
2507 }
2508 else
2509 {
2510 // unknown character
2511 ++current_wchar;
2512 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2513 utf8_bytes_filled = 1;
2514 }
2515 }
2516 }
2517 }
2518 };
2519
2520 template<typename WideStringType>
2521 class wide_string_input_adapter : public input_adapter_protocol
2522 {
2523 public:
wide_string_input_adapter(const WideStringType & w)2524 explicit wide_string_input_adapter(const WideStringType& w) noexcept
2525 : str(w)
2526 {}
2527
get_character()2528 std::char_traits<char>::int_type get_character() noexcept override
2529 {
2530 // check if buffer needs to be filled
2531 if (utf8_bytes_index == utf8_bytes_filled)
2532 {
2533 fill_buffer<sizeof(typename WideStringType::value_type)>();
2534
2535 assert(utf8_bytes_filled > 0);
2536 assert(utf8_bytes_index == 0);
2537 }
2538
2539 // use buffer
2540 assert(utf8_bytes_filled > 0);
2541 assert(utf8_bytes_index < utf8_bytes_filled);
2542 return utf8_bytes[utf8_bytes_index++];
2543 }
2544
2545 private:
2546 template<size_t T>
fill_buffer()2547 void fill_buffer()
2548 {
2549 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2550 }
2551
2552 /// the wstring to process
2553 const WideStringType& str;
2554
2555 /// index of the current wchar in str
2556 std::size_t current_wchar = 0;
2557
2558 /// a buffer for UTF-8 bytes
2559 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2560
2561 /// index to the utf8_codes array for the next valid byte
2562 std::size_t utf8_bytes_index = 0;
2563 /// number of valid bytes in the utf8_codes array
2564 std::size_t utf8_bytes_filled = 0;
2565 };
2566
2567 class input_adapter
2568 {
2569 public:
2570 // native support
input_adapter(std::FILE * file)2571 input_adapter(std::FILE* file)
2572 : ia(std::make_shared<file_input_adapter>(file)) {}
2573 /// input adapter for input stream
input_adapter(std::istream & i)2574 input_adapter(std::istream& i)
2575 : ia(std::make_shared<input_stream_adapter>(i)) {}
2576
2577 /// input adapter for input stream
input_adapter(std::istream && i)2578 input_adapter(std::istream&& i)
2579 : ia(std::make_shared<input_stream_adapter>(i)) {}
2580
input_adapter(const std::wstring & ws)2581 input_adapter(const std::wstring& ws)
2582 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2583
input_adapter(const std::u16string & ws)2584 input_adapter(const std::u16string& ws)
2585 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2586
input_adapter(const std::u32string & ws)2587 input_adapter(const std::u32string& ws)
2588 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2589
2590 /// input adapter for buffer
2591 template<typename CharT,
2592 typename std::enable_if<
2593 std::is_pointer<CharT>::value and
2594 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2595 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2596 int>::type = 0>
input_adapter(CharT b,std::size_t l)2597 input_adapter(CharT b, std::size_t l)
2598 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2599
2600 // derived support
2601
2602 /// input adapter for string literal
2603 template<typename CharT,
2604 typename std::enable_if<
2605 std::is_pointer<CharT>::value and
2606 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2607 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2608 int>::type = 0>
input_adapter(CharT b)2609 input_adapter(CharT b)
2610 : input_adapter(reinterpret_cast<const char*>(b),
2611 std::strlen(reinterpret_cast<const char*>(b))) {}
2612
2613 /// input adapter for iterator range with contiguous storage
2614 template<class IteratorType,
2615 typename std::enable_if<
2616 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2617 int>::type = 0>
input_adapter(IteratorType first,IteratorType last)2618 input_adapter(IteratorType first, IteratorType last)
2619 {
2620 #ifndef NDEBUG
2621 // assertion to check that the iterator range is indeed contiguous,
2622 // see http://stackoverflow.com/a/35008842/266378 for more discussion
2623 const auto is_contiguous = std::accumulate(
2624 first, last, std::pair<bool, int>(true, 0),
2625 [&first](std::pair<bool, int> res, decltype(*first) val)
2626 {
2627 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2628 return res;
2629 }).first;
2630 assert(is_contiguous);
2631 #endif
2632
2633 // assertion to check that each element is 1 byte long
2634 static_assert(
2635 sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
2636 "each element in the iterator range must have the size of 1 byte");
2637
2638 const auto len = static_cast<size_t>(std::distance(first, last));
2639 if (JSON_LIKELY(len > 0))
2640 {
2641 // there is at least one element: use the address of first
2642 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2643 }
2644 else
2645 {
2646 // the address of first cannot be used: use nullptr
2647 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2648 }
2649 }
2650
2651 /// input adapter for array
2652 template<class T, std::size_t N>
input_adapter(T (& array)[N])2653 input_adapter(T (&array)[N])
2654 : input_adapter(std::begin(array), std::end(array)) {}
2655
2656 /// input adapter for contiguous container
2657 template<class ContiguousContainer, typename
2658 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2659 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2660 int>::type = 0>
input_adapter(const ContiguousContainer & c)2661 input_adapter(const ContiguousContainer& c)
2662 : input_adapter(std::begin(c), std::end(c)) {}
2663
operator input_adapter_t()2664 operator input_adapter_t()
2665 {
2666 return ia;
2667 }
2668
2669 private:
2670 /// the actual adapter
2671 input_adapter_t ia = nullptr;
2672 };
2673 } // namespace detail
2674 } // namespace nlohmann
2675
2676 // #include <nlohmann/detail/input/json_sax.hpp>
2677
2678
2679 #include <cassert> // assert
2680 #include <cstddef>
2681 #include <string> // string
2682 #include <utility> // move
2683 #include <vector> // vector
2684
2685 // #include <nlohmann/detail/exceptions.hpp>
2686
2687 // #include <nlohmann/detail/macro_scope.hpp>
2688
2689
2690 namespace nlohmann
2691 {
2692
2693 /*!
2694 @brief SAX interface
2695
2696 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
2697 Each function is called in different situations while the input is parsed. The
2698 boolean return value informs the parser whether to continue processing the
2699 input.
2700 */
2701 template<typename BasicJsonType>
2702 struct json_sax
2703 {
2704 /// type for (signed) integers
2705 using number_integer_t = typename BasicJsonType::number_integer_t;
2706 /// type for unsigned integers
2707 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2708 /// type for floating-point numbers
2709 using number_float_t = typename BasicJsonType::number_float_t;
2710 /// type for strings
2711 using string_t = typename BasicJsonType::string_t;
2712
2713 /*!
2714 @brief a null value was read
2715 @return whether parsing should proceed
2716 */
2717 virtual bool null() = 0;
2718
2719 /*!
2720 @brief a boolean value was read
2721 @param[in] val boolean value
2722 @return whether parsing should proceed
2723 */
2724 virtual bool boolean(bool val) = 0;
2725
2726 /*!
2727 @brief an integer number was read
2728 @param[in] val integer value
2729 @return whether parsing should proceed
2730 */
2731 virtual bool number_integer(number_integer_t val) = 0;
2732
2733 /*!
2734 @brief an unsigned integer number was read
2735 @param[in] val unsigned integer value
2736 @return whether parsing should proceed
2737 */
2738 virtual bool number_unsigned(number_unsigned_t val) = 0;
2739
2740 /*!
2741 @brief an floating-point number was read
2742 @param[in] val floating-point value
2743 @param[in] s raw token value
2744 @return whether parsing should proceed
2745 */
2746 virtual bool number_float(number_float_t val, const string_t& s) = 0;
2747
2748 /*!
2749 @brief a string was read
2750 @param[in] val string value
2751 @return whether parsing should proceed
2752 @note It is safe to move the passed string.
2753 */
2754 virtual bool string(string_t& val) = 0;
2755
2756 /*!
2757 @brief the beginning of an object was read
2758 @param[in] elements number of object elements or -1 if unknown
2759 @return whether parsing should proceed
2760 @note binary formats may report the number of elements
2761 */
2762 virtual bool start_object(std::size_t elements) = 0;
2763
2764 /*!
2765 @brief an object key was read
2766 @param[in] val object key
2767 @return whether parsing should proceed
2768 @note It is safe to move the passed string.
2769 */
2770 virtual bool key(string_t& val) = 0;
2771
2772 /*!
2773 @brief the end of an object was read
2774 @return whether parsing should proceed
2775 */
2776 virtual bool end_object() = 0;
2777
2778 /*!
2779 @brief the beginning of an array was read
2780 @param[in] elements number of array elements or -1 if unknown
2781 @return whether parsing should proceed
2782 @note binary formats may report the number of elements
2783 */
2784 virtual bool start_array(std::size_t elements) = 0;
2785
2786 /*!
2787 @brief the end of an array was read
2788 @return whether parsing should proceed
2789 */
2790 virtual bool end_array() = 0;
2791
2792 /*!
2793 @brief a parse error occurred
2794 @param[in] position the position in the input where the error occurs
2795 @param[in] last_token the last read token
2796 @param[in] ex an exception object describing the error
2797 @return whether parsing should proceed (must return false)
2798 */
2799 virtual bool parse_error(std::size_t position,
2800 const std::string& last_token,
2801 const detail::exception& ex) = 0;
2802
2803 virtual ~json_sax() = default;
2804 };
2805
2806
2807 namespace detail
2808 {
2809 /*!
2810 @brief SAX implementation to create a JSON value from SAX events
2811
2812 This class implements the @ref json_sax interface and processes the SAX events
2813 to create a JSON value which makes it basically a DOM parser. The structure or
2814 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
2815 a pointer to the respective array or object for each recursion depth.
2816
2817 After successful parsing, the value that is passed by reference to the
2818 constructor contains the parsed value.
2819
2820 @tparam BasicJsonType the JSON type
2821 */
2822 template<typename BasicJsonType>
2823 class json_sax_dom_parser
2824 {
2825 public:
2826 using number_integer_t = typename BasicJsonType::number_integer_t;
2827 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2828 using number_float_t = typename BasicJsonType::number_float_t;
2829 using string_t = typename BasicJsonType::string_t;
2830
2831 /*!
2832 @param[in, out] r reference to a JSON value that is manipulated while
2833 parsing
2834 @param[in] allow_exceptions_ whether parse errors yield exceptions
2835 */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)2836 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
2837 : root(r), allow_exceptions(allow_exceptions_)
2838 {}
2839
2840 // make class move-only
2841 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
2842 json_sax_dom_parser(json_sax_dom_parser&&) = default;
2843 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
2844 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
2845 ~json_sax_dom_parser() = default;
2846
null()2847 bool null()
2848 {
2849 handle_value(nullptr);
2850 return true;
2851 }
2852
boolean(bool val)2853 bool boolean(bool val)
2854 {
2855 handle_value(val);
2856 return true;
2857 }
2858
number_integer(number_integer_t val)2859 bool number_integer(number_integer_t val)
2860 {
2861 handle_value(val);
2862 return true;
2863 }
2864
number_unsigned(number_unsigned_t val)2865 bool number_unsigned(number_unsigned_t val)
2866 {
2867 handle_value(val);
2868 return true;
2869 }
2870
number_float(number_float_t val,const string_t &)2871 bool number_float(number_float_t val, const string_t& /*unused*/)
2872 {
2873 handle_value(val);
2874 return true;
2875 }
2876
string(string_t & val)2877 bool string(string_t& val)
2878 {
2879 handle_value(val);
2880 return true;
2881 }
2882
start_object(std::size_t len)2883 bool start_object(std::size_t len)
2884 {
2885 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
2886
2887 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2888 {
2889 JSON_THROW(out_of_range::create(408,
2890 "excessive object size: " + std::to_string(len)));
2891 }
2892
2893 return true;
2894 }
2895
key(string_t & val)2896 bool key(string_t& val)
2897 {
2898 // add null at given key and store the reference for later
2899 object_element = &(ref_stack.back()->m_value.object->operator[](val));
2900 return true;
2901 }
2902
end_object()2903 bool end_object()
2904 {
2905 ref_stack.pop_back();
2906 return true;
2907 }
2908
start_array(std::size_t len)2909 bool start_array(std::size_t len)
2910 {
2911 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
2912
2913 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2914 {
2915 JSON_THROW(out_of_range::create(408,
2916 "excessive array size: " + std::to_string(len)));
2917 }
2918
2919 return true;
2920 }
2921
end_array()2922 bool end_array()
2923 {
2924 ref_stack.pop_back();
2925 return true;
2926 }
2927
parse_error(std::size_t,const std::string &,const detail::exception & ex)2928 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
2929 const detail::exception& ex)
2930 {
2931 errored = true;
2932 if (allow_exceptions)
2933 {
2934 // determine the proper exception type from the id
2935 switch ((ex.id / 100) % 100)
2936 {
2937 case 1:
2938 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
2939 case 4:
2940 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
2941 // LCOV_EXCL_START
2942 case 2:
2943 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
2944 case 3:
2945 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
2946 case 5:
2947 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
2948 default:
2949 assert(false);
2950 // LCOV_EXCL_STOP
2951 }
2952 }
2953 return false;
2954 }
2955
is_errored() const2956 constexpr bool is_errored() const
2957 {
2958 return errored;
2959 }
2960
2961 private:
2962 /*!
2963 @invariant If the ref stack is empty, then the passed value will be the new
2964 root.
2965 @invariant If the ref stack contains a value, then it is an array or an
2966 object to which we can add elements
2967 */
2968 template<typename Value>
handle_value(Value && v)2969 BasicJsonType* handle_value(Value&& v)
2970 {
2971 if (ref_stack.empty())
2972 {
2973 root = BasicJsonType(std::forward<Value>(v));
2974 return &root;
2975 }
2976
2977 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
2978
2979 if (ref_stack.back()->is_array())
2980 {
2981 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
2982 return &(ref_stack.back()->m_value.array->back());
2983 }
2984
2985 assert(ref_stack.back()->is_object());
2986 assert(object_element);
2987 *object_element = BasicJsonType(std::forward<Value>(v));
2988 return object_element;
2989 }
2990
2991 /// the parsed JSON value
2992 BasicJsonType& root;
2993 /// stack to model hierarchy of values
2994 std::vector<BasicJsonType*> ref_stack {};
2995 /// helper to hold the reference for the next object element
2996 BasicJsonType* object_element = nullptr;
2997 /// whether a syntax error occurred
2998 bool errored = false;
2999 /// whether to throw exceptions in case of errors
3000 const bool allow_exceptions = true;
3001 };
3002
3003 template<typename BasicJsonType>
3004 class json_sax_dom_callback_parser
3005 {
3006 public:
3007 using number_integer_t = typename BasicJsonType::number_integer_t;
3008 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3009 using number_float_t = typename BasicJsonType::number_float_t;
3010 using string_t = typename BasicJsonType::string_t;
3011 using parser_callback_t = typename BasicJsonType::parser_callback_t;
3012 using parse_event_t = typename BasicJsonType::parse_event_t;
3013
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)3014 json_sax_dom_callback_parser(BasicJsonType& r,
3015 const parser_callback_t cb,
3016 const bool allow_exceptions_ = true)
3017 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
3018 {
3019 keep_stack.push_back(true);
3020 }
3021
3022 // make class move-only
3023 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
3024 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
3025 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
3026 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
3027 ~json_sax_dom_callback_parser() = default;
3028
null()3029 bool null()
3030 {
3031 handle_value(nullptr);
3032 return true;
3033 }
3034
boolean(bool val)3035 bool boolean(bool val)
3036 {
3037 handle_value(val);
3038 return true;
3039 }
3040
number_integer(number_integer_t val)3041 bool number_integer(number_integer_t val)
3042 {
3043 handle_value(val);
3044 return true;
3045 }
3046
number_unsigned(number_unsigned_t val)3047 bool number_unsigned(number_unsigned_t val)
3048 {
3049 handle_value(val);
3050 return true;
3051 }
3052
number_float(number_float_t val,const string_t &)3053 bool number_float(number_float_t val, const string_t& /*unused*/)
3054 {
3055 handle_value(val);
3056 return true;
3057 }
3058
string(string_t & val)3059 bool string(string_t& val)
3060 {
3061 handle_value(val);
3062 return true;
3063 }
3064
start_object(std::size_t len)3065 bool start_object(std::size_t len)
3066 {
3067 // check callback for object start
3068 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
3069 keep_stack.push_back(keep);
3070
3071 auto val = handle_value(BasicJsonType::value_t::object, true);
3072 ref_stack.push_back(val.second);
3073
3074 // check object limit
3075 if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3076 {
3077 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
3078 }
3079
3080 return true;
3081 }
3082
key(string_t & val)3083 bool key(string_t& val)
3084 {
3085 BasicJsonType k = BasicJsonType(val);
3086
3087 // check callback for key
3088 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
3089 key_keep_stack.push_back(keep);
3090
3091 // add discarded value at given key and store the reference for later
3092 if (keep and ref_stack.back())
3093 {
3094 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
3095 }
3096
3097 return true;
3098 }
3099
end_object()3100 bool end_object()
3101 {
3102 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
3103 {
3104 // discard object
3105 *ref_stack.back() = discarded;
3106 }
3107
3108 assert(not ref_stack.empty());
3109 assert(not keep_stack.empty());
3110 ref_stack.pop_back();
3111 keep_stack.pop_back();
3112
3113 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
3114 {
3115 // remove discarded value
3116 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
3117 {
3118 if (it->is_discarded())
3119 {
3120 ref_stack.back()->erase(it);
3121 break;
3122 }
3123 }
3124 }
3125
3126 return true;
3127 }
3128
start_array(std::size_t len)3129 bool start_array(std::size_t len)
3130 {
3131 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
3132 keep_stack.push_back(keep);
3133
3134 auto val = handle_value(BasicJsonType::value_t::array, true);
3135 ref_stack.push_back(val.second);
3136
3137 // check array limit
3138 if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3139 {
3140 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
3141 }
3142
3143 return true;
3144 }
3145
end_array()3146 bool end_array()
3147 {
3148 bool keep = true;
3149
3150 if (ref_stack.back())
3151 {
3152 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
3153 if (not keep)
3154 {
3155 // discard array
3156 *ref_stack.back() = discarded;
3157 }
3158 }
3159
3160 assert(not ref_stack.empty());
3161 assert(not keep_stack.empty());
3162 ref_stack.pop_back();
3163 keep_stack.pop_back();
3164
3165 // remove discarded value
3166 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
3167 {
3168 ref_stack.back()->m_value.array->pop_back();
3169 }
3170
3171 return true;
3172 }
3173
parse_error(std::size_t,const std::string &,const detail::exception & ex)3174 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
3175 const detail::exception& ex)
3176 {
3177 errored = true;
3178 if (allow_exceptions)
3179 {
3180 // determine the proper exception type from the id
3181 switch ((ex.id / 100) % 100)
3182 {
3183 case 1:
3184 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
3185 case 4:
3186 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
3187 // LCOV_EXCL_START
3188 case 2:
3189 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
3190 case 3:
3191 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
3192 case 5:
3193 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
3194 default:
3195 assert(false);
3196 // LCOV_EXCL_STOP
3197 }
3198 }
3199 return false;
3200 }
3201
is_errored() const3202 constexpr bool is_errored() const
3203 {
3204 return errored;
3205 }
3206
3207 private:
3208 /*!
3209 @param[in] v value to add to the JSON value we build during parsing
3210 @param[in] skip_callback whether we should skip calling the callback
3211 function; this is required after start_array() and
3212 start_object() SAX events, because otherwise we would call the
3213 callback function with an empty array or object, respectively.
3214
3215 @invariant If the ref stack is empty, then the passed value will be the new
3216 root.
3217 @invariant If the ref stack contains a value, then it is an array or an
3218 object to which we can add elements
3219
3220 @return pair of boolean (whether value should be kept) and pointer (to the
3221 passed value in the ref_stack hierarchy; nullptr if not kept)
3222 */
3223 template<typename Value>
handle_value(Value && v,const bool skip_callback=false)3224 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
3225 {
3226 assert(not keep_stack.empty());
3227
3228 // do not handle this value if we know it would be added to a discarded
3229 // container
3230 if (not keep_stack.back())
3231 {
3232 return {false, nullptr};
3233 }
3234
3235 // create value
3236 auto value = BasicJsonType(std::forward<Value>(v));
3237
3238 // check callback
3239 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
3240
3241 // do not handle this value if we just learnt it shall be discarded
3242 if (not keep)
3243 {
3244 return {false, nullptr};
3245 }
3246
3247 if (ref_stack.empty())
3248 {
3249 root = std::move(value);
3250 return {true, &root};
3251 }
3252
3253 // skip this value if we already decided to skip the parent
3254 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
3255 if (not ref_stack.back())
3256 {
3257 return {false, nullptr};
3258 }
3259
3260 // we now only expect arrays and objects
3261 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
3262
3263 // array
3264 if (ref_stack.back()->is_array())
3265 {
3266 ref_stack.back()->m_value.array->push_back(std::move(value));
3267 return {true, &(ref_stack.back()->m_value.array->back())};
3268 }
3269
3270 // object
3271 assert(ref_stack.back()->is_object());
3272 // check if we should store an element for the current key
3273 assert(not key_keep_stack.empty());
3274 const bool store_element = key_keep_stack.back();
3275 key_keep_stack.pop_back();
3276
3277 if (not store_element)
3278 {
3279 return {false, nullptr};
3280 }
3281
3282 assert(object_element);
3283 *object_element = std::move(value);
3284 return {true, object_element};
3285 }
3286
3287 /// the parsed JSON value
3288 BasicJsonType& root;
3289 /// stack to model hierarchy of values
3290 std::vector<BasicJsonType*> ref_stack {};
3291 /// stack to manage which values to keep
3292 std::vector<bool> keep_stack {};
3293 /// stack to manage which object keys to keep
3294 std::vector<bool> key_keep_stack {};
3295 /// helper to hold the reference for the next object element
3296 BasicJsonType* object_element = nullptr;
3297 /// whether a syntax error occurred
3298 bool errored = false;
3299 /// callback function
3300 const parser_callback_t callback = nullptr;
3301 /// whether to throw exceptions in case of errors
3302 const bool allow_exceptions = true;
3303 /// a discarded value for the callback
3304 BasicJsonType discarded = BasicJsonType::value_t::discarded;
3305 };
3306
3307 template<typename BasicJsonType>
3308 class json_sax_acceptor
3309 {
3310 public:
3311 using number_integer_t = typename BasicJsonType::number_integer_t;
3312 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3313 using number_float_t = typename BasicJsonType::number_float_t;
3314 using string_t = typename BasicJsonType::string_t;
3315
null()3316 bool null()
3317 {
3318 return true;
3319 }
3320
boolean(bool)3321 bool boolean(bool /*unused*/)
3322 {
3323 return true;
3324 }
3325
number_integer(number_integer_t)3326 bool number_integer(number_integer_t /*unused*/)
3327 {
3328 return true;
3329 }
3330
number_unsigned(number_unsigned_t)3331 bool number_unsigned(number_unsigned_t /*unused*/)
3332 {
3333 return true;
3334 }
3335
number_float(number_float_t,const string_t &)3336 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
3337 {
3338 return true;
3339 }
3340
string(string_t &)3341 bool string(string_t& /*unused*/)
3342 {
3343 return true;
3344 }
3345
start_object(std::size_t=std::size_t (-1))3346 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
3347 {
3348 return true;
3349 }
3350
key(string_t &)3351 bool key(string_t& /*unused*/)
3352 {
3353 return true;
3354 }
3355
end_object()3356 bool end_object()
3357 {
3358 return true;
3359 }
3360
start_array(std::size_t=std::size_t (-1))3361 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
3362 {
3363 return true;
3364 }
3365
end_array()3366 bool end_array()
3367 {
3368 return true;
3369 }
3370
parse_error(std::size_t,const std::string &,const detail::exception &)3371 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
3372 {
3373 return false;
3374 }
3375 };
3376 } // namespace detail
3377
3378 } // namespace nlohmann
3379
3380 // #include <nlohmann/detail/macro_scope.hpp>
3381
3382 // #include <nlohmann/detail/meta/is_sax.hpp>
3383
3384
3385 #include <cstdint> // size_t
3386 #include <utility> // declval
3387 #include <string> // string
3388
3389 // #include <nlohmann/detail/meta/detected.hpp>
3390
3391 // #include <nlohmann/detail/meta/type_traits.hpp>
3392
3393
3394 namespace nlohmann
3395 {
3396 namespace detail
3397 {
3398 template <typename T>
3399 using null_function_t = decltype(std::declval<T&>().null());
3400
3401 template <typename T>
3402 using boolean_function_t =
3403 decltype(std::declval<T&>().boolean(std::declval<bool>()));
3404
3405 template <typename T, typename Integer>
3406 using number_integer_function_t =
3407 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3408
3409 template <typename T, typename Unsigned>
3410 using number_unsigned_function_t =
3411 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3412
3413 template <typename T, typename Float, typename String>
3414 using number_float_function_t = decltype(std::declval<T&>().number_float(
3415 std::declval<Float>(), std::declval<const String&>()));
3416
3417 template <typename T, typename String>
3418 using string_function_t =
3419 decltype(std::declval<T&>().string(std::declval<String&>()));
3420
3421 template <typename T>
3422 using start_object_function_t =
3423 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3424
3425 template <typename T, typename String>
3426 using key_function_t =
3427 decltype(std::declval<T&>().key(std::declval<String&>()));
3428
3429 template <typename T>
3430 using end_object_function_t = decltype(std::declval<T&>().end_object());
3431
3432 template <typename T>
3433 using start_array_function_t =
3434 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3435
3436 template <typename T>
3437 using end_array_function_t = decltype(std::declval<T&>().end_array());
3438
3439 template <typename T, typename Exception>
3440 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
3441 std::declval<std::size_t>(), std::declval<const std::string&>(),
3442 std::declval<const Exception&>()));
3443
3444 template <typename SAX, typename BasicJsonType>
3445 struct is_sax
3446 {
3447 private:
3448 static_assert(is_basic_json<BasicJsonType>::value,
3449 "BasicJsonType must be of type basic_json<...>");
3450
3451 using number_integer_t = typename BasicJsonType::number_integer_t;
3452 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3453 using number_float_t = typename BasicJsonType::number_float_t;
3454 using string_t = typename BasicJsonType::string_t;
3455 using exception_t = typename BasicJsonType::exception;
3456
3457 public:
3458 static constexpr bool value =
3459 is_detected_exact<bool, null_function_t, SAX>::value &&
3460 is_detected_exact<bool, boolean_function_t, SAX>::value &&
3461 is_detected_exact<bool, number_integer_function_t, SAX,
3462 number_integer_t>::value &&
3463 is_detected_exact<bool, number_unsigned_function_t, SAX,
3464 number_unsigned_t>::value &&
3465 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
3466 string_t>::value &&
3467 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
3468 is_detected_exact<bool, start_object_function_t, SAX>::value &&
3469 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
3470 is_detected_exact<bool, end_object_function_t, SAX>::value &&
3471 is_detected_exact<bool, start_array_function_t, SAX>::value &&
3472 is_detected_exact<bool, end_array_function_t, SAX>::value &&
3473 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
3474 };
3475
3476 template <typename SAX, typename BasicJsonType>
3477 struct is_sax_static_asserts
3478 {
3479 private:
3480 static_assert(is_basic_json<BasicJsonType>::value,
3481 "BasicJsonType must be of type basic_json<...>");
3482
3483 using number_integer_t = typename BasicJsonType::number_integer_t;
3484 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3485 using number_float_t = typename BasicJsonType::number_float_t;
3486 using string_t = typename BasicJsonType::string_t;
3487 using exception_t = typename BasicJsonType::exception;
3488
3489 public:
3490 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
3491 "Missing/invalid function: bool null()");
3492 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3493 "Missing/invalid function: bool boolean(bool)");
3494 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3495 "Missing/invalid function: bool boolean(bool)");
3496 static_assert(
3497 is_detected_exact<bool, number_integer_function_t, SAX,
3498 number_integer_t>::value,
3499 "Missing/invalid function: bool number_integer(number_integer_t)");
3500 static_assert(
3501 is_detected_exact<bool, number_unsigned_function_t, SAX,
3502 number_unsigned_t>::value,
3503 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3504 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
3505 number_float_t, string_t>::value,
3506 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3507 static_assert(
3508 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
3509 "Missing/invalid function: bool string(string_t&)");
3510 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
3511 "Missing/invalid function: bool start_object(std::size_t)");
3512 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
3513 "Missing/invalid function: bool key(string_t&)");
3514 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
3515 "Missing/invalid function: bool end_object()");
3516 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
3517 "Missing/invalid function: bool start_array(std::size_t)");
3518 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
3519 "Missing/invalid function: bool end_array()");
3520 static_assert(
3521 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
3522 "Missing/invalid function: bool parse_error(std::size_t, const "
3523 "std::string&, const exception&)");
3524 };
3525 } // namespace detail
3526 } // namespace nlohmann
3527
3528 // #include <nlohmann/detail/value_t.hpp>
3529
3530
3531 namespace nlohmann
3532 {
3533 namespace detail
3534 {
3535 ///////////////////
3536 // binary reader //
3537 ///////////////////
3538
3539 /*!
3540 @brief deserialization of CBOR, MessagePack, and UBJSON values
3541 */
3542 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
3543 class binary_reader
3544 {
3545 using number_integer_t = typename BasicJsonType::number_integer_t;
3546 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3547 using number_float_t = typename BasicJsonType::number_float_t;
3548 using string_t = typename BasicJsonType::string_t;
3549 using json_sax_t = SAX;
3550
3551 public:
3552 /*!
3553 @brief create a binary reader
3554
3555 @param[in] adapter input adapter to read from
3556 */
binary_reader(input_adapter_t adapter)3557 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
3558 {
3559 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
3560 assert(ia);
3561 }
3562
3563 // make class move-only
3564 binary_reader(const binary_reader&) = delete;
3565 binary_reader(binary_reader&&) = default;
3566 binary_reader& operator=(const binary_reader&) = delete;
3567 binary_reader& operator=(binary_reader&&) = default;
3568 ~binary_reader() = default;
3569
3570 /*!
3571 @param[in] format the binary format to parse
3572 @param[in] sax_ a SAX event processor
3573 @param[in] strict whether to expect the input to be consumed completed
3574
3575 @return
3576 */
sax_parse(const input_format_t format,json_sax_t * sax_,const bool strict=true)3577 bool sax_parse(const input_format_t format,
3578 json_sax_t* sax_,
3579 const bool strict = true)
3580 {
3581 sax = sax_;
3582 bool result = false;
3583
3584 switch (format)
3585 {
3586 case input_format_t::bson:
3587 result = parse_bson_internal();
3588 break;
3589
3590 case input_format_t::cbor:
3591 result = parse_cbor_internal();
3592 break;
3593
3594 case input_format_t::msgpack:
3595 result = parse_msgpack_internal();
3596 break;
3597
3598 case input_format_t::ubjson:
3599 result = parse_ubjson_internal();
3600 break;
3601
3602 default: // LCOV_EXCL_LINE
3603 assert(false); // LCOV_EXCL_LINE
3604 }
3605
3606 // strict mode: next byte must be EOF
3607 if (result and strict)
3608 {
3609 if (format == input_format_t::ubjson)
3610 {
3611 get_ignore_noop();
3612 }
3613 else
3614 {
3615 get();
3616 }
3617
3618 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
3619 {
3620 return sax->parse_error(chars_read, get_token_string(),
3621 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
3622 }
3623 }
3624
3625 return result;
3626 }
3627
3628 /*!
3629 @brief determine system byte order
3630
3631 @return true if and only if system's byte order is little endian
3632
3633 @note from http://stackoverflow.com/a/1001328/266378
3634 */
little_endianess(int num=1)3635 static constexpr bool little_endianess(int num = 1) noexcept
3636 {
3637 return *reinterpret_cast<char*>(&num) == 1;
3638 }
3639
3640 private:
3641 //////////
3642 // BSON //
3643 //////////
3644
3645 /*!
3646 @brief Reads in a BSON-object and passes it to the SAX-parser.
3647 @return whether a valid BSON-value was passed to the SAX parser
3648 */
parse_bson_internal()3649 bool parse_bson_internal()
3650 {
3651 std::int32_t document_size;
3652 get_number<std::int32_t, true>(input_format_t::bson, document_size);
3653
3654 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
3655 {
3656 return false;
3657 }
3658
3659 if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
3660 {
3661 return false;
3662 }
3663
3664 return sax->end_object();
3665 }
3666
3667 /*!
3668 @brief Parses a C-style string from the BSON input.
3669 @param[in, out] result A reference to the string variable where the read
3670 string is to be stored.
3671 @return `true` if the \x00-byte indicating the end of the string was
3672 encountered before the EOF; false` indicates an unexpected EOF.
3673 */
get_bson_cstr(string_t & result)3674 bool get_bson_cstr(string_t& result)
3675 {
3676 auto out = std::back_inserter(result);
3677 while (true)
3678 {
3679 get();
3680 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
3681 {
3682 return false;
3683 }
3684 if (current == 0x00)
3685 {
3686 return true;
3687 }
3688 *out++ = static_cast<char>(current);
3689 }
3690
3691 return true;
3692 }
3693
3694 /*!
3695 @brief Parses a zero-terminated string of length @a len from the BSON
3696 input.
3697 @param[in] len The length (including the zero-byte at the end) of the
3698 string to be read.
3699 @param[in, out] result A reference to the string variable where the read
3700 string is to be stored.
3701 @tparam NumberType The type of the length @a len
3702 @pre len >= 1
3703 @return `true` if the string was successfully parsed
3704 */
3705 template<typename NumberType>
get_bson_string(const NumberType len,string_t & result)3706 bool get_bson_string(const NumberType len, string_t& result)
3707 {
3708 if (JSON_UNLIKELY(len < 1))
3709 {
3710 auto last_token = get_token_string();
3711 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")));
3712 }
3713
3714 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
3715 }
3716
3717 /*!
3718 @brief Read a BSON document element of the given @a element_type.
3719 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
3720 @param[in] element_type_parse_position The position in the input stream,
3721 where the `element_type` was read.
3722 @warning Not all BSON element types are supported yet. An unsupported
3723 @a element_type will give rise to a parse_error.114:
3724 Unsupported BSON record type 0x...
3725 @return whether a valid BSON-object/array was passed to the SAX parser
3726 */
parse_bson_element_internal(const int element_type,const std::size_t element_type_parse_position)3727 bool parse_bson_element_internal(const int element_type,
3728 const std::size_t element_type_parse_position)
3729 {
3730 switch (element_type)
3731 {
3732 case 0x01: // double
3733 {
3734 double number;
3735 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
3736 }
3737
3738 case 0x02: // string
3739 {
3740 std::int32_t len;
3741 string_t value;
3742 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
3743 }
3744
3745 case 0x03: // object
3746 {
3747 return parse_bson_internal();
3748 }
3749
3750 case 0x04: // array
3751 {
3752 return parse_bson_array();
3753 }
3754
3755 case 0x08: // boolean
3756 {
3757 return sax->boolean(get() != 0);
3758 }
3759
3760 case 0x0A: // null
3761 {
3762 return sax->null();
3763 }
3764
3765 case 0x10: // int32
3766 {
3767 std::int32_t value;
3768 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
3769 }
3770
3771 case 0x12: // int64
3772 {
3773 std::int64_t value;
3774 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
3775 }
3776
3777 default: // anything else not supported (yet)
3778 {
3779 std::array<char, 3> cr{{}};
3780 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
3781 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())));
3782 }
3783 }
3784 }
3785
3786 /*!
3787 @brief Read a BSON element list (as specified in the BSON-spec)
3788
3789 The same binary layout is used for objects and arrays, hence it must be
3790 indicated with the argument @a is_array which one is expected
3791 (true --> array, false --> object).
3792
3793 @param[in] is_array Determines if the element list being read is to be
3794 treated as an object (@a is_array == false), or as an
3795 array (@a is_array == true).
3796 @return whether a valid BSON-object/array was passed to the SAX parser
3797 */
parse_bson_element_list(const bool is_array)3798 bool parse_bson_element_list(const bool is_array)
3799 {
3800 string_t key;
3801 while (int element_type = get())
3802 {
3803 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
3804 {
3805 return false;
3806 }
3807
3808 const std::size_t element_type_parse_position = chars_read;
3809 if (JSON_UNLIKELY(not get_bson_cstr(key)))
3810 {
3811 return false;
3812 }
3813
3814 if (not is_array and not sax->key(key))
3815 {
3816 return false;
3817 }
3818
3819 if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
3820 {
3821 return false;
3822 }
3823
3824 // get_bson_cstr only appends
3825 key.clear();
3826 }
3827
3828 return true;
3829 }
3830
3831 /*!
3832 @brief Reads an array from the BSON input and passes it to the SAX-parser.
3833 @return whether a valid BSON-array was passed to the SAX parser
3834 */
parse_bson_array()3835 bool parse_bson_array()
3836 {
3837 std::int32_t document_size;
3838 get_number<std::int32_t, true>(input_format_t::bson, document_size);
3839
3840 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
3841 {
3842 return false;
3843 }
3844
3845 if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
3846 {
3847 return false;
3848 }
3849
3850 return sax->end_array();
3851 }
3852
3853 //////////
3854 // CBOR //
3855 //////////
3856
3857 /*!
3858 @param[in] get_char whether a new character should be retrieved from the
3859 input (true, default) or whether the last read
3860 character should be considered instead
3861
3862 @return whether a valid CBOR value was passed to the SAX parser
3863 */
parse_cbor_internal(const bool get_char=true)3864 bool parse_cbor_internal(const bool get_char = true)
3865 {
3866 switch (get_char ? get() : current)
3867 {
3868 // EOF
3869 case std::char_traits<char>::eof():
3870 return unexpect_eof(input_format_t::cbor, "value");
3871
3872 // Integer 0x00..0x17 (0..23)
3873 case 0x00:
3874 case 0x01:
3875 case 0x02:
3876 case 0x03:
3877 case 0x04:
3878 case 0x05:
3879 case 0x06:
3880 case 0x07:
3881 case 0x08:
3882 case 0x09:
3883 case 0x0A:
3884 case 0x0B:
3885 case 0x0C:
3886 case 0x0D:
3887 case 0x0E:
3888 case 0x0F:
3889 case 0x10:
3890 case 0x11:
3891 case 0x12:
3892 case 0x13:
3893 case 0x14:
3894 case 0x15:
3895 case 0x16:
3896 case 0x17:
3897 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
3898
3899 case 0x18: // Unsigned integer (one-byte uint8_t follows)
3900 {
3901 std::uint8_t number;
3902 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3903 }
3904
3905 case 0x19: // Unsigned integer (two-byte uint16_t follows)
3906 {
3907 std::uint16_t number;
3908 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3909 }
3910
3911 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
3912 {
3913 std::uint32_t number;
3914 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3915 }
3916
3917 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
3918 {
3919 std::uint64_t number;
3920 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3921 }
3922
3923 // Negative integer -1-0x00..-1-0x17 (-1..-24)
3924 case 0x20:
3925 case 0x21:
3926 case 0x22:
3927 case 0x23:
3928 case 0x24:
3929 case 0x25:
3930 case 0x26:
3931 case 0x27:
3932 case 0x28:
3933 case 0x29:
3934 case 0x2A:
3935 case 0x2B:
3936 case 0x2C:
3937 case 0x2D:
3938 case 0x2E:
3939 case 0x2F:
3940 case 0x30:
3941 case 0x31:
3942 case 0x32:
3943 case 0x33:
3944 case 0x34:
3945 case 0x35:
3946 case 0x36:
3947 case 0x37:
3948 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
3949
3950 case 0x38: // Negative integer (one-byte uint8_t follows)
3951 {
3952 std::uint8_t number;
3953 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3954 }
3955
3956 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
3957 {
3958 std::uint16_t number;
3959 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3960 }
3961
3962 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
3963 {
3964 std::uint32_t number;
3965 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3966 }
3967
3968 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
3969 {
3970 std::uint64_t number;
3971 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
3972 - static_cast<number_integer_t>(number));
3973 }
3974
3975 // UTF-8 string (0x00..0x17 bytes follow)
3976 case 0x60:
3977 case 0x61:
3978 case 0x62:
3979 case 0x63:
3980 case 0x64:
3981 case 0x65:
3982 case 0x66:
3983 case 0x67:
3984 case 0x68:
3985 case 0x69:
3986 case 0x6A:
3987 case 0x6B:
3988 case 0x6C:
3989 case 0x6D:
3990 case 0x6E:
3991 case 0x6F:
3992 case 0x70:
3993 case 0x71:
3994 case 0x72:
3995 case 0x73:
3996 case 0x74:
3997 case 0x75:
3998 case 0x76:
3999 case 0x77:
4000 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4001 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4002 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4003 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4004 case 0x7F: // UTF-8 string (indefinite length)
4005 {
4006 string_t s;
4007 return get_cbor_string(s) and sax->string(s);
4008 }
4009
4010 // array (0x00..0x17 data items follow)
4011 case 0x80:
4012 case 0x81:
4013 case 0x82:
4014 case 0x83:
4015 case 0x84:
4016 case 0x85:
4017 case 0x86:
4018 case 0x87:
4019 case 0x88:
4020 case 0x89:
4021 case 0x8A:
4022 case 0x8B:
4023 case 0x8C:
4024 case 0x8D:
4025 case 0x8E:
4026 case 0x8F:
4027 case 0x90:
4028 case 0x91:
4029 case 0x92:
4030 case 0x93:
4031 case 0x94:
4032 case 0x95:
4033 case 0x96:
4034 case 0x97:
4035 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
4036
4037 case 0x98: // array (one-byte uint8_t for n follows)
4038 {
4039 std::uint8_t len;
4040 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4041 }
4042
4043 case 0x99: // array (two-byte uint16_t for n follow)
4044 {
4045 std::uint16_t len;
4046 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4047 }
4048
4049 case 0x9A: // array (four-byte uint32_t for n follow)
4050 {
4051 std::uint32_t len;
4052 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4053 }
4054
4055 case 0x9B: // array (eight-byte uint64_t for n follow)
4056 {
4057 std::uint64_t len;
4058 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4059 }
4060
4061 case 0x9F: // array (indefinite length)
4062 return get_cbor_array(std::size_t(-1));
4063
4064 // map (0x00..0x17 pairs of data items follow)
4065 case 0xA0:
4066 case 0xA1:
4067 case 0xA2:
4068 case 0xA3:
4069 case 0xA4:
4070 case 0xA5:
4071 case 0xA6:
4072 case 0xA7:
4073 case 0xA8:
4074 case 0xA9:
4075 case 0xAA:
4076 case 0xAB:
4077 case 0xAC:
4078 case 0xAD:
4079 case 0xAE:
4080 case 0xAF:
4081 case 0xB0:
4082 case 0xB1:
4083 case 0xB2:
4084 case 0xB3:
4085 case 0xB4:
4086 case 0xB5:
4087 case 0xB6:
4088 case 0xB7:
4089 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
4090
4091 case 0xB8: // map (one-byte uint8_t for n follows)
4092 {
4093 std::uint8_t len;
4094 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4095 }
4096
4097 case 0xB9: // map (two-byte uint16_t for n follow)
4098 {
4099 std::uint16_t len;
4100 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4101 }
4102
4103 case 0xBA: // map (four-byte uint32_t for n follow)
4104 {
4105 std::uint32_t len;
4106 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4107 }
4108
4109 case 0xBB: // map (eight-byte uint64_t for n follow)
4110 {
4111 std::uint64_t len;
4112 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4113 }
4114
4115 case 0xBF: // map (indefinite length)
4116 return get_cbor_object(std::size_t(-1));
4117
4118 case 0xF4: // false
4119 return sax->boolean(false);
4120
4121 case 0xF5: // true
4122 return sax->boolean(true);
4123
4124 case 0xF6: // null
4125 return sax->null();
4126
4127 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
4128 {
4129 const int byte1_raw = get();
4130 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
4131 {
4132 return false;
4133 }
4134 const int byte2_raw = get();
4135 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
4136 {
4137 return false;
4138 }
4139
4140 const auto byte1 = static_cast<unsigned char>(byte1_raw);
4141 const auto byte2 = static_cast<unsigned char>(byte2_raw);
4142
4143 // code from RFC 7049, Appendix D, Figure 3:
4144 // As half-precision floating-point numbers were only added
4145 // to IEEE 754 in 2008, today's programming platforms often
4146 // still only have limited support for them. It is very
4147 // easy to include at least decoding support for them even
4148 // without such support. An example of a small decoder for
4149 // half-precision floating-point numbers in the C language
4150 // is shown in Fig. 3.
4151 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
4152 const double val = [&half]
4153 {
4154 const int exp = (half >> 10u) & 0x1Fu;
4155 const unsigned int mant = half & 0x3FFu;
4156 assert(0 <= exp and exp <= 32);
4157 assert(0 <= mant and mant <= 1024);
4158 switch (exp)
4159 {
4160 case 0:
4161 return std::ldexp(mant, -24);
4162 case 31:
4163 return (mant == 0)
4164 ? std::numeric_limits<double>::infinity()
4165 : std::numeric_limits<double>::quiet_NaN();
4166 default:
4167 return std::ldexp(mant + 1024, exp - 25);
4168 }
4169 }();
4170 return sax->number_float((half & 0x8000u) != 0
4171 ? static_cast<number_float_t>(-val)
4172 : static_cast<number_float_t>(val), "");
4173 }
4174
4175 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
4176 {
4177 float number;
4178 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
4179 }
4180
4181 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
4182 {
4183 double number;
4184 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
4185 }
4186
4187 default: // anything else (0xFF is handled inside the other types)
4188 {
4189 auto last_token = get_token_string();
4190 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")));
4191 }
4192 }
4193 }
4194
4195 /*!
4196 @brief reads a CBOR string
4197
4198 This function first reads starting bytes to determine the expected
4199 string length and then copies this number of bytes into a string.
4200 Additionally, CBOR's strings with indefinite lengths are supported.
4201
4202 @param[out] result created string
4203
4204 @return whether string creation completed
4205 */
get_cbor_string(string_t & result)4206 bool get_cbor_string(string_t& result)
4207 {
4208 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
4209 {
4210 return false;
4211 }
4212
4213 switch (current)
4214 {
4215 // UTF-8 string (0x00..0x17 bytes follow)
4216 case 0x60:
4217 case 0x61:
4218 case 0x62:
4219 case 0x63:
4220 case 0x64:
4221 case 0x65:
4222 case 0x66:
4223 case 0x67:
4224 case 0x68:
4225 case 0x69:
4226 case 0x6A:
4227 case 0x6B:
4228 case 0x6C:
4229 case 0x6D:
4230 case 0x6E:
4231 case 0x6F:
4232 case 0x70:
4233 case 0x71:
4234 case 0x72:
4235 case 0x73:
4236 case 0x74:
4237 case 0x75:
4238 case 0x76:
4239 case 0x77:
4240 {
4241 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
4242 }
4243
4244 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4245 {
4246 std::uint8_t len;
4247 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4248 }
4249
4250 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4251 {
4252 std::uint16_t len;
4253 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4254 }
4255
4256 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4257 {
4258 std::uint32_t len;
4259 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4260 }
4261
4262 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4263 {
4264 std::uint64_t len;
4265 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4266 }
4267
4268 case 0x7F: // UTF-8 string (indefinite length)
4269 {
4270 while (get() != 0xFF)
4271 {
4272 string_t chunk;
4273 if (not get_cbor_string(chunk))
4274 {
4275 return false;
4276 }
4277 result.append(chunk);
4278 }
4279 return true;
4280 }
4281
4282 default:
4283 {
4284 auto last_token = get_token_string();
4285 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")));
4286 }
4287 }
4288 }
4289
4290 /*!
4291 @param[in] len the length of the array or std::size_t(-1) for an
4292 array of indefinite size
4293 @return whether array creation completed
4294 */
get_cbor_array(const std::size_t len)4295 bool get_cbor_array(const std::size_t len)
4296 {
4297 if (JSON_UNLIKELY(not sax->start_array(len)))
4298 {
4299 return false;
4300 }
4301
4302 if (len != std::size_t(-1))
4303 {
4304 for (std::size_t i = 0; i < len; ++i)
4305 {
4306 if (JSON_UNLIKELY(not parse_cbor_internal()))
4307 {
4308 return false;
4309 }
4310 }
4311 }
4312 else
4313 {
4314 while (get() != 0xFF)
4315 {
4316 if (JSON_UNLIKELY(not parse_cbor_internal(false)))
4317 {
4318 return false;
4319 }
4320 }
4321 }
4322
4323 return sax->end_array();
4324 }
4325
4326 /*!
4327 @param[in] len the length of the object or std::size_t(-1) for an
4328 object of indefinite size
4329 @return whether object creation completed
4330 */
get_cbor_object(const std::size_t len)4331 bool get_cbor_object(const std::size_t len)
4332 {
4333 if (JSON_UNLIKELY(not sax->start_object(len)))
4334 {
4335 return false;
4336 }
4337
4338 string_t key;
4339 if (len != std::size_t(-1))
4340 {
4341 for (std::size_t i = 0; i < len; ++i)
4342 {
4343 get();
4344 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
4345 {
4346 return false;
4347 }
4348
4349 if (JSON_UNLIKELY(not parse_cbor_internal()))
4350 {
4351 return false;
4352 }
4353 key.clear();
4354 }
4355 }
4356 else
4357 {
4358 while (get() != 0xFF)
4359 {
4360 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
4361 {
4362 return false;
4363 }
4364
4365 if (JSON_UNLIKELY(not parse_cbor_internal()))
4366 {
4367 return false;
4368 }
4369 key.clear();
4370 }
4371 }
4372
4373 return sax->end_object();
4374 }
4375
4376 /////////////
4377 // MsgPack //
4378 /////////////
4379
4380 /*!
4381 @return whether a valid MessagePack value was passed to the SAX parser
4382 */
parse_msgpack_internal()4383 bool parse_msgpack_internal()
4384 {
4385 switch (get())
4386 {
4387 // EOF
4388 case std::char_traits<char>::eof():
4389 return unexpect_eof(input_format_t::msgpack, "value");
4390
4391 // positive fixint
4392 case 0x00:
4393 case 0x01:
4394 case 0x02:
4395 case 0x03:
4396 case 0x04:
4397 case 0x05:
4398 case 0x06:
4399 case 0x07:
4400 case 0x08:
4401 case 0x09:
4402 case 0x0A:
4403 case 0x0B:
4404 case 0x0C:
4405 case 0x0D:
4406 case 0x0E:
4407 case 0x0F:
4408 case 0x10:
4409 case 0x11:
4410 case 0x12:
4411 case 0x13:
4412 case 0x14:
4413 case 0x15:
4414 case 0x16:
4415 case 0x17:
4416 case 0x18:
4417 case 0x19:
4418 case 0x1A:
4419 case 0x1B:
4420 case 0x1C:
4421 case 0x1D:
4422 case 0x1E:
4423 case 0x1F:
4424 case 0x20:
4425 case 0x21:
4426 case 0x22:
4427 case 0x23:
4428 case 0x24:
4429 case 0x25:
4430 case 0x26:
4431 case 0x27:
4432 case 0x28:
4433 case 0x29:
4434 case 0x2A:
4435 case 0x2B:
4436 case 0x2C:
4437 case 0x2D:
4438 case 0x2E:
4439 case 0x2F:
4440 case 0x30:
4441 case 0x31:
4442 case 0x32:
4443 case 0x33:
4444 case 0x34:
4445 case 0x35:
4446 case 0x36:
4447 case 0x37:
4448 case 0x38:
4449 case 0x39:
4450 case 0x3A:
4451 case 0x3B:
4452 case 0x3C:
4453 case 0x3D:
4454 case 0x3E:
4455 case 0x3F:
4456 case 0x40:
4457 case 0x41:
4458 case 0x42:
4459 case 0x43:
4460 case 0x44:
4461 case 0x45:
4462 case 0x46:
4463 case 0x47:
4464 case 0x48:
4465 case 0x49:
4466 case 0x4A:
4467 case 0x4B:
4468 case 0x4C:
4469 case 0x4D:
4470 case 0x4E:
4471 case 0x4F:
4472 case 0x50:
4473 case 0x51:
4474 case 0x52:
4475 case 0x53:
4476 case 0x54:
4477 case 0x55:
4478 case 0x56:
4479 case 0x57:
4480 case 0x58:
4481 case 0x59:
4482 case 0x5A:
4483 case 0x5B:
4484 case 0x5C:
4485 case 0x5D:
4486 case 0x5E:
4487 case 0x5F:
4488 case 0x60:
4489 case 0x61:
4490 case 0x62:
4491 case 0x63:
4492 case 0x64:
4493 case 0x65:
4494 case 0x66:
4495 case 0x67:
4496 case 0x68:
4497 case 0x69:
4498 case 0x6A:
4499 case 0x6B:
4500 case 0x6C:
4501 case 0x6D:
4502 case 0x6E:
4503 case 0x6F:
4504 case 0x70:
4505 case 0x71:
4506 case 0x72:
4507 case 0x73:
4508 case 0x74:
4509 case 0x75:
4510 case 0x76:
4511 case 0x77:
4512 case 0x78:
4513 case 0x79:
4514 case 0x7A:
4515 case 0x7B:
4516 case 0x7C:
4517 case 0x7D:
4518 case 0x7E:
4519 case 0x7F:
4520 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
4521
4522 // fixmap
4523 case 0x80:
4524 case 0x81:
4525 case 0x82:
4526 case 0x83:
4527 case 0x84:
4528 case 0x85:
4529 case 0x86:
4530 case 0x87:
4531 case 0x88:
4532 case 0x89:
4533 case 0x8A:
4534 case 0x8B:
4535 case 0x8C:
4536 case 0x8D:
4537 case 0x8E:
4538 case 0x8F:
4539 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
4540
4541 // fixarray
4542 case 0x90:
4543 case 0x91:
4544 case 0x92:
4545 case 0x93:
4546 case 0x94:
4547 case 0x95:
4548 case 0x96:
4549 case 0x97:
4550 case 0x98:
4551 case 0x99:
4552 case 0x9A:
4553 case 0x9B:
4554 case 0x9C:
4555 case 0x9D:
4556 case 0x9E:
4557 case 0x9F:
4558 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
4559
4560 // fixstr
4561 case 0xA0:
4562 case 0xA1:
4563 case 0xA2:
4564 case 0xA3:
4565 case 0xA4:
4566 case 0xA5:
4567 case 0xA6:
4568 case 0xA7:
4569 case 0xA8:
4570 case 0xA9:
4571 case 0xAA:
4572 case 0xAB:
4573 case 0xAC:
4574 case 0xAD:
4575 case 0xAE:
4576 case 0xAF:
4577 case 0xB0:
4578 case 0xB1:
4579 case 0xB2:
4580 case 0xB3:
4581 case 0xB4:
4582 case 0xB5:
4583 case 0xB6:
4584 case 0xB7:
4585 case 0xB8:
4586 case 0xB9:
4587 case 0xBA:
4588 case 0xBB:
4589 case 0xBC:
4590 case 0xBD:
4591 case 0xBE:
4592 case 0xBF:
4593 {
4594 string_t s;
4595 return get_msgpack_string(s) and sax->string(s);
4596 }
4597
4598 case 0xC0: // nil
4599 return sax->null();
4600
4601 case 0xC2: // false
4602 return sax->boolean(false);
4603
4604 case 0xC3: // true
4605 return sax->boolean(true);
4606
4607 case 0xCA: // float 32
4608 {
4609 float number;
4610 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
4611 }
4612
4613 case 0xCB: // float 64
4614 {
4615 double number;
4616 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
4617 }
4618
4619 case 0xCC: // uint 8
4620 {
4621 std::uint8_t number;
4622 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4623 }
4624
4625 case 0xCD: // uint 16
4626 {
4627 std::uint16_t number;
4628 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4629 }
4630
4631 case 0xCE: // uint 32
4632 {
4633 std::uint32_t number;
4634 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4635 }
4636
4637 case 0xCF: // uint 64
4638 {
4639 std::uint64_t number;
4640 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4641 }
4642
4643 case 0xD0: // int 8
4644 {
4645 std::int8_t number;
4646 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4647 }
4648
4649 case 0xD1: // int 16
4650 {
4651 std::int16_t number;
4652 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4653 }
4654
4655 case 0xD2: // int 32
4656 {
4657 std::int32_t number;
4658 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4659 }
4660
4661 case 0xD3: // int 64
4662 {
4663 std::int64_t number;
4664 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4665 }
4666
4667 case 0xD9: // str 8
4668 case 0xDA: // str 16
4669 case 0xDB: // str 32
4670 {
4671 string_t s;
4672 return get_msgpack_string(s) and sax->string(s);
4673 }
4674
4675 case 0xDC: // array 16
4676 {
4677 std::uint16_t len;
4678 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
4679 }
4680
4681 case 0xDD: // array 32
4682 {
4683 std::uint32_t len;
4684 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
4685 }
4686
4687 case 0xDE: // map 16
4688 {
4689 std::uint16_t len;
4690 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
4691 }
4692
4693 case 0xDF: // map 32
4694 {
4695 std::uint32_t len;
4696 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
4697 }
4698
4699 // negative fixint
4700 case 0xE0:
4701 case 0xE1:
4702 case 0xE2:
4703 case 0xE3:
4704 case 0xE4:
4705 case 0xE5:
4706 case 0xE6:
4707 case 0xE7:
4708 case 0xE8:
4709 case 0xE9:
4710 case 0xEA:
4711 case 0xEB:
4712 case 0xEC:
4713 case 0xED:
4714 case 0xEE:
4715 case 0xEF:
4716 case 0xF0:
4717 case 0xF1:
4718 case 0xF2:
4719 case 0xF3:
4720 case 0xF4:
4721 case 0xF5:
4722 case 0xF6:
4723 case 0xF7:
4724 case 0xF8:
4725 case 0xF9:
4726 case 0xFA:
4727 case 0xFB:
4728 case 0xFC:
4729 case 0xFD:
4730 case 0xFE:
4731 case 0xFF:
4732 return sax->number_integer(static_cast<std::int8_t>(current));
4733
4734 default: // anything else
4735 {
4736 auto last_token = get_token_string();
4737 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")));
4738 }
4739 }
4740 }
4741
4742 /*!
4743 @brief reads a MessagePack string
4744
4745 This function first reads starting bytes to determine the expected
4746 string length and then copies this number of bytes into a string.
4747
4748 @param[out] result created string
4749
4750 @return whether string creation completed
4751 */
get_msgpack_string(string_t & result)4752 bool get_msgpack_string(string_t& result)
4753 {
4754 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
4755 {
4756 return false;
4757 }
4758
4759 switch (current)
4760 {
4761 // fixstr
4762 case 0xA0:
4763 case 0xA1:
4764 case 0xA2:
4765 case 0xA3:
4766 case 0xA4:
4767 case 0xA5:
4768 case 0xA6:
4769 case 0xA7:
4770 case 0xA8:
4771 case 0xA9:
4772 case 0xAA:
4773 case 0xAB:
4774 case 0xAC:
4775 case 0xAD:
4776 case 0xAE:
4777 case 0xAF:
4778 case 0xB0:
4779 case 0xB1:
4780 case 0xB2:
4781 case 0xB3:
4782 case 0xB4:
4783 case 0xB5:
4784 case 0xB6:
4785 case 0xB7:
4786 case 0xB8:
4787 case 0xB9:
4788 case 0xBA:
4789 case 0xBB:
4790 case 0xBC:
4791 case 0xBD:
4792 case 0xBE:
4793 case 0xBF:
4794 {
4795 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
4796 }
4797
4798 case 0xD9: // str 8
4799 {
4800 std::uint8_t len;
4801 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4802 }
4803
4804 case 0xDA: // str 16
4805 {
4806 std::uint16_t len;
4807 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4808 }
4809
4810 case 0xDB: // str 32
4811 {
4812 std::uint32_t len;
4813 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4814 }
4815
4816 default:
4817 {
4818 auto last_token = get_token_string();
4819 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")));
4820 }
4821 }
4822 }
4823
4824 /*!
4825 @param[in] len the length of the array
4826 @return whether array creation completed
4827 */
get_msgpack_array(const std::size_t len)4828 bool get_msgpack_array(const std::size_t len)
4829 {
4830 if (JSON_UNLIKELY(not sax->start_array(len)))
4831 {
4832 return false;
4833 }
4834
4835 for (std::size_t i = 0; i < len; ++i)
4836 {
4837 if (JSON_UNLIKELY(not parse_msgpack_internal()))
4838 {
4839 return false;
4840 }
4841 }
4842
4843 return sax->end_array();
4844 }
4845
4846 /*!
4847 @param[in] len the length of the object
4848 @return whether object creation completed
4849 */
get_msgpack_object(const std::size_t len)4850 bool get_msgpack_object(const std::size_t len)
4851 {
4852 if (JSON_UNLIKELY(not sax->start_object(len)))
4853 {
4854 return false;
4855 }
4856
4857 string_t key;
4858 for (std::size_t i = 0; i < len; ++i)
4859 {
4860 get();
4861 if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
4862 {
4863 return false;
4864 }
4865
4866 if (JSON_UNLIKELY(not parse_msgpack_internal()))
4867 {
4868 return false;
4869 }
4870 key.clear();
4871 }
4872
4873 return sax->end_object();
4874 }
4875
4876 ////////////
4877 // UBJSON //
4878 ////////////
4879
4880 /*!
4881 @param[in] get_char whether a new character should be retrieved from the
4882 input (true, default) or whether the last read
4883 character should be considered instead
4884
4885 @return whether a valid UBJSON value was passed to the SAX parser
4886 */
parse_ubjson_internal(const bool get_char=true)4887 bool parse_ubjson_internal(const bool get_char = true)
4888 {
4889 return get_ubjson_value(get_char ? get_ignore_noop() : current);
4890 }
4891
4892 /*!
4893 @brief reads a UBJSON string
4894
4895 This function is either called after reading the 'S' byte explicitly
4896 indicating a string, or in case of an object key where the 'S' byte can be
4897 left out.
4898
4899 @param[out] result created string
4900 @param[in] get_char whether a new character should be retrieved from the
4901 input (true, default) or whether the last read
4902 character should be considered instead
4903
4904 @return whether string creation completed
4905 */
get_ubjson_string(string_t & result,const bool get_char=true)4906 bool get_ubjson_string(string_t& result, const bool get_char = true)
4907 {
4908 if (get_char)
4909 {
4910 get(); // TODO(niels): may we ignore N here?
4911 }
4912
4913 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
4914 {
4915 return false;
4916 }
4917
4918 switch (current)
4919 {
4920 case 'U':
4921 {
4922 std::uint8_t len;
4923 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4924 }
4925
4926 case 'i':
4927 {
4928 std::int8_t len;
4929 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4930 }
4931
4932 case 'I':
4933 {
4934 std::int16_t len;
4935 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4936 }
4937
4938 case 'l':
4939 {
4940 std::int32_t len;
4941 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4942 }
4943
4944 case 'L':
4945 {
4946 std::int64_t len;
4947 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4948 }
4949
4950 default:
4951 auto last_token = get_token_string();
4952 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")));
4953 }
4954 }
4955
4956 /*!
4957 @param[out] result determined size
4958 @return whether size determination completed
4959 */
get_ubjson_size_value(std::size_t & result)4960 bool get_ubjson_size_value(std::size_t& result)
4961 {
4962 switch (get_ignore_noop())
4963 {
4964 case 'U':
4965 {
4966 std::uint8_t number;
4967 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
4968 {
4969 return false;
4970 }
4971 result = static_cast<std::size_t>(number);
4972 return true;
4973 }
4974
4975 case 'i':
4976 {
4977 std::int8_t number;
4978 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
4979 {
4980 return false;
4981 }
4982 result = static_cast<std::size_t>(number);
4983 return true;
4984 }
4985
4986 case 'I':
4987 {
4988 std::int16_t number;
4989 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
4990 {
4991 return false;
4992 }
4993 result = static_cast<std::size_t>(number);
4994 return true;
4995 }
4996
4997 case 'l':
4998 {
4999 std::int32_t number;
5000 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5001 {
5002 return false;
5003 }
5004 result = static_cast<std::size_t>(number);
5005 return true;
5006 }
5007
5008 case 'L':
5009 {
5010 std::int64_t number;
5011 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5012 {
5013 return false;
5014 }
5015 result = static_cast<std::size_t>(number);
5016 return true;
5017 }
5018
5019 default:
5020 {
5021 auto last_token = get_token_string();
5022 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")));
5023 }
5024 }
5025 }
5026
5027 /*!
5028 @brief determine the type and size for a container
5029
5030 In the optimized UBJSON format, a type and a size can be provided to allow
5031 for a more compact representation.
5032
5033 @param[out] result pair of the size and the type
5034
5035 @return whether pair creation completed
5036 */
get_ubjson_size_type(std::pair<std::size_t,int> & result)5037 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
5038 {
5039 result.first = string_t::npos; // size
5040 result.second = 0; // type
5041
5042 get_ignore_noop();
5043
5044 if (current == '$')
5045 {
5046 result.second = get(); // must not ignore 'N', because 'N' maybe the type
5047 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
5048 {
5049 return false;
5050 }
5051
5052 get_ignore_noop();
5053 if (JSON_UNLIKELY(current != '#'))
5054 {
5055 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
5056 {
5057 return false;
5058 }
5059 auto last_token = get_token_string();
5060 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")));
5061 }
5062
5063 return get_ubjson_size_value(result.first);
5064 }
5065
5066 if (current == '#')
5067 {
5068 return get_ubjson_size_value(result.first);
5069 }
5070
5071 return true;
5072 }
5073
5074 /*!
5075 @param prefix the previously read or set type prefix
5076 @return whether value creation completed
5077 */
get_ubjson_value(const int prefix)5078 bool get_ubjson_value(const int prefix)
5079 {
5080 switch (prefix)
5081 {
5082 case std::char_traits<char>::eof(): // EOF
5083 return unexpect_eof(input_format_t::ubjson, "value");
5084
5085 case 'T': // true
5086 return sax->boolean(true);
5087 case 'F': // false
5088 return sax->boolean(false);
5089
5090 case 'Z': // null
5091 return sax->null();
5092
5093 case 'U':
5094 {
5095 std::uint8_t number;
5096 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
5097 }
5098
5099 case 'i':
5100 {
5101 std::int8_t number;
5102 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5103 }
5104
5105 case 'I':
5106 {
5107 std::int16_t number;
5108 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5109 }
5110
5111 case 'l':
5112 {
5113 std::int32_t number;
5114 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5115 }
5116
5117 case 'L':
5118 {
5119 std::int64_t number;
5120 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5121 }
5122
5123 case 'd':
5124 {
5125 float number;
5126 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5127 }
5128
5129 case 'D':
5130 {
5131 double number;
5132 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5133 }
5134
5135 case 'C': // char
5136 {
5137 get();
5138 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
5139 {
5140 return false;
5141 }
5142 if (JSON_UNLIKELY(current > 127))
5143 {
5144 auto last_token = get_token_string();
5145 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")));
5146 }
5147 string_t s(1, static_cast<char>(current));
5148 return sax->string(s);
5149 }
5150
5151 case 'S': // string
5152 {
5153 string_t s;
5154 return get_ubjson_string(s) and sax->string(s);
5155 }
5156
5157 case '[': // array
5158 return get_ubjson_array();
5159
5160 case '{': // object
5161 return get_ubjson_object();
5162
5163 default: // anything else
5164 {
5165 auto last_token = get_token_string();
5166 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")));
5167 }
5168 }
5169 }
5170
5171 /*!
5172 @return whether array creation completed
5173 */
get_ubjson_array()5174 bool get_ubjson_array()
5175 {
5176 std::pair<std::size_t, int> size_and_type;
5177 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
5178 {
5179 return false;
5180 }
5181
5182 if (size_and_type.first != string_t::npos)
5183 {
5184 if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
5185 {
5186 return false;
5187 }
5188
5189 if (size_and_type.second != 0)
5190 {
5191 if (size_and_type.second != 'N')
5192 {
5193 for (std::size_t i = 0; i < size_and_type.first; ++i)
5194 {
5195 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
5196 {
5197 return false;
5198 }
5199 }
5200 }
5201 }
5202 else
5203 {
5204 for (std::size_t i = 0; i < size_and_type.first; ++i)
5205 {
5206 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5207 {
5208 return false;
5209 }
5210 }
5211 }
5212 }
5213 else
5214 {
5215 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
5216 {
5217 return false;
5218 }
5219
5220 while (current != ']')
5221 {
5222 if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
5223 {
5224 return false;
5225 }
5226 get_ignore_noop();
5227 }
5228 }
5229
5230 return sax->end_array();
5231 }
5232
5233 /*!
5234 @return whether object creation completed
5235 */
get_ubjson_object()5236 bool get_ubjson_object()
5237 {
5238 std::pair<std::size_t, int> size_and_type;
5239 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
5240 {
5241 return false;
5242 }
5243
5244 string_t key;
5245 if (size_and_type.first != string_t::npos)
5246 {
5247 if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
5248 {
5249 return false;
5250 }
5251
5252 if (size_and_type.second != 0)
5253 {
5254 for (std::size_t i = 0; i < size_and_type.first; ++i)
5255 {
5256 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
5257 {
5258 return false;
5259 }
5260 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
5261 {
5262 return false;
5263 }
5264 key.clear();
5265 }
5266 }
5267 else
5268 {
5269 for (std::size_t i = 0; i < size_and_type.first; ++i)
5270 {
5271 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
5272 {
5273 return false;
5274 }
5275 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5276 {
5277 return false;
5278 }
5279 key.clear();
5280 }
5281 }
5282 }
5283 else
5284 {
5285 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
5286 {
5287 return false;
5288 }
5289
5290 while (current != '}')
5291 {
5292 if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
5293 {
5294 return false;
5295 }
5296 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5297 {
5298 return false;
5299 }
5300 get_ignore_noop();
5301 key.clear();
5302 }
5303 }
5304
5305 return sax->end_object();
5306 }
5307
5308 ///////////////////////
5309 // Utility functions //
5310 ///////////////////////
5311
5312 /*!
5313 @brief get next character from the input
5314
5315 This function provides the interface to the used input adapter. It does
5316 not throw in case the input reached EOF, but returns a -'ve valued
5317 `std::char_traits<char>::eof()` in that case.
5318
5319 @return character read from the input
5320 */
get()5321 int get()
5322 {
5323 ++chars_read;
5324 return current = ia->get_character();
5325 }
5326
5327 /*!
5328 @return character read from the input after ignoring all 'N' entries
5329 */
get_ignore_noop()5330 int get_ignore_noop()
5331 {
5332 do
5333 {
5334 get();
5335 }
5336 while (current == 'N');
5337
5338 return current;
5339 }
5340
5341 /*
5342 @brief read a number from the input
5343
5344 @tparam NumberType the type of the number
5345 @param[in] format the current format (for diagnostics)
5346 @param[out] result number of type @a NumberType
5347
5348 @return whether conversion completed
5349
5350 @note This function needs to respect the system's endianess, because
5351 bytes in CBOR, MessagePack, and UBJSON are stored in network order
5352 (big endian) and therefore need reordering on little endian systems.
5353 */
5354 template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)5355 bool get_number(const input_format_t format, NumberType& result)
5356 {
5357 // step 1: read input into array with system's byte order
5358 std::array<std::uint8_t, sizeof(NumberType)> vec;
5359 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5360 {
5361 get();
5362 if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
5363 {
5364 return false;
5365 }
5366
5367 // reverse byte order prior to conversion if necessary
5368 if (is_little_endian != InputIsLittleEndian)
5369 {
5370 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
5371 }
5372 else
5373 {
5374 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
5375 }
5376 }
5377
5378 // step 2: convert array into number of type T and return
5379 std::memcpy(&result, vec.data(), sizeof(NumberType));
5380 return true;
5381 }
5382
5383 /*!
5384 @brief create a string by reading characters from the input
5385
5386 @tparam NumberType the type of the number
5387 @param[in] format the current format (for diagnostics)
5388 @param[in] len number of characters to read
5389 @param[out] result string created by reading @a len bytes
5390
5391 @return whether string creation completed
5392
5393 @note We can not reserve @a len bytes for the result, because @a len
5394 may be too large. Usually, @ref unexpect_eof() detects the end of
5395 the input before we run out of string memory.
5396 */
5397 template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)5398 bool get_string(const input_format_t format,
5399 const NumberType len,
5400 string_t& result)
5401 {
5402 bool success = true;
5403 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
5404 {
5405 get();
5406 if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
5407 {
5408 success = false;
5409 }
5410 return static_cast<char>(current);
5411 });
5412 return success;
5413 }
5414
5415 /*!
5416 @param[in] format the current format (for diagnostics)
5417 @param[in] context further context information (for diagnostics)
5418 @return whether the last read character is not EOF
5419 */
unexpect_eof(const input_format_t format,const char * context) const5420 bool unexpect_eof(const input_format_t format, const char* context) const
5421 {
5422 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
5423 {
5424 return sax->parse_error(chars_read, "<end of file>",
5425 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
5426 }
5427 return true;
5428 }
5429
5430 /*!
5431 @return a string representation of the last read byte
5432 */
get_token_string() const5433 std::string get_token_string() const
5434 {
5435 std::array<char, 3> cr{{}};
5436 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
5437 return std::string{cr.data()};
5438 }
5439
5440 /*!
5441 @param[in] format the current format
5442 @param[in] detail a detailed error message
5443 @param[in] context further contect information
5444 @return a message string to use in the parse_error exceptions
5445 */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const5446 std::string exception_message(const input_format_t format,
5447 const std::string& detail,
5448 const std::string& context) const
5449 {
5450 std::string error_msg = "syntax error while parsing ";
5451
5452 switch (format)
5453 {
5454 case input_format_t::cbor:
5455 error_msg += "CBOR";
5456 break;
5457
5458 case input_format_t::msgpack:
5459 error_msg += "MessagePack";
5460 break;
5461
5462 case input_format_t::ubjson:
5463 error_msg += "UBJSON";
5464 break;
5465
5466 case input_format_t::bson:
5467 error_msg += "BSON";
5468 break;
5469
5470 default: // LCOV_EXCL_LINE
5471 assert(false); // LCOV_EXCL_LINE
5472 }
5473
5474 return error_msg + " " + context + ": " + detail;
5475 }
5476
5477 private:
5478 /// input adapter
5479 input_adapter_t ia = nullptr;
5480
5481 /// the current character
5482 int current = std::char_traits<char>::eof();
5483
5484 /// the number of characters read
5485 std::size_t chars_read = 0;
5486
5487 /// whether we can assume little endianess
5488 const bool is_little_endian = little_endianess();
5489
5490 /// the SAX parser
5491 json_sax_t* sax = nullptr;
5492 };
5493 } // namespace detail
5494 } // namespace nlohmann
5495
5496 // #include <nlohmann/detail/input/input_adapters.hpp>
5497
5498 // #include <nlohmann/detail/input/lexer.hpp>
5499
5500
5501 #include <array> // array
5502 #include <clocale> // localeconv
5503 #include <cstddef> // size_t
5504 #include <cstdio> // snprintf
5505 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5506 #include <initializer_list> // initializer_list
5507 #include <string> // char_traits, string
5508 #include <utility> // move
5509 #include <vector> // vector
5510
5511 // #include <nlohmann/detail/input/input_adapters.hpp>
5512
5513 // #include <nlohmann/detail/input/position_t.hpp>
5514
5515 // #include <nlohmann/detail/macro_scope.hpp>
5516
5517
5518 namespace nlohmann
5519 {
5520 namespace detail
5521 {
5522 ///////////
5523 // lexer //
5524 ///////////
5525
5526 /*!
5527 @brief lexical analysis
5528
5529 This class organizes the lexical analysis during JSON deserialization.
5530 */
5531 template<typename BasicJsonType>
5532 class lexer
5533 {
5534 using number_integer_t = typename BasicJsonType::number_integer_t;
5535 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5536 using number_float_t = typename BasicJsonType::number_float_t;
5537 using string_t = typename BasicJsonType::string_t;
5538
5539 public:
5540 /// token types for the parser
5541 enum class token_type
5542 {
5543 uninitialized, ///< indicating the scanner is uninitialized
5544 literal_true, ///< the `true` literal
5545 literal_false, ///< the `false` literal
5546 literal_null, ///< the `null` literal
5547 value_string, ///< a string -- use get_string() for actual value
5548 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
5549 value_integer, ///< a signed integer -- use get_number_integer() for actual value
5550 value_float, ///< an floating point number -- use get_number_float() for actual value
5551 begin_array, ///< the character for array begin `[`
5552 begin_object, ///< the character for object begin `{`
5553 end_array, ///< the character for array end `]`
5554 end_object, ///< the character for object end `}`
5555 name_separator, ///< the name separator `:`
5556 value_separator, ///< the value separator `,`
5557 parse_error, ///< indicating a parse error
5558 end_of_input, ///< indicating the end of the input buffer
5559 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
5560 };
5561
5562 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)5563 static const char* token_type_name(const token_type t) noexcept
5564 {
5565 switch (t)
5566 {
5567 case token_type::uninitialized:
5568 return "<uninitialized>";
5569 case token_type::literal_true:
5570 return "true literal";
5571 case token_type::literal_false:
5572 return "false literal";
5573 case token_type::literal_null:
5574 return "null literal";
5575 case token_type::value_string:
5576 return "string literal";
5577 case lexer::token_type::value_unsigned:
5578 case lexer::token_type::value_integer:
5579 case lexer::token_type::value_float:
5580 return "number literal";
5581 case token_type::begin_array:
5582 return "'['";
5583 case token_type::begin_object:
5584 return "'{'";
5585 case token_type::end_array:
5586 return "']'";
5587 case token_type::end_object:
5588 return "'}'";
5589 case token_type::name_separator:
5590 return "':'";
5591 case token_type::value_separator:
5592 return "','";
5593 case token_type::parse_error:
5594 return "<parse error>";
5595 case token_type::end_of_input:
5596 return "end of input";
5597 case token_type::literal_or_value:
5598 return "'[', '{', or a literal";
5599 // LCOV_EXCL_START
5600 default: // catch non-enum values
5601 return "unknown token";
5602 // LCOV_EXCL_STOP
5603 }
5604 }
5605
lexer(detail::input_adapter_t && adapter)5606 explicit lexer(detail::input_adapter_t&& adapter)
5607 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
5608
5609 // delete because of pointer members
5610 lexer(const lexer&) = delete;
5611 lexer(lexer&&) = delete;
5612 lexer& operator=(lexer&) = delete;
5613 lexer& operator=(lexer&&) = delete;
5614 ~lexer() = default;
5615
5616 private:
5617 /////////////////////
5618 // locales
5619 /////////////////////
5620
5621 /// return the locale-dependent decimal point
get_decimal_point()5622 static char get_decimal_point() noexcept
5623 {
5624 const auto loc = localeconv();
5625 assert(loc != nullptr);
5626 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
5627 }
5628
5629 /////////////////////
5630 // scan functions
5631 /////////////////////
5632
5633 /*!
5634 @brief get codepoint from 4 hex characters following `\u`
5635
5636 For input "\u c1 c2 c3 c4" the codepoint is:
5637 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
5638 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
5639
5640 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
5641 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
5642 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
5643 between the ASCII value of the character and the desired integer value.
5644
5645 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
5646 non-hex character)
5647 */
get_codepoint()5648 int get_codepoint()
5649 {
5650 // this function only makes sense after reading `\u`
5651 assert(current == 'u');
5652 int codepoint = 0;
5653
5654 const auto factors = { 12u, 8u, 4u, 0u };
5655 for (const auto factor : factors)
5656 {
5657 get();
5658
5659 if (current >= '0' and current <= '9')
5660 {
5661 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
5662 }
5663 else if (current >= 'A' and current <= 'F')
5664 {
5665 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
5666 }
5667 else if (current >= 'a' and current <= 'f')
5668 {
5669 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
5670 }
5671 else
5672 {
5673 return -1;
5674 }
5675 }
5676
5677 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
5678 return codepoint;
5679 }
5680
5681 /*!
5682 @brief check if the next byte(s) are inside a given range
5683
5684 Adds the current byte and, for each passed range, reads a new byte and
5685 checks if it is inside the range. If a violation was detected, set up an
5686 error message and return false. Otherwise, return true.
5687
5688 @param[in] ranges list of integers; interpreted as list of pairs of
5689 inclusive lower and upper bound, respectively
5690
5691 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
5692 1, 2, or 3 pairs. This precondition is enforced by an assertion.
5693
5694 @return true if and only if no range violation was detected
5695 */
next_byte_in_range(std::initializer_list<int> ranges)5696 bool next_byte_in_range(std::initializer_list<int> ranges)
5697 {
5698 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
5699 add(current);
5700
5701 for (auto range = ranges.begin(); range != ranges.end(); ++range)
5702 {
5703 get();
5704 if (JSON_LIKELY(*range <= current and current <= *(++range)))
5705 {
5706 add(current);
5707 }
5708 else
5709 {
5710 error_message = "invalid string: ill-formed UTF-8 byte";
5711 return false;
5712 }
5713 }
5714
5715 return true;
5716 }
5717
5718 /*!
5719 @brief scan a string literal
5720
5721 This function scans a string according to Sect. 7 of RFC 7159. While
5722 scanning, bytes are escaped and copied into buffer token_buffer. Then the
5723 function returns successfully, token_buffer is *not* null-terminated (as it
5724 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
5725 string.
5726
5727 @return token_type::value_string if string could be successfully scanned,
5728 token_type::parse_error otherwise
5729
5730 @note In case of errors, variable error_message contains a textual
5731 description.
5732 */
scan_string()5733 token_type scan_string()
5734 {
5735 // reset token_buffer (ignore opening quote)
5736 reset();
5737
5738 // we entered the function by reading an open quote
5739 assert(current == '\"');
5740
5741 while (true)
5742 {
5743 // get next character
5744 switch (get())
5745 {
5746 // end of file while parsing string
5747 case std::char_traits<char>::eof():
5748 {
5749 error_message = "invalid string: missing closing quote";
5750 return token_type::parse_error;
5751 }
5752
5753 // closing quote
5754 case '\"':
5755 {
5756 return token_type::value_string;
5757 }
5758
5759 // escapes
5760 case '\\':
5761 {
5762 switch (get())
5763 {
5764 // quotation mark
5765 case '\"':
5766 add('\"');
5767 break;
5768 // reverse solidus
5769 case '\\':
5770 add('\\');
5771 break;
5772 // solidus
5773 case '/':
5774 add('/');
5775 break;
5776 // backspace
5777 case 'b':
5778 add('\b');
5779 break;
5780 // form feed
5781 case 'f':
5782 add('\f');
5783 break;
5784 // line feed
5785 case 'n':
5786 add('\n');
5787 break;
5788 // carriage return
5789 case 'r':
5790 add('\r');
5791 break;
5792 // tab
5793 case 't':
5794 add('\t');
5795 break;
5796
5797 // unicode escapes
5798 case 'u':
5799 {
5800 const int codepoint1 = get_codepoint();
5801 int codepoint = codepoint1; // start with codepoint1
5802
5803 if (JSON_UNLIKELY(codepoint1 == -1))
5804 {
5805 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5806 return token_type::parse_error;
5807 }
5808
5809 // check if code point is a high surrogate
5810 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
5811 {
5812 // expect next \uxxxx entry
5813 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
5814 {
5815 const int codepoint2 = get_codepoint();
5816
5817 if (JSON_UNLIKELY(codepoint2 == -1))
5818 {
5819 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5820 return token_type::parse_error;
5821 }
5822
5823 // check if codepoint2 is a low surrogate
5824 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
5825 {
5826 // overwrite codepoint
5827 codepoint = static_cast<int>(
5828 // high surrogate occupies the most significant 22 bits
5829 (static_cast<unsigned int>(codepoint1) << 10u)
5830 // low surrogate occupies the least significant 15 bits
5831 + static_cast<unsigned int>(codepoint2)
5832 // there is still the 0xD800, 0xDC00 and 0x10000 noise
5833 // in the result so we have to subtract with:
5834 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
5835 - 0x35FDC00u);
5836 }
5837 else
5838 {
5839 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5840 return token_type::parse_error;
5841 }
5842 }
5843 else
5844 {
5845 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5846 return token_type::parse_error;
5847 }
5848 }
5849 else
5850 {
5851 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
5852 {
5853 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
5854 return token_type::parse_error;
5855 }
5856 }
5857
5858 // result of the above calculation yields a proper codepoint
5859 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
5860
5861 // translate codepoint into bytes
5862 if (codepoint < 0x80)
5863 {
5864 // 1-byte characters: 0xxxxxxx (ASCII)
5865 add(codepoint);
5866 }
5867 else if (codepoint <= 0x7FF)
5868 {
5869 // 2-byte characters: 110xxxxx 10xxxxxx
5870 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
5871 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5872 }
5873 else if (codepoint <= 0xFFFF)
5874 {
5875 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
5876 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
5877 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5878 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5879 }
5880 else
5881 {
5882 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5883 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
5884 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
5885 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5886 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5887 }
5888
5889 break;
5890 }
5891
5892 // other characters after escape
5893 default:
5894 error_message = "invalid string: forbidden character after backslash";
5895 return token_type::parse_error;
5896 }
5897
5898 break;
5899 }
5900
5901 // invalid control characters
5902 case 0x00:
5903 {
5904 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
5905 return token_type::parse_error;
5906 }
5907
5908 case 0x01:
5909 {
5910 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
5911 return token_type::parse_error;
5912 }
5913
5914 case 0x02:
5915 {
5916 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
5917 return token_type::parse_error;
5918 }
5919
5920 case 0x03:
5921 {
5922 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
5923 return token_type::parse_error;
5924 }
5925
5926 case 0x04:
5927 {
5928 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
5929 return token_type::parse_error;
5930 }
5931
5932 case 0x05:
5933 {
5934 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
5935 return token_type::parse_error;
5936 }
5937
5938 case 0x06:
5939 {
5940 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
5941 return token_type::parse_error;
5942 }
5943
5944 case 0x07:
5945 {
5946 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
5947 return token_type::parse_error;
5948 }
5949
5950 case 0x08:
5951 {
5952 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
5953 return token_type::parse_error;
5954 }
5955
5956 case 0x09:
5957 {
5958 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
5959 return token_type::parse_error;
5960 }
5961
5962 case 0x0A:
5963 {
5964 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
5965 return token_type::parse_error;
5966 }
5967
5968 case 0x0B:
5969 {
5970 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
5971 return token_type::parse_error;
5972 }
5973
5974 case 0x0C:
5975 {
5976 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
5977 return token_type::parse_error;
5978 }
5979
5980 case 0x0D:
5981 {
5982 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
5983 return token_type::parse_error;
5984 }
5985
5986 case 0x0E:
5987 {
5988 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
5989 return token_type::parse_error;
5990 }
5991
5992 case 0x0F:
5993 {
5994 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
5995 return token_type::parse_error;
5996 }
5997
5998 case 0x10:
5999 {
6000 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6001 return token_type::parse_error;
6002 }
6003
6004 case 0x11:
6005 {
6006 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6007 return token_type::parse_error;
6008 }
6009
6010 case 0x12:
6011 {
6012 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6013 return token_type::parse_error;
6014 }
6015
6016 case 0x13:
6017 {
6018 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6019 return token_type::parse_error;
6020 }
6021
6022 case 0x14:
6023 {
6024 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6025 return token_type::parse_error;
6026 }
6027
6028 case 0x15:
6029 {
6030 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6031 return token_type::parse_error;
6032 }
6033
6034 case 0x16:
6035 {
6036 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6037 return token_type::parse_error;
6038 }
6039
6040 case 0x17:
6041 {
6042 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6043 return token_type::parse_error;
6044 }
6045
6046 case 0x18:
6047 {
6048 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6049 return token_type::parse_error;
6050 }
6051
6052 case 0x19:
6053 {
6054 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6055 return token_type::parse_error;
6056 }
6057
6058 case 0x1A:
6059 {
6060 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6061 return token_type::parse_error;
6062 }
6063
6064 case 0x1B:
6065 {
6066 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6067 return token_type::parse_error;
6068 }
6069
6070 case 0x1C:
6071 {
6072 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6073 return token_type::parse_error;
6074 }
6075
6076 case 0x1D:
6077 {
6078 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6079 return token_type::parse_error;
6080 }
6081
6082 case 0x1E:
6083 {
6084 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6085 return token_type::parse_error;
6086 }
6087
6088 case 0x1F:
6089 {
6090 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6091 return token_type::parse_error;
6092 }
6093
6094 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6095 case 0x20:
6096 case 0x21:
6097 case 0x23:
6098 case 0x24:
6099 case 0x25:
6100 case 0x26:
6101 case 0x27:
6102 case 0x28:
6103 case 0x29:
6104 case 0x2A:
6105 case 0x2B:
6106 case 0x2C:
6107 case 0x2D:
6108 case 0x2E:
6109 case 0x2F:
6110 case 0x30:
6111 case 0x31:
6112 case 0x32:
6113 case 0x33:
6114 case 0x34:
6115 case 0x35:
6116 case 0x36:
6117 case 0x37:
6118 case 0x38:
6119 case 0x39:
6120 case 0x3A:
6121 case 0x3B:
6122 case 0x3C:
6123 case 0x3D:
6124 case 0x3E:
6125 case 0x3F:
6126 case 0x40:
6127 case 0x41:
6128 case 0x42:
6129 case 0x43:
6130 case 0x44:
6131 case 0x45:
6132 case 0x46:
6133 case 0x47:
6134 case 0x48:
6135 case 0x49:
6136 case 0x4A:
6137 case 0x4B:
6138 case 0x4C:
6139 case 0x4D:
6140 case 0x4E:
6141 case 0x4F:
6142 case 0x50:
6143 case 0x51:
6144 case 0x52:
6145 case 0x53:
6146 case 0x54:
6147 case 0x55:
6148 case 0x56:
6149 case 0x57:
6150 case 0x58:
6151 case 0x59:
6152 case 0x5A:
6153 case 0x5B:
6154 case 0x5D:
6155 case 0x5E:
6156 case 0x5F:
6157 case 0x60:
6158 case 0x61:
6159 case 0x62:
6160 case 0x63:
6161 case 0x64:
6162 case 0x65:
6163 case 0x66:
6164 case 0x67:
6165 case 0x68:
6166 case 0x69:
6167 case 0x6A:
6168 case 0x6B:
6169 case 0x6C:
6170 case 0x6D:
6171 case 0x6E:
6172 case 0x6F:
6173 case 0x70:
6174 case 0x71:
6175 case 0x72:
6176 case 0x73:
6177 case 0x74:
6178 case 0x75:
6179 case 0x76:
6180 case 0x77:
6181 case 0x78:
6182 case 0x79:
6183 case 0x7A:
6184 case 0x7B:
6185 case 0x7C:
6186 case 0x7D:
6187 case 0x7E:
6188 case 0x7F:
6189 {
6190 add(current);
6191 break;
6192 }
6193
6194 // U+0080..U+07FF: bytes C2..DF 80..BF
6195 case 0xC2:
6196 case 0xC3:
6197 case 0xC4:
6198 case 0xC5:
6199 case 0xC6:
6200 case 0xC7:
6201 case 0xC8:
6202 case 0xC9:
6203 case 0xCA:
6204 case 0xCB:
6205 case 0xCC:
6206 case 0xCD:
6207 case 0xCE:
6208 case 0xCF:
6209 case 0xD0:
6210 case 0xD1:
6211 case 0xD2:
6212 case 0xD3:
6213 case 0xD4:
6214 case 0xD5:
6215 case 0xD6:
6216 case 0xD7:
6217 case 0xD8:
6218 case 0xD9:
6219 case 0xDA:
6220 case 0xDB:
6221 case 0xDC:
6222 case 0xDD:
6223 case 0xDE:
6224 case 0xDF:
6225 {
6226 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
6227 {
6228 return token_type::parse_error;
6229 }
6230 break;
6231 }
6232
6233 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6234 case 0xE0:
6235 {
6236 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6237 {
6238 return token_type::parse_error;
6239 }
6240 break;
6241 }
6242
6243 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6244 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6245 case 0xE1:
6246 case 0xE2:
6247 case 0xE3:
6248 case 0xE4:
6249 case 0xE5:
6250 case 0xE6:
6251 case 0xE7:
6252 case 0xE8:
6253 case 0xE9:
6254 case 0xEA:
6255 case 0xEB:
6256 case 0xEC:
6257 case 0xEE:
6258 case 0xEF:
6259 {
6260 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6261 {
6262 return token_type::parse_error;
6263 }
6264 break;
6265 }
6266
6267 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6268 case 0xED:
6269 {
6270 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6271 {
6272 return token_type::parse_error;
6273 }
6274 break;
6275 }
6276
6277 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6278 case 0xF0:
6279 {
6280 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6281 {
6282 return token_type::parse_error;
6283 }
6284 break;
6285 }
6286
6287 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6288 case 0xF1:
6289 case 0xF2:
6290 case 0xF3:
6291 {
6292 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6293 {
6294 return token_type::parse_error;
6295 }
6296 break;
6297 }
6298
6299 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6300 case 0xF4:
6301 {
6302 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6303 {
6304 return token_type::parse_error;
6305 }
6306 break;
6307 }
6308
6309 // remaining bytes (80..C1 and F5..FF) are ill-formed
6310 default:
6311 {
6312 error_message = "invalid string: ill-formed UTF-8 byte";
6313 return token_type::parse_error;
6314 }
6315 }
6316 }
6317 }
6318
strtof(float & f,const char * str,char ** endptr)6319 static void strtof(float& f, const char* str, char** endptr) noexcept
6320 {
6321 f = std::strtof(str, endptr);
6322 }
6323
strtof(double & f,const char * str,char ** endptr)6324 static void strtof(double& f, const char* str, char** endptr) noexcept
6325 {
6326 f = std::strtod(str, endptr);
6327 }
6328
strtof(long double & f,const char * str,char ** endptr)6329 static void strtof(long double& f, const char* str, char** endptr) noexcept
6330 {
6331 f = std::strtold(str, endptr);
6332 }
6333
6334 /*!
6335 @brief scan a number literal
6336
6337 This function scans a string according to Sect. 6 of RFC 7159.
6338
6339 The function is realized with a deterministic finite state machine derived
6340 from the grammar described in RFC 7159. Starting in state "init", the
6341 input is read and used to determined the next state. Only state "done"
6342 accepts the number. State "error" is a trap state to model errors. In the
6343 table below, "anything" means any character but the ones listed before.
6344
6345 state | 0 | 1-9 | e E | + | - | . | anything
6346 ---------|----------|----------|----------|---------|---------|----------|-----------
6347 init | zero | any1 | [error] | [error] | minus | [error] | [error]
6348 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
6349 zero | done | done | exponent | done | done | decimal1 | done
6350 any1 | any1 | any1 | exponent | done | done | decimal1 | done
6351 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
6352 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
6353 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
6354 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
6355 any2 | any2 | any2 | done | done | done | done | done
6356
6357 The state machine is realized with one label per state (prefixed with
6358 "scan_number_") and `goto` statements between them. The state machine
6359 contains cycles, but any cycle can be left when EOF is read. Therefore,
6360 the function is guaranteed to terminate.
6361
6362 During scanning, the read bytes are stored in token_buffer. This string is
6363 then converted to a signed integer, an unsigned integer, or a
6364 floating-point number.
6365
6366 @return token_type::value_unsigned, token_type::value_integer, or
6367 token_type::value_float if number could be successfully scanned,
6368 token_type::parse_error otherwise
6369
6370 @note The scanner is independent of the current locale. Internally, the
6371 locale's decimal point is used instead of `.` to work with the
6372 locale-dependent converters.
6373 */
scan_number()6374 token_type scan_number() // lgtm [cpp/use-of-goto]
6375 {
6376 // reset token_buffer to store the number's bytes
6377 reset();
6378
6379 // the type of the parsed number; initially set to unsigned; will be
6380 // changed if minus sign, decimal point or exponent is read
6381 token_type number_type = token_type::value_unsigned;
6382
6383 // state (init): we just found out we need to scan a number
6384 switch (current)
6385 {
6386 case '-':
6387 {
6388 add(current);
6389 goto scan_number_minus;
6390 }
6391
6392 case '0':
6393 {
6394 add(current);
6395 goto scan_number_zero;
6396 }
6397
6398 case '1':
6399 case '2':
6400 case '3':
6401 case '4':
6402 case '5':
6403 case '6':
6404 case '7':
6405 case '8':
6406 case '9':
6407 {
6408 add(current);
6409 goto scan_number_any1;
6410 }
6411
6412 // all other characters are rejected outside scan_number()
6413 default: // LCOV_EXCL_LINE
6414 assert(false); // LCOV_EXCL_LINE
6415 }
6416
6417 scan_number_minus:
6418 // state: we just parsed a leading minus sign
6419 number_type = token_type::value_integer;
6420 switch (get())
6421 {
6422 case '0':
6423 {
6424 add(current);
6425 goto scan_number_zero;
6426 }
6427
6428 case '1':
6429 case '2':
6430 case '3':
6431 case '4':
6432 case '5':
6433 case '6':
6434 case '7':
6435 case '8':
6436 case '9':
6437 {
6438 add(current);
6439 goto scan_number_any1;
6440 }
6441
6442 default:
6443 {
6444 error_message = "invalid number; expected digit after '-'";
6445 return token_type::parse_error;
6446 }
6447 }
6448
6449 scan_number_zero:
6450 // state: we just parse a zero (maybe with a leading minus sign)
6451 switch (get())
6452 {
6453 case '.':
6454 {
6455 add(decimal_point_char);
6456 goto scan_number_decimal1;
6457 }
6458
6459 case 'e':
6460 case 'E':
6461 {
6462 add(current);
6463 goto scan_number_exponent;
6464 }
6465
6466 default:
6467 goto scan_number_done;
6468 }
6469
6470 scan_number_any1:
6471 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6472 switch (get())
6473 {
6474 case '0':
6475 case '1':
6476 case '2':
6477 case '3':
6478 case '4':
6479 case '5':
6480 case '6':
6481 case '7':
6482 case '8':
6483 case '9':
6484 {
6485 add(current);
6486 goto scan_number_any1;
6487 }
6488
6489 case '.':
6490 {
6491 add(decimal_point_char);
6492 goto scan_number_decimal1;
6493 }
6494
6495 case 'e':
6496 case 'E':
6497 {
6498 add(current);
6499 goto scan_number_exponent;
6500 }
6501
6502 default:
6503 goto scan_number_done;
6504 }
6505
6506 scan_number_decimal1:
6507 // state: we just parsed a decimal point
6508 number_type = token_type::value_float;
6509 switch (get())
6510 {
6511 case '0':
6512 case '1':
6513 case '2':
6514 case '3':
6515 case '4':
6516 case '5':
6517 case '6':
6518 case '7':
6519 case '8':
6520 case '9':
6521 {
6522 add(current);
6523 goto scan_number_decimal2;
6524 }
6525
6526 default:
6527 {
6528 error_message = "invalid number; expected digit after '.'";
6529 return token_type::parse_error;
6530 }
6531 }
6532
6533 scan_number_decimal2:
6534 // we just parsed at least one number after a decimal point
6535 switch (get())
6536 {
6537 case '0':
6538 case '1':
6539 case '2':
6540 case '3':
6541 case '4':
6542 case '5':
6543 case '6':
6544 case '7':
6545 case '8':
6546 case '9':
6547 {
6548 add(current);
6549 goto scan_number_decimal2;
6550 }
6551
6552 case 'e':
6553 case 'E':
6554 {
6555 add(current);
6556 goto scan_number_exponent;
6557 }
6558
6559 default:
6560 goto scan_number_done;
6561 }
6562
6563 scan_number_exponent:
6564 // we just parsed an exponent
6565 number_type = token_type::value_float;
6566 switch (get())
6567 {
6568 case '+':
6569 case '-':
6570 {
6571 add(current);
6572 goto scan_number_sign;
6573 }
6574
6575 case '0':
6576 case '1':
6577 case '2':
6578 case '3':
6579 case '4':
6580 case '5':
6581 case '6':
6582 case '7':
6583 case '8':
6584 case '9':
6585 {
6586 add(current);
6587 goto scan_number_any2;
6588 }
6589
6590 default:
6591 {
6592 error_message =
6593 "invalid number; expected '+', '-', or digit after exponent";
6594 return token_type::parse_error;
6595 }
6596 }
6597
6598 scan_number_sign:
6599 // we just parsed an exponent sign
6600 switch (get())
6601 {
6602 case '0':
6603 case '1':
6604 case '2':
6605 case '3':
6606 case '4':
6607 case '5':
6608 case '6':
6609 case '7':
6610 case '8':
6611 case '9':
6612 {
6613 add(current);
6614 goto scan_number_any2;
6615 }
6616
6617 default:
6618 {
6619 error_message = "invalid number; expected digit after exponent sign";
6620 return token_type::parse_error;
6621 }
6622 }
6623
6624 scan_number_any2:
6625 // we just parsed a number after the exponent or exponent sign
6626 switch (get())
6627 {
6628 case '0':
6629 case '1':
6630 case '2':
6631 case '3':
6632 case '4':
6633 case '5':
6634 case '6':
6635 case '7':
6636 case '8':
6637 case '9':
6638 {
6639 add(current);
6640 goto scan_number_any2;
6641 }
6642
6643 default:
6644 goto scan_number_done;
6645 }
6646
6647 scan_number_done:
6648 // unget the character after the number (we only read it to know that
6649 // we are done scanning a number)
6650 unget();
6651
6652 char* endptr = nullptr;
6653 errno = 0;
6654
6655 // try to parse integers first and fall back to floats
6656 if (number_type == token_type::value_unsigned)
6657 {
6658 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
6659
6660 // we checked the number format before
6661 assert(endptr == token_buffer.data() + token_buffer.size());
6662
6663 if (errno == 0)
6664 {
6665 value_unsigned = static_cast<number_unsigned_t>(x);
6666 if (value_unsigned == x)
6667 {
6668 return token_type::value_unsigned;
6669 }
6670 }
6671 }
6672 else if (number_type == token_type::value_integer)
6673 {
6674 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
6675
6676 // we checked the number format before
6677 assert(endptr == token_buffer.data() + token_buffer.size());
6678
6679 if (errno == 0)
6680 {
6681 value_integer = static_cast<number_integer_t>(x);
6682 if (value_integer == x)
6683 {
6684 return token_type::value_integer;
6685 }
6686 }
6687 }
6688
6689 // this code is reached if we parse a floating-point number or if an
6690 // integer conversion above failed
6691 strtof(value_float, token_buffer.data(), &endptr);
6692
6693 // we checked the number format before
6694 assert(endptr == token_buffer.data() + token_buffer.size());
6695
6696 return token_type::value_float;
6697 }
6698
6699 /*!
6700 @param[in] literal_text the literal text to expect
6701 @param[in] length the length of the passed literal text
6702 @param[in] return_type the token type to return on success
6703 */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)6704 token_type scan_literal(const char* literal_text, const std::size_t length,
6705 token_type return_type)
6706 {
6707 assert(current == literal_text[0]);
6708 for (std::size_t i = 1; i < length; ++i)
6709 {
6710 if (JSON_UNLIKELY(get() != literal_text[i]))
6711 {
6712 error_message = "invalid literal";
6713 return token_type::parse_error;
6714 }
6715 }
6716 return return_type;
6717 }
6718
6719 /////////////////////
6720 // input management
6721 /////////////////////
6722
6723 /// reset token_buffer; current character is beginning of token
reset()6724 void reset() noexcept
6725 {
6726 token_buffer.clear();
6727 token_string.clear();
6728 token_string.push_back(std::char_traits<char>::to_char_type(current));
6729 }
6730
6731 /*
6732 @brief get next character from the input
6733
6734 This function provides the interface to the used input adapter. It does
6735 not throw in case the input reached EOF, but returns a
6736 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
6737 for use in error messages.
6738
6739 @return character read from the input
6740 */
get()6741 std::char_traits<char>::int_type get()
6742 {
6743 ++position.chars_read_total;
6744 ++position.chars_read_current_line;
6745
6746 if (next_unget)
6747 {
6748 // just reset the next_unget variable and work with current
6749 next_unget = false;
6750 }
6751 else
6752 {
6753 current = ia->get_character();
6754 }
6755
6756 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6757 {
6758 token_string.push_back(std::char_traits<char>::to_char_type(current));
6759 }
6760
6761 if (current == '\n')
6762 {
6763 ++position.lines_read;
6764 position.chars_read_current_line = 0;
6765 }
6766
6767 return current;
6768 }
6769
6770 /*!
6771 @brief unget current character (read it again on next get)
6772
6773 We implement unget by setting variable next_unget to true. The input is not
6774 changed - we just simulate ungetting by modifying chars_read_total,
6775 chars_read_current_line, and token_string. The next call to get() will
6776 behave as if the unget character is read again.
6777 */
unget()6778 void unget()
6779 {
6780 next_unget = true;
6781
6782 --position.chars_read_total;
6783
6784 // in case we "unget" a newline, we have to also decrement the lines_read
6785 if (position.chars_read_current_line == 0)
6786 {
6787 if (position.lines_read > 0)
6788 {
6789 --position.lines_read;
6790 }
6791 }
6792 else
6793 {
6794 --position.chars_read_current_line;
6795 }
6796
6797 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6798 {
6799 assert(not token_string.empty());
6800 token_string.pop_back();
6801 }
6802 }
6803
6804 /// add a character to token_buffer
add(int c)6805 void add(int c)
6806 {
6807 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
6808 }
6809
6810 public:
6811 /////////////////////
6812 // value getters
6813 /////////////////////
6814
6815 /// return integer value
get_number_integer() const6816 constexpr number_integer_t get_number_integer() const noexcept
6817 {
6818 return value_integer;
6819 }
6820
6821 /// return unsigned integer value
get_number_unsigned() const6822 constexpr number_unsigned_t get_number_unsigned() const noexcept
6823 {
6824 return value_unsigned;
6825 }
6826
6827 /// return floating-point value
get_number_float() const6828 constexpr number_float_t get_number_float() const noexcept
6829 {
6830 return value_float;
6831 }
6832
6833 /// return current string value (implicitly resets the token; useful only once)
get_string()6834 string_t& get_string()
6835 {
6836 return token_buffer;
6837 }
6838
6839 /////////////////////
6840 // diagnostics
6841 /////////////////////
6842
6843 /// return position of last read token
get_position() const6844 constexpr position_t get_position() const noexcept
6845 {
6846 return position;
6847 }
6848
6849 /// return the last read token (for errors only). Will never contain EOF
6850 /// (an arbitrary value that is not a valid char value, often -1), because
6851 /// 255 may legitimately occur. May contain NUL, which should be escaped.
get_token_string() const6852 std::string get_token_string() const
6853 {
6854 // escape control characters
6855 std::string result;
6856 for (const auto c : token_string)
6857 {
6858 if ('\x00' <= c and c <= '\x1F')
6859 {
6860 // escape control characters
6861 std::array<char, 9> cs{{}};
6862 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
6863 result += cs.data();
6864 }
6865 else
6866 {
6867 // add character as is
6868 result.push_back(c);
6869 }
6870 }
6871
6872 return result;
6873 }
6874
6875 /// return syntax error message
get_error_message() const6876 constexpr const char* get_error_message() const noexcept
6877 {
6878 return error_message;
6879 }
6880
6881 /////////////////////
6882 // actual scanner
6883 /////////////////////
6884
6885 /*!
6886 @brief skip the UTF-8 byte order mark
6887 @return true iff there is no BOM or the correct BOM has been skipped
6888 */
skip_bom()6889 bool skip_bom()
6890 {
6891 if (get() == 0xEF)
6892 {
6893 // check if we completely parse the BOM
6894 return get() == 0xBB and get() == 0xBF;
6895 }
6896
6897 // the first character is not the beginning of the BOM; unget it to
6898 // process is later
6899 unget();
6900 return true;
6901 }
6902
scan()6903 token_type scan()
6904 {
6905 // initially, skip the BOM
6906 if (position.chars_read_total == 0 and not skip_bom())
6907 {
6908 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
6909 return token_type::parse_error;
6910 }
6911
6912 // read next character and ignore whitespace
6913 do
6914 {
6915 get();
6916 }
6917 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
6918
6919 switch (current)
6920 {
6921 // structural characters
6922 case '[':
6923 return token_type::begin_array;
6924 case ']':
6925 return token_type::end_array;
6926 case '{':
6927 return token_type::begin_object;
6928 case '}':
6929 return token_type::end_object;
6930 case ':':
6931 return token_type::name_separator;
6932 case ',':
6933 return token_type::value_separator;
6934
6935 // literals
6936 case 't':
6937 return scan_literal("true", 4, token_type::literal_true);
6938 case 'f':
6939 return scan_literal("false", 5, token_type::literal_false);
6940 case 'n':
6941 return scan_literal("null", 4, token_type::literal_null);
6942
6943 // string
6944 case '\"':
6945 return scan_string();
6946
6947 // number
6948 case '-':
6949 case '0':
6950 case '1':
6951 case '2':
6952 case '3':
6953 case '4':
6954 case '5':
6955 case '6':
6956 case '7':
6957 case '8':
6958 case '9':
6959 return scan_number();
6960
6961 // end of input (the null byte is needed when parsing from
6962 // string literals)
6963 case '\0':
6964 case std::char_traits<char>::eof():
6965 return token_type::end_of_input;
6966
6967 // error
6968 default:
6969 error_message = "invalid literal";
6970 return token_type::parse_error;
6971 }
6972 }
6973
6974 private:
6975 /// input adapter
6976 detail::input_adapter_t ia = nullptr;
6977
6978 /// the current character
6979 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
6980
6981 /// whether the next get() call should just return current
6982 bool next_unget = false;
6983
6984 /// the start position of the current token
6985 position_t position {};
6986
6987 /// raw input token string (for error messages)
6988 std::vector<char> token_string {};
6989
6990 /// buffer for variable-length tokens (numbers, strings)
6991 string_t token_buffer {};
6992
6993 /// a description of occurred lexer errors
6994 const char* error_message = "";
6995
6996 // number values
6997 number_integer_t value_integer = 0;
6998 number_unsigned_t value_unsigned = 0;
6999 number_float_t value_float = 0;
7000
7001 /// the decimal point
7002 const char decimal_point_char = '.';
7003 };
7004 } // namespace detail
7005 } // namespace nlohmann
7006
7007 // #include <nlohmann/detail/input/parser.hpp>
7008
7009
7010 #include <cassert> // assert
7011 #include <cmath> // isfinite
7012 #include <cstdint> // uint8_t
7013 #include <functional> // function
7014 #include <string> // string
7015 #include <utility> // move
7016 #include <vector> // vector
7017
7018 // #include <nlohmann/detail/exceptions.hpp>
7019
7020 // #include <nlohmann/detail/input/input_adapters.hpp>
7021
7022 // #include <nlohmann/detail/input/json_sax.hpp>
7023
7024 // #include <nlohmann/detail/input/lexer.hpp>
7025
7026 // #include <nlohmann/detail/macro_scope.hpp>
7027
7028 // #include <nlohmann/detail/meta/is_sax.hpp>
7029
7030 // #include <nlohmann/detail/value_t.hpp>
7031
7032
7033 namespace nlohmann
7034 {
7035 namespace detail
7036 {
7037 ////////////
7038 // parser //
7039 ////////////
7040
7041 /*!
7042 @brief syntax analysis
7043
7044 This class implements a recursive decent parser.
7045 */
7046 template<typename BasicJsonType>
7047 class parser
7048 {
7049 using number_integer_t = typename BasicJsonType::number_integer_t;
7050 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7051 using number_float_t = typename BasicJsonType::number_float_t;
7052 using string_t = typename BasicJsonType::string_t;
7053 using lexer_t = lexer<BasicJsonType>;
7054 using token_type = typename lexer_t::token_type;
7055
7056 public:
7057 enum class parse_event_t : uint8_t
7058 {
7059 /// the parser read `{` and started to process a JSON object
7060 object_start,
7061 /// the parser read `}` and finished processing a JSON object
7062 object_end,
7063 /// the parser read `[` and started to process a JSON array
7064 array_start,
7065 /// the parser read `]` and finished processing a JSON array
7066 array_end,
7067 /// the parser read a key of a value in an object
7068 key,
7069 /// the parser finished reading a JSON value
7070 value
7071 };
7072
7073 using parser_callback_t =
7074 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
7075
7076 /// a parser reading from an input adapter
parser(detail::input_adapter_t && adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)7077 explicit parser(detail::input_adapter_t&& adapter,
7078 const parser_callback_t cb = nullptr,
7079 const bool allow_exceptions_ = true)
7080 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
7081 {
7082 // read first token
7083 get_token();
7084 }
7085
7086 /*!
7087 @brief public parser interface
7088
7089 @param[in] strict whether to expect the last token to be EOF
7090 @param[in,out] result parsed JSON value
7091
7092 @throw parse_error.101 in case of an unexpected token
7093 @throw parse_error.102 if to_unicode fails or surrogate error
7094 @throw parse_error.103 if to_unicode fails
7095 */
parse(const bool strict,BasicJsonType & result)7096 void parse(const bool strict, BasicJsonType& result)
7097 {
7098 if (callback)
7099 {
7100 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
7101 sax_parse_internal(&sdp);
7102 result.assert_invariant();
7103
7104 // in strict mode, input must be completely read
7105 if (strict and (get_token() != token_type::end_of_input))
7106 {
7107 sdp.parse_error(m_lexer.get_position(),
7108 m_lexer.get_token_string(),
7109 parse_error::create(101, m_lexer.get_position(),
7110 exception_message(token_type::end_of_input, "value")));
7111 }
7112
7113 // in case of an error, return discarded value
7114 if (sdp.is_errored())
7115 {
7116 result = value_t::discarded;
7117 return;
7118 }
7119
7120 // set top-level value to null if it was discarded by the callback
7121 // function
7122 if (result.is_discarded())
7123 {
7124 result = nullptr;
7125 }
7126 }
7127 else
7128 {
7129 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
7130 sax_parse_internal(&sdp);
7131 result.assert_invariant();
7132
7133 // in strict mode, input must be completely read
7134 if (strict and (get_token() != token_type::end_of_input))
7135 {
7136 sdp.parse_error(m_lexer.get_position(),
7137 m_lexer.get_token_string(),
7138 parse_error::create(101, m_lexer.get_position(),
7139 exception_message(token_type::end_of_input, "value")));
7140 }
7141
7142 // in case of an error, return discarded value
7143 if (sdp.is_errored())
7144 {
7145 result = value_t::discarded;
7146 return;
7147 }
7148 }
7149 }
7150
7151 /*!
7152 @brief public accept interface
7153
7154 @param[in] strict whether to expect the last token to be EOF
7155 @return whether the input is a proper JSON text
7156 */
accept(const bool strict=true)7157 bool accept(const bool strict = true)
7158 {
7159 json_sax_acceptor<BasicJsonType> sax_acceptor;
7160 return sax_parse(&sax_acceptor, strict);
7161 }
7162
7163 template <typename SAX>
sax_parse(SAX * sax,const bool strict=true)7164 bool sax_parse(SAX* sax, const bool strict = true)
7165 {
7166 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7167 const bool result = sax_parse_internal(sax);
7168
7169 // strict mode: next byte must be EOF
7170 if (result and strict and (get_token() != token_type::end_of_input))
7171 {
7172 return sax->parse_error(m_lexer.get_position(),
7173 m_lexer.get_token_string(),
7174 parse_error::create(101, m_lexer.get_position(),
7175 exception_message(token_type::end_of_input, "value")));
7176 }
7177
7178 return result;
7179 }
7180
7181 private:
7182 template <typename SAX>
sax_parse_internal(SAX * sax)7183 bool sax_parse_internal(SAX* sax)
7184 {
7185 // stack to remember the hierarchy of structured values we are parsing
7186 // true = array; false = object
7187 std::vector<bool> states;
7188 // value to avoid a goto (see comment where set to true)
7189 bool skip_to_state_evaluation = false;
7190
7191 while (true)
7192 {
7193 if (not skip_to_state_evaluation)
7194 {
7195 // invariant: get_token() was called before each iteration
7196 switch (last_token)
7197 {
7198 case token_type::begin_object:
7199 {
7200 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7201 {
7202 return false;
7203 }
7204
7205 // closing } -> we are done
7206 if (get_token() == token_type::end_object)
7207 {
7208 if (JSON_UNLIKELY(not sax->end_object()))
7209 {
7210 return false;
7211 }
7212 break;
7213 }
7214
7215 // parse key
7216 if (JSON_UNLIKELY(last_token != token_type::value_string))
7217 {
7218 return sax->parse_error(m_lexer.get_position(),
7219 m_lexer.get_token_string(),
7220 parse_error::create(101, m_lexer.get_position(),
7221 exception_message(token_type::value_string, "object key")));
7222 }
7223 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7224 {
7225 return false;
7226 }
7227
7228 // parse separator (:)
7229 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7230 {
7231 return sax->parse_error(m_lexer.get_position(),
7232 m_lexer.get_token_string(),
7233 parse_error::create(101, m_lexer.get_position(),
7234 exception_message(token_type::name_separator, "object separator")));
7235 }
7236
7237 // remember we are now inside an object
7238 states.push_back(false);
7239
7240 // parse values
7241 get_token();
7242 continue;
7243 }
7244
7245 case token_type::begin_array:
7246 {
7247 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7248 {
7249 return false;
7250 }
7251
7252 // closing ] -> we are done
7253 if (get_token() == token_type::end_array)
7254 {
7255 if (JSON_UNLIKELY(not sax->end_array()))
7256 {
7257 return false;
7258 }
7259 break;
7260 }
7261
7262 // remember we are now inside an array
7263 states.push_back(true);
7264
7265 // parse values (no need to call get_token)
7266 continue;
7267 }
7268
7269 case token_type::value_float:
7270 {
7271 const auto res = m_lexer.get_number_float();
7272
7273 if (JSON_UNLIKELY(not std::isfinite(res)))
7274 {
7275 return sax->parse_error(m_lexer.get_position(),
7276 m_lexer.get_token_string(),
7277 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
7278 }
7279
7280 if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
7281 {
7282 return false;
7283 }
7284
7285 break;
7286 }
7287
7288 case token_type::literal_false:
7289 {
7290 if (JSON_UNLIKELY(not sax->boolean(false)))
7291 {
7292 return false;
7293 }
7294 break;
7295 }
7296
7297 case token_type::literal_null:
7298 {
7299 if (JSON_UNLIKELY(not sax->null()))
7300 {
7301 return false;
7302 }
7303 break;
7304 }
7305
7306 case token_type::literal_true:
7307 {
7308 if (JSON_UNLIKELY(not sax->boolean(true)))
7309 {
7310 return false;
7311 }
7312 break;
7313 }
7314
7315 case token_type::value_integer:
7316 {
7317 if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
7318 {
7319 return false;
7320 }
7321 break;
7322 }
7323
7324 case token_type::value_string:
7325 {
7326 if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
7327 {
7328 return false;
7329 }
7330 break;
7331 }
7332
7333 case token_type::value_unsigned:
7334 {
7335 if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
7336 {
7337 return false;
7338 }
7339 break;
7340 }
7341
7342 case token_type::parse_error:
7343 {
7344 // using "uninitialized" to avoid "expected" message
7345 return sax->parse_error(m_lexer.get_position(),
7346 m_lexer.get_token_string(),
7347 parse_error::create(101, m_lexer.get_position(),
7348 exception_message(token_type::uninitialized, "value")));
7349 }
7350
7351 default: // the last token was unexpected
7352 {
7353 return sax->parse_error(m_lexer.get_position(),
7354 m_lexer.get_token_string(),
7355 parse_error::create(101, m_lexer.get_position(),
7356 exception_message(token_type::literal_or_value, "value")));
7357 }
7358 }
7359 }
7360 else
7361 {
7362 skip_to_state_evaluation = false;
7363 }
7364
7365 // we reached this line after we successfully parsed a value
7366 if (states.empty())
7367 {
7368 // empty stack: we reached the end of the hierarchy: done
7369 return true;
7370 }
7371
7372 if (states.back()) // array
7373 {
7374 // comma -> next value
7375 if (get_token() == token_type::value_separator)
7376 {
7377 // parse a new value
7378 get_token();
7379 continue;
7380 }
7381
7382 // closing ]
7383 if (JSON_LIKELY(last_token == token_type::end_array))
7384 {
7385 if (JSON_UNLIKELY(not sax->end_array()))
7386 {
7387 return false;
7388 }
7389
7390 // We are done with this array. Before we can parse a
7391 // new value, we need to evaluate the new state first.
7392 // By setting skip_to_state_evaluation to false, we
7393 // are effectively jumping to the beginning of this if.
7394 assert(not states.empty());
7395 states.pop_back();
7396 skip_to_state_evaluation = true;
7397 continue;
7398 }
7399
7400 return sax->parse_error(m_lexer.get_position(),
7401 m_lexer.get_token_string(),
7402 parse_error::create(101, m_lexer.get_position(),
7403 exception_message(token_type::end_array, "array")));
7404 }
7405 else // object
7406 {
7407 // comma -> next value
7408 if (get_token() == token_type::value_separator)
7409 {
7410 // parse key
7411 if (JSON_UNLIKELY(get_token() != token_type::value_string))
7412 {
7413 return sax->parse_error(m_lexer.get_position(),
7414 m_lexer.get_token_string(),
7415 parse_error::create(101, m_lexer.get_position(),
7416 exception_message(token_type::value_string, "object key")));
7417 }
7418
7419 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7420 {
7421 return false;
7422 }
7423
7424 // parse separator (:)
7425 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7426 {
7427 return sax->parse_error(m_lexer.get_position(),
7428 m_lexer.get_token_string(),
7429 parse_error::create(101, m_lexer.get_position(),
7430 exception_message(token_type::name_separator, "object separator")));
7431 }
7432
7433 // parse values
7434 get_token();
7435 continue;
7436 }
7437
7438 // closing }
7439 if (JSON_LIKELY(last_token == token_type::end_object))
7440 {
7441 if (JSON_UNLIKELY(not sax->end_object()))
7442 {
7443 return false;
7444 }
7445
7446 // We are done with this object. Before we can parse a
7447 // new value, we need to evaluate the new state first.
7448 // By setting skip_to_state_evaluation to false, we
7449 // are effectively jumping to the beginning of this if.
7450 assert(not states.empty());
7451 states.pop_back();
7452 skip_to_state_evaluation = true;
7453 continue;
7454 }
7455
7456 return sax->parse_error(m_lexer.get_position(),
7457 m_lexer.get_token_string(),
7458 parse_error::create(101, m_lexer.get_position(),
7459 exception_message(token_type::end_object, "object")));
7460 }
7461 }
7462 }
7463
7464 /// get next token from lexer
get_token()7465 token_type get_token()
7466 {
7467 return last_token = m_lexer.scan();
7468 }
7469
exception_message(const token_type expected,const std::string & context)7470 std::string exception_message(const token_type expected, const std::string& context)
7471 {
7472 std::string error_msg = "syntax error ";
7473
7474 if (not context.empty())
7475 {
7476 error_msg += "while parsing " + context + " ";
7477 }
7478
7479 error_msg += "- ";
7480
7481 if (last_token == token_type::parse_error)
7482 {
7483 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
7484 m_lexer.get_token_string() + "'";
7485 }
7486 else
7487 {
7488 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
7489 }
7490
7491 if (expected != token_type::uninitialized)
7492 {
7493 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
7494 }
7495
7496 return error_msg;
7497 }
7498
7499 private:
7500 /// callback function
7501 const parser_callback_t callback = nullptr;
7502 /// the type of the last read token
7503 token_type last_token = token_type::uninitialized;
7504 /// the lexer
7505 lexer_t m_lexer;
7506 /// whether to throw exceptions in case of errors
7507 const bool allow_exceptions = true;
7508 };
7509 } // namespace detail
7510 } // namespace nlohmann
7511
7512 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
7513
7514
7515 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
7516
7517
7518 #include <cstddef> // ptrdiff_t
7519 #include <limits> // numeric_limits
7520
7521 namespace nlohmann
7522 {
7523 namespace detail
7524 {
7525 /*
7526 @brief an iterator for primitive JSON types
7527
7528 This class models an iterator for primitive JSON types (boolean, number,
7529 string). It's only purpose is to allow the iterator/const_iterator classes
7530 to "iterate" over primitive values. Internally, the iterator is modeled by
7531 a `difference_type` variable. Value begin_value (`0`) models the begin,
7532 end_value (`1`) models past the end.
7533 */
7534 class primitive_iterator_t
7535 {
7536 private:
7537 using difference_type = std::ptrdiff_t;
7538 static constexpr difference_type begin_value = 0;
7539 static constexpr difference_type end_value = begin_value + 1;
7540
7541 /// iterator as signed integer type
7542 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
7543
7544 public:
get_value() const7545 constexpr difference_type get_value() const noexcept
7546 {
7547 return m_it;
7548 }
7549
7550 /// set iterator to a defined beginning
set_begin()7551 void set_begin() noexcept
7552 {
7553 m_it = begin_value;
7554 }
7555
7556 /// set iterator to a defined past the end
set_end()7557 void set_end() noexcept
7558 {
7559 m_it = end_value;
7560 }
7561
7562 /// return whether the iterator can be dereferenced
is_begin() const7563 constexpr bool is_begin() const noexcept
7564 {
7565 return m_it == begin_value;
7566 }
7567
7568 /// return whether the iterator is at end
is_end() const7569 constexpr bool is_end() const noexcept
7570 {
7571 return m_it == end_value;
7572 }
7573
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)7574 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7575 {
7576 return lhs.m_it == rhs.m_it;
7577 }
7578
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)7579 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7580 {
7581 return lhs.m_it < rhs.m_it;
7582 }
7583
operator +(difference_type n)7584 primitive_iterator_t operator+(difference_type n) noexcept
7585 {
7586 auto result = *this;
7587 result += n;
7588 return result;
7589 }
7590
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)7591 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7592 {
7593 return lhs.m_it - rhs.m_it;
7594 }
7595
operator ++()7596 primitive_iterator_t& operator++() noexcept
7597 {
7598 ++m_it;
7599 return *this;
7600 }
7601
operator ++(int)7602 primitive_iterator_t const operator++(int) noexcept
7603 {
7604 auto result = *this;
7605 ++m_it;
7606 return result;
7607 }
7608
operator --()7609 primitive_iterator_t& operator--() noexcept
7610 {
7611 --m_it;
7612 return *this;
7613 }
7614
operator --(int)7615 primitive_iterator_t const operator--(int) noexcept
7616 {
7617 auto result = *this;
7618 --m_it;
7619 return result;
7620 }
7621
operator +=(difference_type n)7622 primitive_iterator_t& operator+=(difference_type n) noexcept
7623 {
7624 m_it += n;
7625 return *this;
7626 }
7627
operator -=(difference_type n)7628 primitive_iterator_t& operator-=(difference_type n) noexcept
7629 {
7630 m_it -= n;
7631 return *this;
7632 }
7633 };
7634 } // namespace detail
7635 } // namespace nlohmann
7636
7637
7638 namespace nlohmann
7639 {
7640 namespace detail
7641 {
7642 /*!
7643 @brief an iterator value
7644
7645 @note This structure could easily be a union, but MSVC currently does not allow
7646 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
7647 */
7648 template<typename BasicJsonType> struct internal_iterator
7649 {
7650 /// iterator for JSON objects
7651 typename BasicJsonType::object_t::iterator object_iterator {};
7652 /// iterator for JSON arrays
7653 typename BasicJsonType::array_t::iterator array_iterator {};
7654 /// generic iterator for all other types
7655 primitive_iterator_t primitive_iterator {};
7656 };
7657 } // namespace detail
7658 } // namespace nlohmann
7659
7660 // #include <nlohmann/detail/iterators/iter_impl.hpp>
7661
7662
7663 #include <ciso646> // not
7664 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
7665 #include <type_traits> // conditional, is_const, remove_const
7666
7667 // #include <nlohmann/detail/exceptions.hpp>
7668
7669 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
7670
7671 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
7672
7673 // #include <nlohmann/detail/macro_scope.hpp>
7674
7675 // #include <nlohmann/detail/meta/cpp_future.hpp>
7676
7677 // #include <nlohmann/detail/meta/type_traits.hpp>
7678
7679 // #include <nlohmann/detail/value_t.hpp>
7680
7681
7682 namespace nlohmann
7683 {
7684 namespace detail
7685 {
7686 // forward declare, to be able to friend it later on
7687 template<typename IteratorType> class iteration_proxy;
7688 template<typename IteratorType> class iteration_proxy_value;
7689
7690 /*!
7691 @brief a template for a bidirectional iterator for the @ref basic_json class
7692 This class implements a both iterators (iterator and const_iterator) for the
7693 @ref basic_json class.
7694 @note An iterator is called *initialized* when a pointer to a JSON value has
7695 been set (e.g., by a constructor or a copy assignment). If the iterator is
7696 default-constructed, it is *uninitialized* and most methods are undefined.
7697 **The library uses assertions to detect calls on uninitialized iterators.**
7698 @requirement The class satisfies the following concept requirements:
7699 -
7700 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
7701 The iterator that can be moved can be moved in both directions (i.e.
7702 incremented and decremented).
7703 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
7704 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
7705 */
7706 template<typename BasicJsonType>
7707 class iter_impl
7708 {
7709 /// allow basic_json to access private members
7710 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
7711 friend BasicJsonType;
7712 friend iteration_proxy<iter_impl>;
7713 friend iteration_proxy_value<iter_impl>;
7714
7715 using object_t = typename BasicJsonType::object_t;
7716 using array_t = typename BasicJsonType::array_t;
7717 // make sure BasicJsonType is basic_json or const basic_json
7718 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
7719 "iter_impl only accepts (const) basic_json");
7720
7721 public:
7722
7723 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
7724 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
7725 /// A user-defined iterator should provide publicly accessible typedefs named
7726 /// iterator_category, value_type, difference_type, pointer, and reference.
7727 /// Note that value_type is required to be non-const, even for constant iterators.
7728 using iterator_category = std::bidirectional_iterator_tag;
7729
7730 /// the type of the values when the iterator is dereferenced
7731 using value_type = typename BasicJsonType::value_type;
7732 /// a type to represent differences between iterators
7733 using difference_type = typename BasicJsonType::difference_type;
7734 /// defines a pointer to the type iterated over (value_type)
7735 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
7736 typename BasicJsonType::const_pointer,
7737 typename BasicJsonType::pointer>::type;
7738 /// defines a reference to the type iterated over (value_type)
7739 using reference =
7740 typename std::conditional<std::is_const<BasicJsonType>::value,
7741 typename BasicJsonType::const_reference,
7742 typename BasicJsonType::reference>::type;
7743
7744 /// default constructor
7745 iter_impl() = default;
7746
7747 /*!
7748 @brief constructor for a given JSON instance
7749 @param[in] object pointer to a JSON object for this iterator
7750 @pre object != nullptr
7751 @post The iterator is initialized; i.e. `m_object != nullptr`.
7752 */
iter_impl(pointer object)7753 explicit iter_impl(pointer object) noexcept : m_object(object)
7754 {
7755 assert(m_object != nullptr);
7756
7757 switch (m_object->m_type)
7758 {
7759 case value_t::object:
7760 {
7761 m_it.object_iterator = typename object_t::iterator();
7762 break;
7763 }
7764
7765 case value_t::array:
7766 {
7767 m_it.array_iterator = typename array_t::iterator();
7768 break;
7769 }
7770
7771 default:
7772 {
7773 m_it.primitive_iterator = primitive_iterator_t();
7774 break;
7775 }
7776 }
7777 }
7778
7779 /*!
7780 @note The conventional copy constructor and copy assignment are implicitly
7781 defined. Combined with the following converting constructor and
7782 assignment, they support: (1) copy from iterator to iterator, (2)
7783 copy from const iterator to const iterator, and (3) conversion from
7784 iterator to const iterator. However conversion from const iterator
7785 to iterator is not defined.
7786 */
7787
7788 /*!
7789 @brief converting constructor
7790 @param[in] other non-const iterator to copy from
7791 @note It is not checked whether @a other is initialized.
7792 */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)7793 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7794 : m_object(other.m_object), m_it(other.m_it) {}
7795
7796 /*!
7797 @brief converting assignment
7798 @param[in,out] other non-const iterator to copy from
7799 @return const/non-const iterator
7800 @note It is not checked whether @a other is initialized.
7801 */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)7802 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7803 {
7804 m_object = other.m_object;
7805 m_it = other.m_it;
7806 return *this;
7807 }
7808
7809 private:
7810 /*!
7811 @brief set the iterator to the first value
7812 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7813 */
set_begin()7814 void set_begin() noexcept
7815 {
7816 assert(m_object != nullptr);
7817
7818 switch (m_object->m_type)
7819 {
7820 case value_t::object:
7821 {
7822 m_it.object_iterator = m_object->m_value.object->begin();
7823 break;
7824 }
7825
7826 case value_t::array:
7827 {
7828 m_it.array_iterator = m_object->m_value.array->begin();
7829 break;
7830 }
7831
7832 case value_t::null:
7833 {
7834 // set to end so begin()==end() is true: null is empty
7835 m_it.primitive_iterator.set_end();
7836 break;
7837 }
7838
7839 default:
7840 {
7841 m_it.primitive_iterator.set_begin();
7842 break;
7843 }
7844 }
7845 }
7846
7847 /*!
7848 @brief set the iterator past the last value
7849 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7850 */
set_end()7851 void set_end() noexcept
7852 {
7853 assert(m_object != nullptr);
7854
7855 switch (m_object->m_type)
7856 {
7857 case value_t::object:
7858 {
7859 m_it.object_iterator = m_object->m_value.object->end();
7860 break;
7861 }
7862
7863 case value_t::array:
7864 {
7865 m_it.array_iterator = m_object->m_value.array->end();
7866 break;
7867 }
7868
7869 default:
7870 {
7871 m_it.primitive_iterator.set_end();
7872 break;
7873 }
7874 }
7875 }
7876
7877 public:
7878 /*!
7879 @brief return a reference to the value pointed to by the iterator
7880 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7881 */
operator *() const7882 reference operator*() const
7883 {
7884 assert(m_object != nullptr);
7885
7886 switch (m_object->m_type)
7887 {
7888 case value_t::object:
7889 {
7890 assert(m_it.object_iterator != m_object->m_value.object->end());
7891 return m_it.object_iterator->second;
7892 }
7893
7894 case value_t::array:
7895 {
7896 assert(m_it.array_iterator != m_object->m_value.array->end());
7897 return *m_it.array_iterator;
7898 }
7899
7900 case value_t::null:
7901 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7902
7903 default:
7904 {
7905 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7906 {
7907 return *m_object;
7908 }
7909
7910 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7911 }
7912 }
7913 }
7914
7915 /*!
7916 @brief dereference the iterator
7917 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7918 */
operator ->() const7919 pointer operator->() const
7920 {
7921 assert(m_object != nullptr);
7922
7923 switch (m_object->m_type)
7924 {
7925 case value_t::object:
7926 {
7927 assert(m_it.object_iterator != m_object->m_value.object->end());
7928 return &(m_it.object_iterator->second);
7929 }
7930
7931 case value_t::array:
7932 {
7933 assert(m_it.array_iterator != m_object->m_value.array->end());
7934 return &*m_it.array_iterator;
7935 }
7936
7937 default:
7938 {
7939 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7940 {
7941 return m_object;
7942 }
7943
7944 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7945 }
7946 }
7947 }
7948
7949 /*!
7950 @brief post-increment (it++)
7951 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7952 */
operator ++(int)7953 iter_impl const operator++(int)
7954 {
7955 auto result = *this;
7956 ++(*this);
7957 return result;
7958 }
7959
7960 /*!
7961 @brief pre-increment (++it)
7962 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7963 */
operator ++()7964 iter_impl& operator++()
7965 {
7966 assert(m_object != nullptr);
7967
7968 switch (m_object->m_type)
7969 {
7970 case value_t::object:
7971 {
7972 std::advance(m_it.object_iterator, 1);
7973 break;
7974 }
7975
7976 case value_t::array:
7977 {
7978 std::advance(m_it.array_iterator, 1);
7979 break;
7980 }
7981
7982 default:
7983 {
7984 ++m_it.primitive_iterator;
7985 break;
7986 }
7987 }
7988
7989 return *this;
7990 }
7991
7992 /*!
7993 @brief post-decrement (it--)
7994 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7995 */
operator --(int)7996 iter_impl const operator--(int)
7997 {
7998 auto result = *this;
7999 --(*this);
8000 return result;
8001 }
8002
8003 /*!
8004 @brief pre-decrement (--it)
8005 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8006 */
operator --()8007 iter_impl& operator--()
8008 {
8009 assert(m_object != nullptr);
8010
8011 switch (m_object->m_type)
8012 {
8013 case value_t::object:
8014 {
8015 std::advance(m_it.object_iterator, -1);
8016 break;
8017 }
8018
8019 case value_t::array:
8020 {
8021 std::advance(m_it.array_iterator, -1);
8022 break;
8023 }
8024
8025 default:
8026 {
8027 --m_it.primitive_iterator;
8028 break;
8029 }
8030 }
8031
8032 return *this;
8033 }
8034
8035 /*!
8036 @brief comparison: equal
8037 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8038 */
operator ==(const iter_impl & other) const8039 bool operator==(const iter_impl& other) const
8040 {
8041 // if objects are not the same, the comparison is undefined
8042 if (JSON_UNLIKELY(m_object != other.m_object))
8043 {
8044 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8045 }
8046
8047 assert(m_object != nullptr);
8048
8049 switch (m_object->m_type)
8050 {
8051 case value_t::object:
8052 return (m_it.object_iterator == other.m_it.object_iterator);
8053
8054 case value_t::array:
8055 return (m_it.array_iterator == other.m_it.array_iterator);
8056
8057 default:
8058 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
8059 }
8060 }
8061
8062 /*!
8063 @brief comparison: not equal
8064 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8065 */
operator !=(const iter_impl & other) const8066 bool operator!=(const iter_impl& other) const
8067 {
8068 return not operator==(other);
8069 }
8070
8071 /*!
8072 @brief comparison: smaller
8073 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8074 */
operator <(const iter_impl & other) const8075 bool operator<(const iter_impl& other) const
8076 {
8077 // if objects are not the same, the comparison is undefined
8078 if (JSON_UNLIKELY(m_object != other.m_object))
8079 {
8080 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8081 }
8082
8083 assert(m_object != nullptr);
8084
8085 switch (m_object->m_type)
8086 {
8087 case value_t::object:
8088 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
8089
8090 case value_t::array:
8091 return (m_it.array_iterator < other.m_it.array_iterator);
8092
8093 default:
8094 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
8095 }
8096 }
8097
8098 /*!
8099 @brief comparison: less than or equal
8100 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8101 */
operator <=(const iter_impl & other) const8102 bool operator<=(const iter_impl& other) const
8103 {
8104 return not other.operator < (*this);
8105 }
8106
8107 /*!
8108 @brief comparison: greater than
8109 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8110 */
operator >(const iter_impl & other) const8111 bool operator>(const iter_impl& other) const
8112 {
8113 return not operator<=(other);
8114 }
8115
8116 /*!
8117 @brief comparison: greater than or equal
8118 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8119 */
operator >=(const iter_impl & other) const8120 bool operator>=(const iter_impl& other) const
8121 {
8122 return not operator<(other);
8123 }
8124
8125 /*!
8126 @brief add to iterator
8127 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8128 */
operator +=(difference_type i)8129 iter_impl& operator+=(difference_type i)
8130 {
8131 assert(m_object != nullptr);
8132
8133 switch (m_object->m_type)
8134 {
8135 case value_t::object:
8136 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8137
8138 case value_t::array:
8139 {
8140 std::advance(m_it.array_iterator, i);
8141 break;
8142 }
8143
8144 default:
8145 {
8146 m_it.primitive_iterator += i;
8147 break;
8148 }
8149 }
8150
8151 return *this;
8152 }
8153
8154 /*!
8155 @brief subtract from iterator
8156 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8157 */
operator -=(difference_type i)8158 iter_impl& operator-=(difference_type i)
8159 {
8160 return operator+=(-i);
8161 }
8162
8163 /*!
8164 @brief add to iterator
8165 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8166 */
operator +(difference_type i) const8167 iter_impl operator+(difference_type i) const
8168 {
8169 auto result = *this;
8170 result += i;
8171 return result;
8172 }
8173
8174 /*!
8175 @brief addition of distance and iterator
8176 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8177 */
operator +(difference_type i,const iter_impl & it)8178 friend iter_impl operator+(difference_type i, const iter_impl& it)
8179 {
8180 auto result = it;
8181 result += i;
8182 return result;
8183 }
8184
8185 /*!
8186 @brief subtract from iterator
8187 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8188 */
operator -(difference_type i) const8189 iter_impl operator-(difference_type i) const
8190 {
8191 auto result = *this;
8192 result -= i;
8193 return result;
8194 }
8195
8196 /*!
8197 @brief return difference
8198 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8199 */
operator -(const iter_impl & other) const8200 difference_type operator-(const iter_impl& other) const
8201 {
8202 assert(m_object != nullptr);
8203
8204 switch (m_object->m_type)
8205 {
8206 case value_t::object:
8207 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8208
8209 case value_t::array:
8210 return m_it.array_iterator - other.m_it.array_iterator;
8211
8212 default:
8213 return m_it.primitive_iterator - other.m_it.primitive_iterator;
8214 }
8215 }
8216
8217 /*!
8218 @brief access to successor
8219 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8220 */
operator [](difference_type n) const8221 reference operator[](difference_type n) const
8222 {
8223 assert(m_object != nullptr);
8224
8225 switch (m_object->m_type)
8226 {
8227 case value_t::object:
8228 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
8229
8230 case value_t::array:
8231 return *std::next(m_it.array_iterator, n);
8232
8233 case value_t::null:
8234 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8235
8236 default:
8237 {
8238 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
8239 {
8240 return *m_object;
8241 }
8242
8243 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8244 }
8245 }
8246 }
8247
8248 /*!
8249 @brief return the key of an object iterator
8250 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8251 */
key() const8252 const typename object_t::key_type& key() const
8253 {
8254 assert(m_object != nullptr);
8255
8256 if (JSON_LIKELY(m_object->is_object()))
8257 {
8258 return m_it.object_iterator->first;
8259 }
8260
8261 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
8262 }
8263
8264 /*!
8265 @brief return the value of an iterator
8266 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8267 */
value() const8268 reference value() const
8269 {
8270 return operator*();
8271 }
8272
8273 private:
8274 /// associated JSON instance
8275 pointer m_object = nullptr;
8276 /// the actual iterator of the associated instance
8277 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
8278 };
8279 } // namespace detail
8280 } // namespace nlohmann
8281
8282 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
8283
8284 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
8285
8286
8287 #include <cstddef> // ptrdiff_t
8288 #include <iterator> // reverse_iterator
8289 #include <utility> // declval
8290
8291 namespace nlohmann
8292 {
8293 namespace detail
8294 {
8295 //////////////////////
8296 // reverse_iterator //
8297 //////////////////////
8298
8299 /*!
8300 @brief a template for a reverse iterator class
8301
8302 @tparam Base the base iterator type to reverse. Valid types are @ref
8303 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
8304 create @ref const_reverse_iterator).
8305
8306 @requirement The class satisfies the following concept requirements:
8307 -
8308 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
8309 The iterator that can be moved can be moved in both directions (i.e.
8310 incremented and decremented).
8311 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
8312 It is possible to write to the pointed-to element (only if @a Base is
8313 @ref iterator).
8314
8315 @since version 1.0.0
8316 */
8317 template<typename Base>
8318 class json_reverse_iterator : public std::reverse_iterator<Base>
8319 {
8320 public:
8321 using difference_type = std::ptrdiff_t;
8322 /// shortcut to the reverse iterator adapter
8323 using base_iterator = std::reverse_iterator<Base>;
8324 /// the reference type for the pointed-to element
8325 using reference = typename Base::reference;
8326
8327 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)8328 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
8329 : base_iterator(it) {}
8330
8331 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)8332 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
8333
8334 /// post-increment (it++)
operator ++(int)8335 json_reverse_iterator const operator++(int)
8336 {
8337 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
8338 }
8339
8340 /// pre-increment (++it)
operator ++()8341 json_reverse_iterator& operator++()
8342 {
8343 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
8344 }
8345
8346 /// post-decrement (it--)
operator --(int)8347 json_reverse_iterator const operator--(int)
8348 {
8349 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
8350 }
8351
8352 /// pre-decrement (--it)
operator --()8353 json_reverse_iterator& operator--()
8354 {
8355 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
8356 }
8357
8358 /// add to iterator
operator +=(difference_type i)8359 json_reverse_iterator& operator+=(difference_type i)
8360 {
8361 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
8362 }
8363
8364 /// add to iterator
operator +(difference_type i) const8365 json_reverse_iterator operator+(difference_type i) const
8366 {
8367 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
8368 }
8369
8370 /// subtract from iterator
operator -(difference_type i) const8371 json_reverse_iterator operator-(difference_type i) const
8372 {
8373 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
8374 }
8375
8376 /// return difference
operator -(const json_reverse_iterator & other) const8377 difference_type operator-(const json_reverse_iterator& other) const
8378 {
8379 return base_iterator(*this) - base_iterator(other);
8380 }
8381
8382 /// access to successor
operator [](difference_type n) const8383 reference operator[](difference_type n) const
8384 {
8385 return *(this->operator+(n));
8386 }
8387
8388 /// return the key of an object iterator
key() const8389 auto key() const -> decltype(std::declval<Base>().key())
8390 {
8391 auto it = --this->base();
8392 return it.key();
8393 }
8394
8395 /// return the value of an iterator
value() const8396 reference value() const
8397 {
8398 auto it = --this->base();
8399 return it.operator * ();
8400 }
8401 };
8402 } // namespace detail
8403 } // namespace nlohmann
8404
8405 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
8406
8407 // #include <nlohmann/detail/json_pointer.hpp>
8408
8409
8410 #include <algorithm> // all_of
8411 #include <cassert> // assert
8412 #include <numeric> // accumulate
8413 #include <string> // string
8414 #include <utility> // move
8415 #include <vector> // vector
8416
8417 // #include <nlohmann/detail/exceptions.hpp>
8418
8419 // #include <nlohmann/detail/macro_scope.hpp>
8420
8421 // #include <nlohmann/detail/value_t.hpp>
8422
8423
8424 namespace nlohmann
8425 {
8426 template<typename BasicJsonType>
8427 class json_pointer
8428 {
8429 // allow basic_json to access private members
8430 NLOHMANN_BASIC_JSON_TPL_DECLARATION
8431 friend class basic_json;
8432
8433 public:
8434 /*!
8435 @brief create JSON pointer
8436
8437 Create a JSON pointer according to the syntax described in
8438 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
8439
8440 @param[in] s string representing the JSON pointer; if omitted, the empty
8441 string is assumed which references the whole JSON value
8442
8443 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
8444 not begin with a slash (`/`); see example below
8445
8446 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
8447 not followed by `0` (representing `~`) or `1` (representing `/`); see
8448 example below
8449
8450 @liveexample{The example shows the construction several valid JSON pointers
8451 as well as the exceptional behavior.,json_pointer}
8452
8453 @since version 2.0.0
8454 */
json_pointer(const std::string & s="")8455 explicit json_pointer(const std::string& s = "")
8456 : reference_tokens(split(s))
8457 {}
8458
8459 /*!
8460 @brief return a string representation of the JSON pointer
8461
8462 @invariant For each JSON pointer `ptr`, it holds:
8463 @code {.cpp}
8464 ptr == json_pointer(ptr.to_string());
8465 @endcode
8466
8467 @return a string representation of the JSON pointer
8468
8469 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
8470
8471 @since version 2.0.0
8472 */
to_string() const8473 std::string to_string() const
8474 {
8475 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8476 std::string{},
8477 [](const std::string & a, const std::string & b)
8478 {
8479 return a + "/" + escape(b);
8480 });
8481 }
8482
8483 /// @copydoc to_string()
operator std::string() const8484 operator std::string() const
8485 {
8486 return to_string();
8487 }
8488
8489 /*!
8490 @brief append another JSON pointer at the end of this JSON pointer
8491
8492 @param[in] ptr JSON pointer to append
8493 @return JSON pointer with @a ptr appended
8494
8495 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8496
8497 @complexity Linear in the length of @a ptr.
8498
8499 @sa @ref operator/=(std::string) to append a reference token
8500 @sa @ref operator/=(std::size_t) to append an array index
8501 @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
8502
8503 @since version 3.6.0
8504 */
operator /=(const json_pointer & ptr)8505 json_pointer& operator/=(const json_pointer& ptr)
8506 {
8507 reference_tokens.insert(reference_tokens.end(),
8508 ptr.reference_tokens.begin(),
8509 ptr.reference_tokens.end());
8510 return *this;
8511 }
8512
8513 /*!
8514 @brief append an unescaped reference token at the end of this JSON pointer
8515
8516 @param[in] token reference token to append
8517 @return JSON pointer with @a token appended without escaping @a token
8518
8519 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8520
8521 @complexity Amortized constant.
8522
8523 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8524 @sa @ref operator/=(std::size_t) to append an array index
8525 @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
8526
8527 @since version 3.6.0
8528 */
operator /=(std::string token)8529 json_pointer& operator/=(std::string token)
8530 {
8531 push_back(std::move(token));
8532 return *this;
8533 }
8534
8535 /*!
8536 @brief append an array index at the end of this JSON pointer
8537
8538 @param[in] array_index array index ot append
8539 @return JSON pointer with @a array_index appended
8540
8541 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8542
8543 @complexity Amortized constant.
8544
8545 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8546 @sa @ref operator/=(std::string) to append a reference token
8547 @sa @ref operator/(const json_pointer&, std::string) for a binary operator
8548
8549 @since version 3.6.0
8550 */
operator /=(std::size_t array_index)8551 json_pointer& operator/=(std::size_t array_index)
8552 {
8553 return *this /= std::to_string(array_index);
8554 }
8555
8556 /*!
8557 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
8558
8559 @param[in] lhs JSON pointer
8560 @param[in] rhs JSON pointer
8561 @return a new JSON pointer with @a rhs appended to @a lhs
8562
8563 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8564
8565 @complexity Linear in the length of @a lhs and @a rhs.
8566
8567 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8568
8569 @since version 3.6.0
8570 */
operator /(const json_pointer & lhs,const json_pointer & rhs)8571 friend json_pointer operator/(const json_pointer& lhs,
8572 const json_pointer& rhs)
8573 {
8574 return json_pointer(lhs) /= rhs;
8575 }
8576
8577 /*!
8578 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
8579
8580 @param[in] ptr JSON pointer
8581 @param[in] token reference token
8582 @return a new JSON pointer with unescaped @a token appended to @a ptr
8583
8584 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8585
8586 @complexity Linear in the length of @a ptr.
8587
8588 @sa @ref operator/=(std::string) to append a reference token
8589
8590 @since version 3.6.0
8591 */
operator /(const json_pointer & ptr,std::string token)8592 friend json_pointer operator/(const json_pointer& ptr, std::string token)
8593 {
8594 return json_pointer(ptr) /= std::move(token);
8595 }
8596
8597 /*!
8598 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
8599
8600 @param[in] ptr JSON pointer
8601 @param[in] array_index array index
8602 @return a new JSON pointer with @a array_index appended to @a ptr
8603
8604 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8605
8606 @complexity Linear in the length of @a ptr.
8607
8608 @sa @ref operator/=(std::size_t) to append an array index
8609
8610 @since version 3.6.0
8611 */
operator /(const json_pointer & ptr,std::size_t array_index)8612 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
8613 {
8614 return json_pointer(ptr) /= array_index;
8615 }
8616
8617 /*!
8618 @brief returns the parent of this JSON pointer
8619
8620 @return parent of this JSON pointer; in case this JSON pointer is the root,
8621 the root itself is returned
8622
8623 @complexity Linear in the length of the JSON pointer.
8624
8625 @liveexample{The example shows the result of `parent_pointer` for different
8626 JSON Pointers.,json_pointer__parent_pointer}
8627
8628 @since version 3.6.0
8629 */
parent_pointer() const8630 json_pointer parent_pointer() const
8631 {
8632 if (empty())
8633 {
8634 return *this;
8635 }
8636
8637 json_pointer res = *this;
8638 res.pop_back();
8639 return res;
8640 }
8641
8642 /*!
8643 @brief remove last reference token
8644
8645 @pre not `empty()`
8646
8647 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
8648
8649 @complexity Constant.
8650
8651 @throw out_of_range.405 if JSON pointer has no parent
8652
8653 @since version 3.6.0
8654 */
pop_back()8655 void pop_back()
8656 {
8657 if (JSON_UNLIKELY(empty()))
8658 {
8659 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8660 }
8661
8662 reference_tokens.pop_back();
8663 }
8664
8665 /*!
8666 @brief return last reference token
8667
8668 @pre not `empty()`
8669 @return last reference token
8670
8671 @liveexample{The example shows the usage of `back`.,json_pointer__back}
8672
8673 @complexity Constant.
8674
8675 @throw out_of_range.405 if JSON pointer has no parent
8676
8677 @since version 3.6.0
8678 */
back()8679 const std::string& back()
8680 {
8681 if (JSON_UNLIKELY(empty()))
8682 {
8683 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8684 }
8685
8686 return reference_tokens.back();
8687 }
8688
8689 /*!
8690 @brief append an unescaped token at the end of the reference pointer
8691
8692 @param[in] token token to add
8693
8694 @complexity Amortized constant.
8695
8696 @liveexample{The example shows the result of `push_back` for different
8697 JSON Pointers.,json_pointer__push_back}
8698
8699 @since version 3.6.0
8700 */
push_back(const std::string & token)8701 void push_back(const std::string& token)
8702 {
8703 reference_tokens.push_back(token);
8704 }
8705
8706 /// @copydoc push_back(const std::string&)
push_back(std::string && token)8707 void push_back(std::string&& token)
8708 {
8709 reference_tokens.push_back(std::move(token));
8710 }
8711
8712 /*!
8713 @brief return whether pointer points to the root document
8714
8715 @return true iff the JSON pointer points to the root document
8716
8717 @complexity Constant.
8718
8719 @exceptionsafety No-throw guarantee: this function never throws exceptions.
8720
8721 @liveexample{The example shows the result of `empty` for different JSON
8722 Pointers.,json_pointer__empty}
8723
8724 @since version 3.6.0
8725 */
empty() const8726 bool empty() const noexcept
8727 {
8728 return reference_tokens.empty();
8729 }
8730
8731 private:
8732 /*!
8733 @param[in] s reference token to be converted into an array index
8734
8735 @return integer representation of @a s
8736
8737 @throw out_of_range.404 if string @a s could not be converted to an integer
8738 */
array_index(const std::string & s)8739 static int array_index(const std::string& s)
8740 {
8741 std::size_t processed_chars = 0;
8742 const int res = std::stoi(s, &processed_chars);
8743
8744 // check if the string was completely read
8745 if (JSON_UNLIKELY(processed_chars != s.size()))
8746 {
8747 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
8748 }
8749
8750 return res;
8751 }
8752
top() const8753 json_pointer top() const
8754 {
8755 if (JSON_UNLIKELY(empty()))
8756 {
8757 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8758 }
8759
8760 json_pointer result = *this;
8761 result.reference_tokens = {reference_tokens[0]};
8762 return result;
8763 }
8764
8765 /*!
8766 @brief create and return a reference to the pointed to value
8767
8768 @complexity Linear in the number of reference tokens.
8769
8770 @throw parse_error.109 if array index is not a number
8771 @throw type_error.313 if value cannot be unflattened
8772 */
get_and_create(BasicJsonType & j) const8773 BasicJsonType& get_and_create(BasicJsonType& j) const
8774 {
8775 using size_type = typename BasicJsonType::size_type;
8776 auto result = &j;
8777
8778 // in case no reference tokens exist, return a reference to the JSON value
8779 // j which will be overwritten by a primitive value
8780 for (const auto& reference_token : reference_tokens)
8781 {
8782 switch (result->m_type)
8783 {
8784 case detail::value_t::null:
8785 {
8786 if (reference_token == "0")
8787 {
8788 // start a new array if reference token is 0
8789 result = &result->operator[](0);
8790 }
8791 else
8792 {
8793 // start a new object otherwise
8794 result = &result->operator[](reference_token);
8795 }
8796 break;
8797 }
8798
8799 case detail::value_t::object:
8800 {
8801 // create an entry in the object
8802 result = &result->operator[](reference_token);
8803 break;
8804 }
8805
8806 case detail::value_t::array:
8807 {
8808 // create an entry in the array
8809 JSON_TRY
8810 {
8811 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
8812 }
8813 JSON_CATCH(std::invalid_argument&)
8814 {
8815 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8816 }
8817 break;
8818 }
8819
8820 /*
8821 The following code is only reached if there exists a reference
8822 token _and_ the current value is primitive. In this case, we have
8823 an error situation, because primitive values may only occur as
8824 single value; that is, with an empty list of reference tokens.
8825 */
8826 default:
8827 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
8828 }
8829 }
8830
8831 return *result;
8832 }
8833
8834 /*!
8835 @brief return a reference to the pointed to value
8836
8837 @note This version does not throw if a value is not present, but tries to
8838 create nested values instead. For instance, calling this function
8839 with pointer `"/this/that"` on a null value is equivalent to calling
8840 `operator[]("this").operator[]("that")` on that value, effectively
8841 changing the null value to an object.
8842
8843 @param[in] ptr a JSON value
8844
8845 @return reference to the JSON value pointed to by the JSON pointer
8846
8847 @complexity Linear in the length of the JSON pointer.
8848
8849 @throw parse_error.106 if an array index begins with '0'
8850 @throw parse_error.109 if an array index was not a number
8851 @throw out_of_range.404 if the JSON pointer can not be resolved
8852 */
get_unchecked(BasicJsonType * ptr) const8853 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
8854 {
8855 using size_type = typename BasicJsonType::size_type;
8856 for (const auto& reference_token : reference_tokens)
8857 {
8858 // convert null values to arrays or objects before continuing
8859 if (ptr->m_type == detail::value_t::null)
8860 {
8861 // check if reference token is a number
8862 const bool nums =
8863 std::all_of(reference_token.begin(), reference_token.end(),
8864 [](const char x)
8865 {
8866 return x >= '0' and x <= '9';
8867 });
8868
8869 // change value to array for numbers or "-" or to object otherwise
8870 *ptr = (nums or reference_token == "-")
8871 ? detail::value_t::array
8872 : detail::value_t::object;
8873 }
8874
8875 switch (ptr->m_type)
8876 {
8877 case detail::value_t::object:
8878 {
8879 // use unchecked object access
8880 ptr = &ptr->operator[](reference_token);
8881 break;
8882 }
8883
8884 case detail::value_t::array:
8885 {
8886 // error condition (cf. RFC 6901, Sect. 4)
8887 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
8888 {
8889 JSON_THROW(detail::parse_error::create(106, 0,
8890 "array index '" + reference_token +
8891 "' must not begin with '0'"));
8892 }
8893
8894 if (reference_token == "-")
8895 {
8896 // explicitly treat "-" as index beyond the end
8897 ptr = &ptr->operator[](ptr->m_value.array->size());
8898 }
8899 else
8900 {
8901 // convert array index to number; unchecked access
8902 JSON_TRY
8903 {
8904 ptr = &ptr->operator[](
8905 static_cast<size_type>(array_index(reference_token)));
8906 }
8907 JSON_CATCH(std::invalid_argument&)
8908 {
8909 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8910 }
8911 }
8912 break;
8913 }
8914
8915 default:
8916 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8917 }
8918 }
8919
8920 return *ptr;
8921 }
8922
8923 /*!
8924 @throw parse_error.106 if an array index begins with '0'
8925 @throw parse_error.109 if an array index was not a number
8926 @throw out_of_range.402 if the array index '-' is used
8927 @throw out_of_range.404 if the JSON pointer can not be resolved
8928 */
get_checked(BasicJsonType * ptr) const8929 BasicJsonType& get_checked(BasicJsonType* ptr) const
8930 {
8931 using size_type = typename BasicJsonType::size_type;
8932 for (const auto& reference_token : reference_tokens)
8933 {
8934 switch (ptr->m_type)
8935 {
8936 case detail::value_t::object:
8937 {
8938 // note: at performs range check
8939 ptr = &ptr->at(reference_token);
8940 break;
8941 }
8942
8943 case detail::value_t::array:
8944 {
8945 if (JSON_UNLIKELY(reference_token == "-"))
8946 {
8947 // "-" always fails the range check
8948 JSON_THROW(detail::out_of_range::create(402,
8949 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8950 ") is out of range"));
8951 }
8952
8953 // error condition (cf. RFC 6901, Sect. 4)
8954 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
8955 {
8956 JSON_THROW(detail::parse_error::create(106, 0,
8957 "array index '" + reference_token +
8958 "' must not begin with '0'"));
8959 }
8960
8961 // note: at performs range check
8962 JSON_TRY
8963 {
8964 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
8965 }
8966 JSON_CATCH(std::invalid_argument&)
8967 {
8968 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8969 }
8970 break;
8971 }
8972
8973 default:
8974 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8975 }
8976 }
8977
8978 return *ptr;
8979 }
8980
8981 /*!
8982 @brief return a const reference to the pointed to value
8983
8984 @param[in] ptr a JSON value
8985
8986 @return const reference to the JSON value pointed to by the JSON
8987 pointer
8988
8989 @throw parse_error.106 if an array index begins with '0'
8990 @throw parse_error.109 if an array index was not a number
8991 @throw out_of_range.402 if the array index '-' is used
8992 @throw out_of_range.404 if the JSON pointer can not be resolved
8993 */
get_unchecked(const BasicJsonType * ptr) const8994 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
8995 {
8996 using size_type = typename BasicJsonType::size_type;
8997 for (const auto& reference_token : reference_tokens)
8998 {
8999 switch (ptr->m_type)
9000 {
9001 case detail::value_t::object:
9002 {
9003 // use unchecked object access
9004 ptr = &ptr->operator[](reference_token);
9005 break;
9006 }
9007
9008 case detail::value_t::array:
9009 {
9010 if (JSON_UNLIKELY(reference_token == "-"))
9011 {
9012 // "-" cannot be used for const access
9013 JSON_THROW(detail::out_of_range::create(402,
9014 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9015 ") is out of range"));
9016 }
9017
9018 // error condition (cf. RFC 6901, Sect. 4)
9019 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9020 {
9021 JSON_THROW(detail::parse_error::create(106, 0,
9022 "array index '" + reference_token +
9023 "' must not begin with '0'"));
9024 }
9025
9026 // use unchecked array access
9027 JSON_TRY
9028 {
9029 ptr = &ptr->operator[](
9030 static_cast<size_type>(array_index(reference_token)));
9031 }
9032 JSON_CATCH(std::invalid_argument&)
9033 {
9034 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9035 }
9036 break;
9037 }
9038
9039 default:
9040 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9041 }
9042 }
9043
9044 return *ptr;
9045 }
9046
9047 /*!
9048 @throw parse_error.106 if an array index begins with '0'
9049 @throw parse_error.109 if an array index was not a number
9050 @throw out_of_range.402 if the array index '-' is used
9051 @throw out_of_range.404 if the JSON pointer can not be resolved
9052 */
get_checked(const BasicJsonType * ptr) const9053 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
9054 {
9055 using size_type = typename BasicJsonType::size_type;
9056 for (const auto& reference_token : reference_tokens)
9057 {
9058 switch (ptr->m_type)
9059 {
9060 case detail::value_t::object:
9061 {
9062 // note: at performs range check
9063 ptr = &ptr->at(reference_token);
9064 break;
9065 }
9066
9067 case detail::value_t::array:
9068 {
9069 if (JSON_UNLIKELY(reference_token == "-"))
9070 {
9071 // "-" always fails the range check
9072 JSON_THROW(detail::out_of_range::create(402,
9073 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9074 ") is out of range"));
9075 }
9076
9077 // error condition (cf. RFC 6901, Sect. 4)
9078 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9079 {
9080 JSON_THROW(detail::parse_error::create(106, 0,
9081 "array index '" + reference_token +
9082 "' must not begin with '0'"));
9083 }
9084
9085 // note: at performs range check
9086 JSON_TRY
9087 {
9088 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9089 }
9090 JSON_CATCH(std::invalid_argument&)
9091 {
9092 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9093 }
9094 break;
9095 }
9096
9097 default:
9098 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9099 }
9100 }
9101
9102 return *ptr;
9103 }
9104
9105 /*!
9106 @brief split the string input to reference tokens
9107
9108 @note This function is only called by the json_pointer constructor.
9109 All exceptions below are documented there.
9110
9111 @throw parse_error.107 if the pointer is not empty or begins with '/'
9112 @throw parse_error.108 if character '~' is not followed by '0' or '1'
9113 */
split(const std::string & reference_string)9114 static std::vector<std::string> split(const std::string& reference_string)
9115 {
9116 std::vector<std::string> result;
9117
9118 // special case: empty reference string -> no reference tokens
9119 if (reference_string.empty())
9120 {
9121 return result;
9122 }
9123
9124 // check if nonempty reference string begins with slash
9125 if (JSON_UNLIKELY(reference_string[0] != '/'))
9126 {
9127 JSON_THROW(detail::parse_error::create(107, 1,
9128 "JSON pointer must be empty or begin with '/' - was: '" +
9129 reference_string + "'"));
9130 }
9131
9132 // extract the reference tokens:
9133 // - slash: position of the last read slash (or end of string)
9134 // - start: position after the previous slash
9135 for (
9136 // search for the first slash after the first character
9137 std::size_t slash = reference_string.find_first_of('/', 1),
9138 // set the beginning of the first reference token
9139 start = 1;
9140 // we can stop if start == 0 (if slash == std::string::npos)
9141 start != 0;
9142 // set the beginning of the next reference token
9143 // (will eventually be 0 if slash == std::string::npos)
9144 start = (slash == std::string::npos) ? 0 : slash + 1,
9145 // find next slash
9146 slash = reference_string.find_first_of('/', start))
9147 {
9148 // use the text between the beginning of the reference token
9149 // (start) and the last slash (slash).
9150 auto reference_token = reference_string.substr(start, slash - start);
9151
9152 // check reference tokens are properly escaped
9153 for (std::size_t pos = reference_token.find_first_of('~');
9154 pos != std::string::npos;
9155 pos = reference_token.find_first_of('~', pos + 1))
9156 {
9157 assert(reference_token[pos] == '~');
9158
9159 // ~ must be followed by 0 or 1
9160 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9161 (reference_token[pos + 1] != '0' and
9162 reference_token[pos + 1] != '1')))
9163 {
9164 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
9165 }
9166 }
9167
9168 // finally, store the reference token
9169 unescape(reference_token);
9170 result.push_back(reference_token);
9171 }
9172
9173 return result;
9174 }
9175
9176 /*!
9177 @brief replace all occurrences of a substring by another string
9178
9179 @param[in,out] s the string to manipulate; changed so that all
9180 occurrences of @a f are replaced with @a t
9181 @param[in] f the substring to replace with @a t
9182 @param[in] t the string to replace @a f
9183
9184 @pre The search string @a f must not be empty. **This precondition is
9185 enforced with an assertion.**
9186
9187 @since version 2.0.0
9188 */
replace_substring(std::string & s,const std::string & f,const std::string & t)9189 static void replace_substring(std::string& s, const std::string& f,
9190 const std::string& t)
9191 {
9192 assert(not f.empty());
9193 for (auto pos = s.find(f); // find first occurrence of f
9194 pos != std::string::npos; // make sure f was found
9195 s.replace(pos, f.size(), t), // replace with t, and
9196 pos = s.find(f, pos + t.size())) // find next occurrence of f
9197 {}
9198 }
9199
9200 /// escape "~" to "~0" and "/" to "~1"
escape(std::string s)9201 static std::string escape(std::string s)
9202 {
9203 replace_substring(s, "~", "~0");
9204 replace_substring(s, "/", "~1");
9205 return s;
9206 }
9207
9208 /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)9209 static void unescape(std::string& s)
9210 {
9211 replace_substring(s, "~1", "/");
9212 replace_substring(s, "~0", "~");
9213 }
9214
9215 /*!
9216 @param[in] reference_string the reference string to the current value
9217 @param[in] value the value to consider
9218 @param[in,out] result the result object to insert values to
9219
9220 @note Empty objects or arrays are flattened to `null`.
9221 */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)9222 static void flatten(const std::string& reference_string,
9223 const BasicJsonType& value,
9224 BasicJsonType& result)
9225 {
9226 switch (value.m_type)
9227 {
9228 case detail::value_t::array:
9229 {
9230 if (value.m_value.array->empty())
9231 {
9232 // flatten empty array as null
9233 result[reference_string] = nullptr;
9234 }
9235 else
9236 {
9237 // iterate array and use index as reference string
9238 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9239 {
9240 flatten(reference_string + "/" + std::to_string(i),
9241 value.m_value.array->operator[](i), result);
9242 }
9243 }
9244 break;
9245 }
9246
9247 case detail::value_t::object:
9248 {
9249 if (value.m_value.object->empty())
9250 {
9251 // flatten empty object as null
9252 result[reference_string] = nullptr;
9253 }
9254 else
9255 {
9256 // iterate object and use keys as reference string
9257 for (const auto& element : *value.m_value.object)
9258 {
9259 flatten(reference_string + "/" + escape(element.first), element.second, result);
9260 }
9261 }
9262 break;
9263 }
9264
9265 default:
9266 {
9267 // add primitive value with its reference string
9268 result[reference_string] = value;
9269 break;
9270 }
9271 }
9272 }
9273
9274 /*!
9275 @param[in] value flattened JSON
9276
9277 @return unflattened JSON
9278
9279 @throw parse_error.109 if array index is not a number
9280 @throw type_error.314 if value is not an object
9281 @throw type_error.315 if object values are not primitive
9282 @throw type_error.313 if value cannot be unflattened
9283 */
9284 static BasicJsonType
unflatten(const BasicJsonType & value)9285 unflatten(const BasicJsonType& value)
9286 {
9287 if (JSON_UNLIKELY(not value.is_object()))
9288 {
9289 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
9290 }
9291
9292 BasicJsonType result;
9293
9294 // iterate the JSON object values
9295 for (const auto& element : *value.m_value.object)
9296 {
9297 if (JSON_UNLIKELY(not element.second.is_primitive()))
9298 {
9299 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
9300 }
9301
9302 // assign value to reference pointed to by JSON pointer; Note that if
9303 // the JSON pointer is "" (i.e., points to the whole value), function
9304 // get_and_create returns a reference to result itself. An assignment
9305 // will then create a primitive value.
9306 json_pointer(element.first).get_and_create(result) = element.second;
9307 }
9308
9309 return result;
9310 }
9311
9312 /*!
9313 @brief compares two JSON pointers for equality
9314
9315 @param[in] lhs JSON pointer to compare
9316 @param[in] rhs JSON pointer to compare
9317 @return whether @a lhs is equal to @a rhs
9318
9319 @complexity Linear in the length of the JSON pointer
9320
9321 @exceptionsafety No-throw guarantee: this function never throws exceptions.
9322 */
operator ==(json_pointer const & lhs,json_pointer const & rhs)9323 friend bool operator==(json_pointer const& lhs,
9324 json_pointer const& rhs) noexcept
9325 {
9326 return lhs.reference_tokens == rhs.reference_tokens;
9327 }
9328
9329 /*!
9330 @brief compares two JSON pointers for inequality
9331
9332 @param[in] lhs JSON pointer to compare
9333 @param[in] rhs JSON pointer to compare
9334 @return whether @a lhs is not equal @a rhs
9335
9336 @complexity Linear in the length of the JSON pointer
9337
9338 @exceptionsafety No-throw guarantee: this function never throws exceptions.
9339 */
operator !=(json_pointer const & lhs,json_pointer const & rhs)9340 friend bool operator!=(json_pointer const& lhs,
9341 json_pointer const& rhs) noexcept
9342 {
9343 return not (lhs == rhs);
9344 }
9345
9346 /// the reference tokens
9347 std::vector<std::string> reference_tokens;
9348 };
9349 } // namespace nlohmann
9350
9351 // #include <nlohmann/detail/json_ref.hpp>
9352
9353
9354 #include <initializer_list>
9355 #include <utility>
9356
9357 // #include <nlohmann/detail/meta/type_traits.hpp>
9358
9359
9360 namespace nlohmann
9361 {
9362 namespace detail
9363 {
9364 template<typename BasicJsonType>
9365 class json_ref
9366 {
9367 public:
9368 using value_type = BasicJsonType;
9369
json_ref(value_type && value)9370 json_ref(value_type&& value)
9371 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
9372 {}
9373
json_ref(const value_type & value)9374 json_ref(const value_type& value)
9375 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
9376 {}
9377
json_ref(std::initializer_list<json_ref> init)9378 json_ref(std::initializer_list<json_ref> init)
9379 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
9380 {}
9381
9382 template <
9383 class... Args,
9384 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)9385 json_ref(Args && ... args)
9386 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
9387 is_rvalue(true) {}
9388
9389 // class should be movable only
9390 json_ref(json_ref&&) = default;
9391 json_ref(const json_ref&) = delete;
9392 json_ref& operator=(const json_ref&) = delete;
9393 json_ref& operator=(json_ref&&) = delete;
9394 ~json_ref() = default;
9395
moved_or_copied() const9396 value_type moved_or_copied() const
9397 {
9398 if (is_rvalue)
9399 {
9400 return std::move(*value_ref);
9401 }
9402 return *value_ref;
9403 }
9404
operator *() const9405 value_type const& operator*() const
9406 {
9407 return *static_cast<value_type const*>(value_ref);
9408 }
9409
operator ->() const9410 value_type const* operator->() const
9411 {
9412 return static_cast<value_type const*>(value_ref);
9413 }
9414
9415 private:
9416 mutable value_type owned_value = nullptr;
9417 value_type* value_ref = nullptr;
9418 const bool is_rvalue;
9419 };
9420 } // namespace detail
9421 } // namespace nlohmann
9422
9423 // #include <nlohmann/detail/macro_scope.hpp>
9424
9425 // #include <nlohmann/detail/meta/cpp_future.hpp>
9426
9427 // #include <nlohmann/detail/meta/type_traits.hpp>
9428
9429 // #include <nlohmann/detail/output/binary_writer.hpp>
9430
9431
9432 #include <algorithm> // reverse
9433 #include <array> // array
9434 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
9435 #include <cstring> // memcpy
9436 #include <limits> // numeric_limits
9437 #include <string> // string
9438
9439 // #include <nlohmann/detail/input/binary_reader.hpp>
9440
9441 // #include <nlohmann/detail/output/output_adapters.hpp>
9442
9443
9444 #include <algorithm> // copy
9445 #include <cstddef> // size_t
9446 #include <ios> // streamsize
9447 #include <iterator> // back_inserter
9448 #include <memory> // shared_ptr, make_shared
9449 #include <ostream> // basic_ostream
9450 #include <string> // basic_string
9451 #include <vector> // vector
9452
9453 namespace nlohmann
9454 {
9455 namespace detail
9456 {
9457 /// abstract output adapter interface
9458 template<typename CharType> struct output_adapter_protocol
9459 {
9460 virtual void write_character(CharType c) = 0;
9461 virtual void write_characters(const CharType* s, std::size_t length) = 0;
9462 virtual ~output_adapter_protocol() = default;
9463 };
9464
9465 /// a type to simplify interfaces
9466 template<typename CharType>
9467 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
9468
9469 /// output adapter for byte vectors
9470 template<typename CharType>
9471 class output_vector_adapter : public output_adapter_protocol<CharType>
9472 {
9473 public:
output_vector_adapter(std::vector<CharType> & vec)9474 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
9475 : v(vec)
9476 {}
9477
write_character(CharType c)9478 void write_character(CharType c) override
9479 {
9480 v.push_back(c);
9481 }
9482
write_characters(const CharType * s,std::size_t length)9483 void write_characters(const CharType* s, std::size_t length) override
9484 {
9485 std::copy(s, s + length, std::back_inserter(v));
9486 }
9487
9488 private:
9489 std::vector<CharType>& v;
9490 };
9491
9492 /// output adapter for output streams
9493 template<typename CharType>
9494 class output_stream_adapter : public output_adapter_protocol<CharType>
9495 {
9496 public:
output_stream_adapter(std::basic_ostream<CharType> & s)9497 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
9498 : stream(s)
9499 {}
9500
write_character(CharType c)9501 void write_character(CharType c) override
9502 {
9503 stream.put(c);
9504 }
9505
write_characters(const CharType * s,std::size_t length)9506 void write_characters(const CharType* s, std::size_t length) override
9507 {
9508 stream.write(s, static_cast<std::streamsize>(length));
9509 }
9510
9511 private:
9512 std::basic_ostream<CharType>& stream;
9513 };
9514
9515 /// output adapter for basic_string
9516 template<typename CharType, typename StringType = std::basic_string<CharType>>
9517 class output_string_adapter : public output_adapter_protocol<CharType>
9518 {
9519 public:
output_string_adapter(StringType & s)9520 explicit output_string_adapter(StringType& s) noexcept
9521 : str(s)
9522 {}
9523
write_character(CharType c)9524 void write_character(CharType c) override
9525 {
9526 str.push_back(c);
9527 }
9528
write_characters(const CharType * s,std::size_t length)9529 void write_characters(const CharType* s, std::size_t length) override
9530 {
9531 str.append(s, length);
9532 }
9533
9534 private:
9535 StringType& str;
9536 };
9537
9538 template<typename CharType, typename StringType = std::basic_string<CharType>>
9539 class output_adapter
9540 {
9541 public:
output_adapter(std::vector<CharType> & vec)9542 output_adapter(std::vector<CharType>& vec)
9543 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
9544
output_adapter(std::basic_ostream<CharType> & s)9545 output_adapter(std::basic_ostream<CharType>& s)
9546 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
9547
output_adapter(StringType & s)9548 output_adapter(StringType& s)
9549 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
9550
operator output_adapter_t<CharType>()9551 operator output_adapter_t<CharType>()
9552 {
9553 return oa;
9554 }
9555
9556 private:
9557 output_adapter_t<CharType> oa = nullptr;
9558 };
9559 } // namespace detail
9560 } // namespace nlohmann
9561
9562
9563 namespace nlohmann
9564 {
9565 namespace detail
9566 {
9567 ///////////////////
9568 // binary writer //
9569 ///////////////////
9570
9571 /*!
9572 @brief serialization to CBOR and MessagePack values
9573 */
9574 template<typename BasicJsonType, typename CharType>
9575 class binary_writer
9576 {
9577 using string_t = typename BasicJsonType::string_t;
9578
9579 public:
9580 /*!
9581 @brief create a binary writer
9582
9583 @param[in] adapter output adapter to write to
9584 */
binary_writer(output_adapter_t<CharType> adapter)9585 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
9586 {
9587 assert(oa);
9588 }
9589
9590 /*!
9591 @param[in] j JSON value to serialize
9592 @pre j.type() == value_t::object
9593 */
write_bson(const BasicJsonType & j)9594 void write_bson(const BasicJsonType& j)
9595 {
9596 switch (j.type())
9597 {
9598 case value_t::object:
9599 {
9600 write_bson_object(*j.m_value.object);
9601 break;
9602 }
9603
9604 default:
9605 {
9606 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
9607 }
9608 }
9609 }
9610
9611 /*!
9612 @param[in] j JSON value to serialize
9613 */
write_cbor(const BasicJsonType & j)9614 void write_cbor(const BasicJsonType& j)
9615 {
9616 switch (j.type())
9617 {
9618 case value_t::null:
9619 {
9620 oa->write_character(to_char_type(0xF6));
9621 break;
9622 }
9623
9624 case value_t::boolean:
9625 {
9626 oa->write_character(j.m_value.boolean
9627 ? to_char_type(0xF5)
9628 : to_char_type(0xF4));
9629 break;
9630 }
9631
9632 case value_t::number_integer:
9633 {
9634 if (j.m_value.number_integer >= 0)
9635 {
9636 // CBOR does not differentiate between positive signed
9637 // integers and unsigned integers. Therefore, we used the
9638 // code from the value_t::number_unsigned case here.
9639 if (j.m_value.number_integer <= 0x17)
9640 {
9641 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9642 }
9643 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
9644 {
9645 oa->write_character(to_char_type(0x18));
9646 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9647 }
9648 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
9649 {
9650 oa->write_character(to_char_type(0x19));
9651 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9652 }
9653 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
9654 {
9655 oa->write_character(to_char_type(0x1A));
9656 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9657 }
9658 else
9659 {
9660 oa->write_character(to_char_type(0x1B));
9661 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9662 }
9663 }
9664 else
9665 {
9666 // The conversions below encode the sign in the first
9667 // byte, and the value is converted to a positive number.
9668 const auto positive_number = -1 - j.m_value.number_integer;
9669 if (j.m_value.number_integer >= -24)
9670 {
9671 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
9672 }
9673 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
9674 {
9675 oa->write_character(to_char_type(0x38));
9676 write_number(static_cast<std::uint8_t>(positive_number));
9677 }
9678 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
9679 {
9680 oa->write_character(to_char_type(0x39));
9681 write_number(static_cast<std::uint16_t>(positive_number));
9682 }
9683 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
9684 {
9685 oa->write_character(to_char_type(0x3A));
9686 write_number(static_cast<std::uint32_t>(positive_number));
9687 }
9688 else
9689 {
9690 oa->write_character(to_char_type(0x3B));
9691 write_number(static_cast<std::uint64_t>(positive_number));
9692 }
9693 }
9694 break;
9695 }
9696
9697 case value_t::number_unsigned:
9698 {
9699 if (j.m_value.number_unsigned <= 0x17)
9700 {
9701 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
9702 }
9703 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9704 {
9705 oa->write_character(to_char_type(0x18));
9706 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
9707 }
9708 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9709 {
9710 oa->write_character(to_char_type(0x19));
9711 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
9712 }
9713 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9714 {
9715 oa->write_character(to_char_type(0x1A));
9716 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
9717 }
9718 else
9719 {
9720 oa->write_character(to_char_type(0x1B));
9721 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
9722 }
9723 break;
9724 }
9725
9726 case value_t::number_float:
9727 {
9728 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
9729 write_number(j.m_value.number_float);
9730 break;
9731 }
9732
9733 case value_t::string:
9734 {
9735 // step 1: write control byte and the string length
9736 const auto N = j.m_value.string->size();
9737 if (N <= 0x17)
9738 {
9739 write_number(static_cast<std::uint8_t>(0x60 + N));
9740 }
9741 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9742 {
9743 oa->write_character(to_char_type(0x78));
9744 write_number(static_cast<std::uint8_t>(N));
9745 }
9746 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9747 {
9748 oa->write_character(to_char_type(0x79));
9749 write_number(static_cast<std::uint16_t>(N));
9750 }
9751 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9752 {
9753 oa->write_character(to_char_type(0x7A));
9754 write_number(static_cast<std::uint32_t>(N));
9755 }
9756 // LCOV_EXCL_START
9757 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9758 {
9759 oa->write_character(to_char_type(0x7B));
9760 write_number(static_cast<std::uint64_t>(N));
9761 }
9762 // LCOV_EXCL_STOP
9763
9764 // step 2: write the string
9765 oa->write_characters(
9766 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
9767 j.m_value.string->size());
9768 break;
9769 }
9770
9771 case value_t::array:
9772 {
9773 // step 1: write control byte and the array size
9774 const auto N = j.m_value.array->size();
9775 if (N <= 0x17)
9776 {
9777 write_number(static_cast<std::uint8_t>(0x80 + N));
9778 }
9779 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9780 {
9781 oa->write_character(to_char_type(0x98));
9782 write_number(static_cast<std::uint8_t>(N));
9783 }
9784 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9785 {
9786 oa->write_character(to_char_type(0x99));
9787 write_number(static_cast<std::uint16_t>(N));
9788 }
9789 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9790 {
9791 oa->write_character(to_char_type(0x9A));
9792 write_number(static_cast<std::uint32_t>(N));
9793 }
9794 // LCOV_EXCL_START
9795 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9796 {
9797 oa->write_character(to_char_type(0x9B));
9798 write_number(static_cast<std::uint64_t>(N));
9799 }
9800 // LCOV_EXCL_STOP
9801
9802 // step 2: write each element
9803 for (const auto& el : *j.m_value.array)
9804 {
9805 write_cbor(el);
9806 }
9807 break;
9808 }
9809
9810 case value_t::object:
9811 {
9812 // step 1: write control byte and the object size
9813 const auto N = j.m_value.object->size();
9814 if (N <= 0x17)
9815 {
9816 write_number(static_cast<std::uint8_t>(0xA0 + N));
9817 }
9818 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9819 {
9820 oa->write_character(to_char_type(0xB8));
9821 write_number(static_cast<std::uint8_t>(N));
9822 }
9823 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9824 {
9825 oa->write_character(to_char_type(0xB9));
9826 write_number(static_cast<std::uint16_t>(N));
9827 }
9828 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9829 {
9830 oa->write_character(to_char_type(0xBA));
9831 write_number(static_cast<std::uint32_t>(N));
9832 }
9833 // LCOV_EXCL_START
9834 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9835 {
9836 oa->write_character(to_char_type(0xBB));
9837 write_number(static_cast<std::uint64_t>(N));
9838 }
9839 // LCOV_EXCL_STOP
9840
9841 // step 2: write each element
9842 for (const auto& el : *j.m_value.object)
9843 {
9844 write_cbor(el.first);
9845 write_cbor(el.second);
9846 }
9847 break;
9848 }
9849
9850 default:
9851 break;
9852 }
9853 }
9854
9855 /*!
9856 @param[in] j JSON value to serialize
9857 */
write_msgpack(const BasicJsonType & j)9858 void write_msgpack(const BasicJsonType& j)
9859 {
9860 switch (j.type())
9861 {
9862 case value_t::null: // nil
9863 {
9864 oa->write_character(to_char_type(0xC0));
9865 break;
9866 }
9867
9868 case value_t::boolean: // true and false
9869 {
9870 oa->write_character(j.m_value.boolean
9871 ? to_char_type(0xC3)
9872 : to_char_type(0xC2));
9873 break;
9874 }
9875
9876 case value_t::number_integer:
9877 {
9878 if (j.m_value.number_integer >= 0)
9879 {
9880 // MessagePack does not differentiate between positive
9881 // signed integers and unsigned integers. Therefore, we used
9882 // the code from the value_t::number_unsigned case here.
9883 if (j.m_value.number_unsigned < 128)
9884 {
9885 // positive fixnum
9886 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9887 }
9888 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9889 {
9890 // uint 8
9891 oa->write_character(to_char_type(0xCC));
9892 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9893 }
9894 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9895 {
9896 // uint 16
9897 oa->write_character(to_char_type(0xCD));
9898 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9899 }
9900 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9901 {
9902 // uint 32
9903 oa->write_character(to_char_type(0xCE));
9904 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9905 }
9906 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9907 {
9908 // uint 64
9909 oa->write_character(to_char_type(0xCF));
9910 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9911 }
9912 }
9913 else
9914 {
9915 if (j.m_value.number_integer >= -32)
9916 {
9917 // negative fixnum
9918 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
9919 }
9920 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
9921 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
9922 {
9923 // int 8
9924 oa->write_character(to_char_type(0xD0));
9925 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
9926 }
9927 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
9928 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
9929 {
9930 // int 16
9931 oa->write_character(to_char_type(0xD1));
9932 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
9933 }
9934 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
9935 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
9936 {
9937 // int 32
9938 oa->write_character(to_char_type(0xD2));
9939 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
9940 }
9941 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
9942 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
9943 {
9944 // int 64
9945 oa->write_character(to_char_type(0xD3));
9946 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
9947 }
9948 }
9949 break;
9950 }
9951
9952 case value_t::number_unsigned:
9953 {
9954 if (j.m_value.number_unsigned < 128)
9955 {
9956 // positive fixnum
9957 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9958 }
9959 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9960 {
9961 // uint 8
9962 oa->write_character(to_char_type(0xCC));
9963 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9964 }
9965 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9966 {
9967 // uint 16
9968 oa->write_character(to_char_type(0xCD));
9969 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9970 }
9971 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9972 {
9973 // uint 32
9974 oa->write_character(to_char_type(0xCE));
9975 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9976 }
9977 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9978 {
9979 // uint 64
9980 oa->write_character(to_char_type(0xCF));
9981 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9982 }
9983 break;
9984 }
9985
9986 case value_t::number_float:
9987 {
9988 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
9989 write_number(j.m_value.number_float);
9990 break;
9991 }
9992
9993 case value_t::string:
9994 {
9995 // step 1: write control byte and the string length
9996 const auto N = j.m_value.string->size();
9997 if (N <= 31)
9998 {
9999 // fixstr
10000 write_number(static_cast<std::uint8_t>(0xA0 | N));
10001 }
10002 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
10003 {
10004 // str 8
10005 oa->write_character(to_char_type(0xD9));
10006 write_number(static_cast<std::uint8_t>(N));
10007 }
10008 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10009 {
10010 // str 16
10011 oa->write_character(to_char_type(0xDA));
10012 write_number(static_cast<std::uint16_t>(N));
10013 }
10014 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10015 {
10016 // str 32
10017 oa->write_character(to_char_type(0xDB));
10018 write_number(static_cast<std::uint32_t>(N));
10019 }
10020
10021 // step 2: write the string
10022 oa->write_characters(
10023 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
10024 j.m_value.string->size());
10025 break;
10026 }
10027
10028 case value_t::array:
10029 {
10030 // step 1: write control byte and the array size
10031 const auto N = j.m_value.array->size();
10032 if (N <= 15)
10033 {
10034 // fixarray
10035 write_number(static_cast<std::uint8_t>(0x90 | N));
10036 }
10037 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10038 {
10039 // array 16
10040 oa->write_character(to_char_type(0xDC));
10041 write_number(static_cast<std::uint16_t>(N));
10042 }
10043 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10044 {
10045 // array 32
10046 oa->write_character(to_char_type(0xDD));
10047 write_number(static_cast<std::uint32_t>(N));
10048 }
10049
10050 // step 2: write each element
10051 for (const auto& el : *j.m_value.array)
10052 {
10053 write_msgpack(el);
10054 }
10055 break;
10056 }
10057
10058 case value_t::object:
10059 {
10060 // step 1: write control byte and the object size
10061 const auto N = j.m_value.object->size();
10062 if (N <= 15)
10063 {
10064 // fixmap
10065 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
10066 }
10067 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10068 {
10069 // map 16
10070 oa->write_character(to_char_type(0xDE));
10071 write_number(static_cast<std::uint16_t>(N));
10072 }
10073 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10074 {
10075 // map 32
10076 oa->write_character(to_char_type(0xDF));
10077 write_number(static_cast<std::uint32_t>(N));
10078 }
10079
10080 // step 2: write each element
10081 for (const auto& el : *j.m_value.object)
10082 {
10083 write_msgpack(el.first);
10084 write_msgpack(el.second);
10085 }
10086 break;
10087 }
10088
10089 default:
10090 break;
10091 }
10092 }
10093
10094 /*!
10095 @param[in] j JSON value to serialize
10096 @param[in] use_count whether to use '#' prefixes (optimized format)
10097 @param[in] use_type whether to use '$' prefixes (optimized format)
10098 @param[in] add_prefix whether prefixes need to be used for this value
10099 */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)10100 void write_ubjson(const BasicJsonType& j, const bool use_count,
10101 const bool use_type, const bool add_prefix = true)
10102 {
10103 switch (j.type())
10104 {
10105 case value_t::null:
10106 {
10107 if (add_prefix)
10108 {
10109 oa->write_character(to_char_type('Z'));
10110 }
10111 break;
10112 }
10113
10114 case value_t::boolean:
10115 {
10116 if (add_prefix)
10117 {
10118 oa->write_character(j.m_value.boolean
10119 ? to_char_type('T')
10120 : to_char_type('F'));
10121 }
10122 break;
10123 }
10124
10125 case value_t::number_integer:
10126 {
10127 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
10128 break;
10129 }
10130
10131 case value_t::number_unsigned:
10132 {
10133 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
10134 break;
10135 }
10136
10137 case value_t::number_float:
10138 {
10139 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
10140 break;
10141 }
10142
10143 case value_t::string:
10144 {
10145 if (add_prefix)
10146 {
10147 oa->write_character(to_char_type('S'));
10148 }
10149 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
10150 oa->write_characters(
10151 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
10152 j.m_value.string->size());
10153 break;
10154 }
10155
10156 case value_t::array:
10157 {
10158 if (add_prefix)
10159 {
10160 oa->write_character(to_char_type('['));
10161 }
10162
10163 bool prefix_required = true;
10164 if (use_type and not j.m_value.array->empty())
10165 {
10166 assert(use_count);
10167 const CharType first_prefix = ubjson_prefix(j.front());
10168 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
10169 [this, first_prefix](const BasicJsonType & v)
10170 {
10171 return ubjson_prefix(v) == first_prefix;
10172 });
10173
10174 if (same_prefix)
10175 {
10176 prefix_required = false;
10177 oa->write_character(to_char_type('$'));
10178 oa->write_character(first_prefix);
10179 }
10180 }
10181
10182 if (use_count)
10183 {
10184 oa->write_character(to_char_type('#'));
10185 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
10186 }
10187
10188 for (const auto& el : *j.m_value.array)
10189 {
10190 write_ubjson(el, use_count, use_type, prefix_required);
10191 }
10192
10193 if (not use_count)
10194 {
10195 oa->write_character(to_char_type(']'));
10196 }
10197
10198 break;
10199 }
10200
10201 case value_t::object:
10202 {
10203 if (add_prefix)
10204 {
10205 oa->write_character(to_char_type('{'));
10206 }
10207
10208 bool prefix_required = true;
10209 if (use_type and not j.m_value.object->empty())
10210 {
10211 assert(use_count);
10212 const CharType first_prefix = ubjson_prefix(j.front());
10213 const bool same_prefix = std::all_of(j.begin(), j.end(),
10214 [this, first_prefix](const BasicJsonType & v)
10215 {
10216 return ubjson_prefix(v) == first_prefix;
10217 });
10218
10219 if (same_prefix)
10220 {
10221 prefix_required = false;
10222 oa->write_character(to_char_type('$'));
10223 oa->write_character(first_prefix);
10224 }
10225 }
10226
10227 if (use_count)
10228 {
10229 oa->write_character(to_char_type('#'));
10230 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
10231 }
10232
10233 for (const auto& el : *j.m_value.object)
10234 {
10235 write_number_with_ubjson_prefix(el.first.size(), true);
10236 oa->write_characters(
10237 reinterpret_cast<const CharType*>(el.first.c_str()),
10238 el.first.size());
10239 write_ubjson(el.second, use_count, use_type, prefix_required);
10240 }
10241
10242 if (not use_count)
10243 {
10244 oa->write_character(to_char_type('}'));
10245 }
10246
10247 break;
10248 }
10249
10250 default:
10251 break;
10252 }
10253 }
10254
10255 private:
10256 //////////
10257 // BSON //
10258 //////////
10259
10260 /*!
10261 @return The size of a BSON document entry header, including the id marker
10262 and the entry name size (and its null-terminator).
10263 */
calc_bson_entry_header_size(const string_t & name)10264 static std::size_t calc_bson_entry_header_size(const string_t& name)
10265 {
10266 const auto it = name.find(static_cast<typename string_t::value_type>(0));
10267 if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
10268 {
10269 JSON_THROW(out_of_range::create(409,
10270 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
10271 }
10272
10273 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
10274 }
10275
10276 /*!
10277 @brief Writes the given @a element_type and @a name to the output adapter
10278 */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)10279 void write_bson_entry_header(const string_t& name,
10280 const std::uint8_t element_type)
10281 {
10282 oa->write_character(to_char_type(element_type)); // boolean
10283 oa->write_characters(
10284 reinterpret_cast<const CharType*>(name.c_str()),
10285 name.size() + 1u);
10286 }
10287
10288 /*!
10289 @brief Writes a BSON element with key @a name and boolean value @a value
10290 */
write_bson_boolean(const string_t & name,const bool value)10291 void write_bson_boolean(const string_t& name,
10292 const bool value)
10293 {
10294 write_bson_entry_header(name, 0x08);
10295 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
10296 }
10297
10298 /*!
10299 @brief Writes a BSON element with key @a name and double value @a value
10300 */
write_bson_double(const string_t & name,const double value)10301 void write_bson_double(const string_t& name,
10302 const double value)
10303 {
10304 write_bson_entry_header(name, 0x01);
10305 write_number<double, true>(value);
10306 }
10307
10308 /*!
10309 @return The size of the BSON-encoded string in @a value
10310 */
calc_bson_string_size(const string_t & value)10311 static std::size_t calc_bson_string_size(const string_t& value)
10312 {
10313 return sizeof(std::int32_t) + value.size() + 1ul;
10314 }
10315
10316 /*!
10317 @brief Writes a BSON element with key @a name and string value @a value
10318 */
write_bson_string(const string_t & name,const string_t & value)10319 void write_bson_string(const string_t& name,
10320 const string_t& value)
10321 {
10322 write_bson_entry_header(name, 0x02);
10323
10324 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
10325 oa->write_characters(
10326 reinterpret_cast<const CharType*>(value.c_str()),
10327 value.size() + 1);
10328 }
10329
10330 /*!
10331 @brief Writes a BSON element with key @a name and null value
10332 */
write_bson_null(const string_t & name)10333 void write_bson_null(const string_t& name)
10334 {
10335 write_bson_entry_header(name, 0x0A);
10336 }
10337
10338 /*!
10339 @return The size of the BSON-encoded integer @a value
10340 */
calc_bson_integer_size(const std::int64_t value)10341 static std::size_t calc_bson_integer_size(const std::int64_t value)
10342 {
10343 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
10344 ? sizeof(std::int32_t)
10345 : sizeof(std::int64_t);
10346 }
10347
10348 /*!
10349 @brief Writes a BSON element with key @a name and integer @a value
10350 */
write_bson_integer(const string_t & name,const std::int64_t value)10351 void write_bson_integer(const string_t& name,
10352 const std::int64_t value)
10353 {
10354 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
10355 {
10356 write_bson_entry_header(name, 0x10); // int32
10357 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
10358 }
10359 else
10360 {
10361 write_bson_entry_header(name, 0x12); // int64
10362 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
10363 }
10364 }
10365
10366 /*!
10367 @return The size of the BSON-encoded unsigned integer in @a j
10368 */
calc_bson_unsigned_size(const std::uint64_t value)10369 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
10370 {
10371 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10372 ? sizeof(std::int32_t)
10373 : sizeof(std::int64_t);
10374 }
10375
10376 /*!
10377 @brief Writes a BSON element with key @a name and unsigned @a value
10378 */
write_bson_unsigned(const string_t & name,const std::uint64_t value)10379 void write_bson_unsigned(const string_t& name,
10380 const std::uint64_t value)
10381 {
10382 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10383 {
10384 write_bson_entry_header(name, 0x10 /* int32 */);
10385 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
10386 }
10387 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10388 {
10389 write_bson_entry_header(name, 0x12 /* int64 */);
10390 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
10391 }
10392 else
10393 {
10394 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
10395 }
10396 }
10397
10398 /*!
10399 @brief Writes a BSON element with key @a name and object @a value
10400 */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)10401 void write_bson_object_entry(const string_t& name,
10402 const typename BasicJsonType::object_t& value)
10403 {
10404 write_bson_entry_header(name, 0x03); // object
10405 write_bson_object(value);
10406 }
10407
10408 /*!
10409 @return The size of the BSON-encoded array @a value
10410 */
calc_bson_array_size(const typename BasicJsonType::array_t & value)10411 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
10412 {
10413 std::size_t embedded_document_size = 0ul;
10414 std::size_t array_index = 0ul;
10415
10416 for (const auto& el : value)
10417 {
10418 embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
10419 }
10420
10421 return sizeof(std::int32_t) + embedded_document_size + 1ul;
10422 }
10423
10424 /*!
10425 @brief Writes a BSON element with key @a name and array @a value
10426 */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)10427 void write_bson_array(const string_t& name,
10428 const typename BasicJsonType::array_t& value)
10429 {
10430 write_bson_entry_header(name, 0x04); // array
10431 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
10432
10433 std::size_t array_index = 0ul;
10434
10435 for (const auto& el : value)
10436 {
10437 write_bson_element(std::to_string(array_index++), el);
10438 }
10439
10440 oa->write_character(to_char_type(0x00));
10441 }
10442
10443 /*!
10444 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
10445 @return The calculated size for the BSON document entry for @a j with the given @a name.
10446 */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)10447 static std::size_t calc_bson_element_size(const string_t& name,
10448 const BasicJsonType& j)
10449 {
10450 const auto header_size = calc_bson_entry_header_size(name);
10451 switch (j.type())
10452 {
10453 case value_t::object:
10454 return header_size + calc_bson_object_size(*j.m_value.object);
10455
10456 case value_t::array:
10457 return header_size + calc_bson_array_size(*j.m_value.array);
10458
10459 case value_t::boolean:
10460 return header_size + 1ul;
10461
10462 case value_t::number_float:
10463 return header_size + 8ul;
10464
10465 case value_t::number_integer:
10466 return header_size + calc_bson_integer_size(j.m_value.number_integer);
10467
10468 case value_t::number_unsigned:
10469 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
10470
10471 case value_t::string:
10472 return header_size + calc_bson_string_size(*j.m_value.string);
10473
10474 case value_t::null:
10475 return header_size + 0ul;
10476
10477 // LCOV_EXCL_START
10478 default:
10479 assert(false);
10480 return 0ul;
10481 // LCOV_EXCL_STOP
10482 }
10483 }
10484
10485 /*!
10486 @brief Serializes the JSON value @a j to BSON and associates it with the
10487 key @a name.
10488 @param name The name to associate with the JSON entity @a j within the
10489 current BSON document
10490 @return The size of the BSON entry
10491 */
write_bson_element(const string_t & name,const BasicJsonType & j)10492 void write_bson_element(const string_t& name,
10493 const BasicJsonType& j)
10494 {
10495 switch (j.type())
10496 {
10497 case value_t::object:
10498 return write_bson_object_entry(name, *j.m_value.object);
10499
10500 case value_t::array:
10501 return write_bson_array(name, *j.m_value.array);
10502
10503 case value_t::boolean:
10504 return write_bson_boolean(name, j.m_value.boolean);
10505
10506 case value_t::number_float:
10507 return write_bson_double(name, j.m_value.number_float);
10508
10509 case value_t::number_integer:
10510 return write_bson_integer(name, j.m_value.number_integer);
10511
10512 case value_t::number_unsigned:
10513 return write_bson_unsigned(name, j.m_value.number_unsigned);
10514
10515 case value_t::string:
10516 return write_bson_string(name, *j.m_value.string);
10517
10518 case value_t::null:
10519 return write_bson_null(name);
10520
10521 // LCOV_EXCL_START
10522 default:
10523 assert(false);
10524 return;
10525 // LCOV_EXCL_STOP
10526 }
10527 }
10528
10529 /*!
10530 @brief Calculates the size of the BSON serialization of the given
10531 JSON-object @a j.
10532 @param[in] j JSON value to serialize
10533 @pre j.type() == value_t::object
10534 */
calc_bson_object_size(const typename BasicJsonType::object_t & value)10535 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
10536 {
10537 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
10538 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
10539 {
10540 return result += calc_bson_element_size(el.first, el.second);
10541 });
10542
10543 return sizeof(std::int32_t) + document_size + 1ul;
10544 }
10545
10546 /*!
10547 @param[in] j JSON value to serialize
10548 @pre j.type() == value_t::object
10549 */
write_bson_object(const typename BasicJsonType::object_t & value)10550 void write_bson_object(const typename BasicJsonType::object_t& value)
10551 {
10552 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
10553
10554 for (const auto& el : value)
10555 {
10556 write_bson_element(el.first, el.second);
10557 }
10558
10559 oa->write_character(to_char_type(0x00));
10560 }
10561
10562 //////////
10563 // CBOR //
10564 //////////
10565
get_cbor_float_prefix(float)10566 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
10567 {
10568 return to_char_type(0xFA); // Single-Precision Float
10569 }
10570
get_cbor_float_prefix(double)10571 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
10572 {
10573 return to_char_type(0xFB); // Double-Precision Float
10574 }
10575
10576 /////////////
10577 // MsgPack //
10578 /////////////
10579
get_msgpack_float_prefix(float)10580 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
10581 {
10582 return to_char_type(0xCA); // float 32
10583 }
10584
get_msgpack_float_prefix(double)10585 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
10586 {
10587 return to_char_type(0xCB); // float 64
10588 }
10589
10590 ////////////
10591 // UBJSON //
10592 ////////////
10593
10594 // UBJSON: write number (floating point)
10595 template<typename NumberType, typename std::enable_if<
10596 std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10597 void write_number_with_ubjson_prefix(const NumberType n,
10598 const bool add_prefix)
10599 {
10600 if (add_prefix)
10601 {
10602 oa->write_character(get_ubjson_float_prefix(n));
10603 }
10604 write_number(n);
10605 }
10606
10607 // UBJSON: write number (unsigned integer)
10608 template<typename NumberType, typename std::enable_if<
10609 std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10610 void write_number_with_ubjson_prefix(const NumberType n,
10611 const bool add_prefix)
10612 {
10613 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
10614 {
10615 if (add_prefix)
10616 {
10617 oa->write_character(to_char_type('i')); // int8
10618 }
10619 write_number(static_cast<std::uint8_t>(n));
10620 }
10621 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
10622 {
10623 if (add_prefix)
10624 {
10625 oa->write_character(to_char_type('U')); // uint8
10626 }
10627 write_number(static_cast<std::uint8_t>(n));
10628 }
10629 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
10630 {
10631 if (add_prefix)
10632 {
10633 oa->write_character(to_char_type('I')); // int16
10634 }
10635 write_number(static_cast<std::int16_t>(n));
10636 }
10637 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10638 {
10639 if (add_prefix)
10640 {
10641 oa->write_character(to_char_type('l')); // int32
10642 }
10643 write_number(static_cast<std::int32_t>(n));
10644 }
10645 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10646 {
10647 if (add_prefix)
10648 {
10649 oa->write_character(to_char_type('L')); // int64
10650 }
10651 write_number(static_cast<std::int64_t>(n));
10652 }
10653 else
10654 {
10655 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
10656 }
10657 }
10658
10659 // UBJSON: write number (signed integer)
10660 template<typename NumberType, typename std::enable_if<
10661 std::is_signed<NumberType>::value and
10662 not std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10663 void write_number_with_ubjson_prefix(const NumberType n,
10664 const bool add_prefix)
10665 {
10666 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
10667 {
10668 if (add_prefix)
10669 {
10670 oa->write_character(to_char_type('i')); // int8
10671 }
10672 write_number(static_cast<std::int8_t>(n));
10673 }
10674 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n and n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
10675 {
10676 if (add_prefix)
10677 {
10678 oa->write_character(to_char_type('U')); // uint8
10679 }
10680 write_number(static_cast<std::uint8_t>(n));
10681 }
10682 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
10683 {
10684 if (add_prefix)
10685 {
10686 oa->write_character(to_char_type('I')); // int16
10687 }
10688 write_number(static_cast<std::int16_t>(n));
10689 }
10690 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
10691 {
10692 if (add_prefix)
10693 {
10694 oa->write_character(to_char_type('l')); // int32
10695 }
10696 write_number(static_cast<std::int32_t>(n));
10697 }
10698 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
10699 {
10700 if (add_prefix)
10701 {
10702 oa->write_character(to_char_type('L')); // int64
10703 }
10704 write_number(static_cast<std::int64_t>(n));
10705 }
10706 // LCOV_EXCL_START
10707 else
10708 {
10709 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
10710 }
10711 // LCOV_EXCL_STOP
10712 }
10713
10714 /*!
10715 @brief determine the type prefix of container values
10716
10717 @note This function does not need to be 100% accurate when it comes to
10718 integer limits. In case a number exceeds the limits of int64_t,
10719 this will be detected by a later call to function
10720 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
10721 value that does not fit the previous limits.
10722 */
ubjson_prefix(const BasicJsonType & j) const10723 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
10724 {
10725 switch (j.type())
10726 {
10727 case value_t::null:
10728 return 'Z';
10729
10730 case value_t::boolean:
10731 return j.m_value.boolean ? 'T' : 'F';
10732
10733 case value_t::number_integer:
10734 {
10735 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
10736 {
10737 return 'i';
10738 }
10739 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
10740 {
10741 return 'U';
10742 }
10743 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
10744 {
10745 return 'I';
10746 }
10747 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer and j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
10748 {
10749 return 'l';
10750 }
10751 // no check and assume int64_t (see note above)
10752 return 'L';
10753 }
10754
10755 case value_t::number_unsigned:
10756 {
10757 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int8_t>::max)())
10758 {
10759 return 'i';
10760 }
10761 if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
10762 {
10763 return 'U';
10764 }
10765 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int16_t>::max)())
10766 {
10767 return 'I';
10768 }
10769 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int32_t>::max)())
10770 {
10771 return 'l';
10772 }
10773 // no check and assume int64_t (see note above)
10774 return 'L';
10775 }
10776
10777 case value_t::number_float:
10778 return get_ubjson_float_prefix(j.m_value.number_float);
10779
10780 case value_t::string:
10781 return 'S';
10782
10783 case value_t::array:
10784 return '[';
10785
10786 case value_t::object:
10787 return '{';
10788
10789 default: // discarded values
10790 return 'N';
10791 }
10792 }
10793
get_ubjson_float_prefix(float)10794 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
10795 {
10796 return 'd'; // float 32
10797 }
10798
get_ubjson_float_prefix(double)10799 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
10800 {
10801 return 'D'; // float 64
10802 }
10803
10804 ///////////////////////
10805 // Utility functions //
10806 ///////////////////////
10807
10808 /*
10809 @brief write a number to output input
10810 @param[in] n number of type @a NumberType
10811 @tparam NumberType the type of the number
10812 @tparam OutputIsLittleEndian Set to true if output data is
10813 required to be little endian
10814
10815 @note This function needs to respect the system's endianess, because bytes
10816 in CBOR, MessagePack, and UBJSON are stored in network order (big
10817 endian) and therefore need reordering on little endian systems.
10818 */
10819 template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)10820 void write_number(const NumberType n)
10821 {
10822 // step 1: write number to array of length NumberType
10823 std::array<CharType, sizeof(NumberType)> vec;
10824 std::memcpy(vec.data(), &n, sizeof(NumberType));
10825
10826 // step 2: write array to output (with possible reordering)
10827 if (is_little_endian != OutputIsLittleEndian)
10828 {
10829 // reverse byte order prior to conversion if necessary
10830 std::reverse(vec.begin(), vec.end());
10831 }
10832
10833 oa->write_characters(vec.data(), sizeof(NumberType));
10834 }
10835
10836 public:
10837 // The following to_char_type functions are implement the conversion
10838 // between uint8_t and CharType. In case CharType is not unsigned,
10839 // such a conversion is required to allow values greater than 128.
10840 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
10841 template < typename C = CharType,
10842 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)10843 static constexpr CharType to_char_type(std::uint8_t x) noexcept
10844 {
10845 return *reinterpret_cast<char*>(&x);
10846 }
10847
10848 template < typename C = CharType,
10849 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)10850 static CharType to_char_type(std::uint8_t x) noexcept
10851 {
10852 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
10853 static_assert(std::is_pod<CharType>::value, "CharType must be POD");
10854 CharType result;
10855 std::memcpy(&result, &x, sizeof(x));
10856 return result;
10857 }
10858
10859 template<typename C = CharType,
10860 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)10861 static constexpr CharType to_char_type(std::uint8_t x) noexcept
10862 {
10863 return x;
10864 }
10865
10866 template < typename InputCharType, typename C = CharType,
10867 enable_if_t <
10868 std::is_signed<C>::value and
10869 std::is_signed<char>::value and
10870 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
10871 > * = nullptr >
to_char_type(InputCharType x)10872 static constexpr CharType to_char_type(InputCharType x) noexcept
10873 {
10874 return x;
10875 }
10876
10877 private:
10878 /// whether we can assume little endianess
10879 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
10880
10881 /// the output
10882 output_adapter_t<CharType> oa = nullptr;
10883 };
10884 } // namespace detail
10885 } // namespace nlohmann
10886
10887 // #include <nlohmann/detail/output/output_adapters.hpp>
10888
10889 // #include <nlohmann/detail/output/serializer.hpp>
10890
10891
10892 #include <algorithm> // reverse, remove, fill, find, none_of
10893 #include <array> // array
10894 #include <cassert> // assert
10895 #include <ciso646> // and, or
10896 #include <clocale> // localeconv, lconv
10897 #include <cmath> // labs, isfinite, isnan, signbit
10898 #include <cstddef> // size_t, ptrdiff_t
10899 #include <cstdint> // uint8_t
10900 #include <cstdio> // snprintf
10901 #include <limits> // numeric_limits
10902 #include <string> // string
10903 #include <type_traits> // is_same
10904 #include <utility> // move
10905
10906 // #include <nlohmann/detail/conversions/to_chars.hpp>
10907
10908
10909 #include <array> // array
10910 #include <cassert> // assert
10911 #include <ciso646> // or, and, not
10912 #include <cmath> // signbit, isfinite
10913 #include <cstdint> // intN_t, uintN_t
10914 #include <cstring> // memcpy, memmove
10915 #include <limits> // numeric_limits
10916 #include <type_traits> // conditional
10917
10918 namespace nlohmann
10919 {
10920 namespace detail
10921 {
10922
10923 /*!
10924 @brief implements the Grisu2 algorithm for binary to decimal floating-point
10925 conversion.
10926
10927 This implementation is a slightly modified version of the reference
10928 implementation which may be obtained from
10929 http://florian.loitsch.com/publications (bench.tar.gz).
10930
10931 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
10932
10933 For a detailed description of the algorithm see:
10934
10935 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
10936 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
10937 Language Design and Implementation, PLDI 2010
10938 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
10939 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
10940 Design and Implementation, PLDI 1996
10941 */
10942 namespace dtoa_impl
10943 {
10944
10945 template <typename Target, typename Source>
10946 Target reinterpret_bits(const Source source)
10947 {
10948 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
10949
10950 Target target;
10951 std::memcpy(&target, &source, sizeof(Source));
10952 return target;
10953 }
10954
10955 struct diyfp // f * 2^e
10956 {
10957 static constexpr int kPrecision = 64; // = q
10958
10959 std::uint64_t f = 0;
10960 int e = 0;
10961
diyfpnlohmann::detail::dtoa_impl::diyfp10962 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
10963
10964 /*!
10965 @brief returns x - y
10966 @pre x.e == y.e and x.f >= y.f
10967 */
subnlohmann::detail::dtoa_impl::diyfp10968 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
10969 {
10970 assert(x.e == y.e);
10971 assert(x.f >= y.f);
10972
10973 return {x.f - y.f, x.e};
10974 }
10975
10976 /*!
10977 @brief returns x * y
10978 @note The result is rounded. (Only the upper q bits are returned.)
10979 */
mulnlohmann::detail::dtoa_impl::diyfp10980 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
10981 {
10982 static_assert(kPrecision == 64, "internal error");
10983
10984 // Computes:
10985 // f = round((x.f * y.f) / 2^q)
10986 // e = x.e + y.e + q
10987
10988 // Emulate the 64-bit * 64-bit multiplication:
10989 //
10990 // p = u * v
10991 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
10992 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
10993 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
10994 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
10995 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
10996 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
10997 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
10998 //
10999 // (Since Q might be larger than 2^32 - 1)
11000 //
11001 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
11002 //
11003 // (Q_hi + H does not overflow a 64-bit int)
11004 //
11005 // = p_lo + 2^64 p_hi
11006
11007 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
11008 const std::uint64_t u_hi = x.f >> 32u;
11009 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
11010 const std::uint64_t v_hi = y.f >> 32u;
11011
11012 const std::uint64_t p0 = u_lo * v_lo;
11013 const std::uint64_t p1 = u_lo * v_hi;
11014 const std::uint64_t p2 = u_hi * v_lo;
11015 const std::uint64_t p3 = u_hi * v_hi;
11016
11017 const std::uint64_t p0_hi = p0 >> 32u;
11018 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
11019 const std::uint64_t p1_hi = p1 >> 32u;
11020 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
11021 const std::uint64_t p2_hi = p2 >> 32u;
11022
11023 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
11024
11025 // The full product might now be computed as
11026 //
11027 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
11028 // p_lo = p0_lo + (Q << 32)
11029 //
11030 // But in this particular case here, the full p_lo is not required.
11031 // Effectively we only need to add the highest bit in p_lo to p_hi (and
11032 // Q_hi + 1 does not overflow).
11033
11034 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
11035
11036 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
11037
11038 return {h, x.e + y.e + 64};
11039 }
11040
11041 /*!
11042 @brief normalize x such that the significand is >= 2^(q-1)
11043 @pre x.f != 0
11044 */
normalizenlohmann::detail::dtoa_impl::diyfp11045 static diyfp normalize(diyfp x) noexcept
11046 {
11047 assert(x.f != 0);
11048
11049 while ((x.f >> 63u) == 0)
11050 {
11051 x.f <<= 1u;
11052 x.e--;
11053 }
11054
11055 return x;
11056 }
11057
11058 /*!
11059 @brief normalize x such that the result has the exponent E
11060 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
11061 */
normalize_tonlohmann::detail::dtoa_impl::diyfp11062 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
11063 {
11064 const int delta = x.e - target_exponent;
11065
11066 assert(delta >= 0);
11067 assert(((x.f << delta) >> delta) == x.f);
11068
11069 return {x.f << delta, target_exponent};
11070 }
11071 };
11072
11073 struct boundaries
11074 {
11075 diyfp w;
11076 diyfp minus;
11077 diyfp plus;
11078 };
11079
11080 /*!
11081 Compute the (normalized) diyfp representing the input number 'value' and its
11082 boundaries.
11083
11084 @pre value must be finite and positive
11085 */
11086 template <typename FloatType>
compute_boundaries(FloatType value)11087 boundaries compute_boundaries(FloatType value)
11088 {
11089 assert(std::isfinite(value));
11090 assert(value > 0);
11091
11092 // Convert the IEEE representation into a diyfp.
11093 //
11094 // If v is denormal:
11095 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
11096 // If v is normalized:
11097 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
11098
11099 static_assert(std::numeric_limits<FloatType>::is_iec559,
11100 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
11101
11102 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
11103 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
11104 constexpr int kMinExp = 1 - kBias;
11105 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
11106
11107 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
11108
11109 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
11110 const std::uint64_t E = bits >> (kPrecision - 1);
11111 const std::uint64_t F = bits & (kHiddenBit - 1);
11112
11113 const bool is_denormal = E == 0;
11114 const diyfp v = is_denormal
11115 ? diyfp(F, kMinExp)
11116 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
11117
11118 // Compute the boundaries m- and m+ of the floating-point value
11119 // v = f * 2^e.
11120 //
11121 // Determine v- and v+, the floating-point predecessor and successor if v,
11122 // respectively.
11123 //
11124 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
11125 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
11126 //
11127 // v+ = v + 2^e
11128 //
11129 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
11130 // between m- and m+ round to v, regardless of how the input rounding
11131 // algorithm breaks ties.
11132 //
11133 // ---+-------------+-------------+-------------+-------------+--- (A)
11134 // v- m- v m+ v+
11135 //
11136 // -----------------+------+------+-------------+-------------+--- (B)
11137 // v- m- v m+ v+
11138
11139 const bool lower_boundary_is_closer = F == 0 and E > 1;
11140 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
11141 const diyfp m_minus = lower_boundary_is_closer
11142 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
11143 : diyfp(2 * v.f - 1, v.e - 1); // (A)
11144
11145 // Determine the normalized w+ = m+.
11146 const diyfp w_plus = diyfp::normalize(m_plus);
11147
11148 // Determine w- = m- such that e_(w-) = e_(w+).
11149 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
11150
11151 return {diyfp::normalize(v), w_minus, w_plus};
11152 }
11153
11154 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
11155 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
11156 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
11157 //
11158 // alpha <= e = e_c + e_w + q <= gamma
11159 //
11160 // or
11161 //
11162 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
11163 // <= f_c * f_w * 2^gamma
11164 //
11165 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
11166 //
11167 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
11168 //
11169 // or
11170 //
11171 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
11172 //
11173 // The choice of (alpha,gamma) determines the size of the table and the form of
11174 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
11175 // in practice:
11176 //
11177 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
11178 // processed independently: An integral part p1, and a fractional part p2:
11179 //
11180 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
11181 // = (f div 2^-e) + (f mod 2^-e) * 2^e
11182 // = p1 + p2 * 2^e
11183 //
11184 // The conversion of p1 into decimal form requires a series of divisions and
11185 // modulos by (a power of) 10. These operations are faster for 32-bit than for
11186 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
11187 // achieved by choosing
11188 //
11189 // -e >= 32 or e <= -32 := gamma
11190 //
11191 // In order to convert the fractional part
11192 //
11193 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
11194 //
11195 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
11196 // d[-i] are extracted in order:
11197 //
11198 // (10 * p2) div 2^-e = d[-1]
11199 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
11200 //
11201 // The multiplication by 10 must not overflow. It is sufficient to choose
11202 //
11203 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
11204 //
11205 // Since p2 = f mod 2^-e < 2^-e,
11206 //
11207 // -e <= 60 or e >= -60 := alpha
11208
11209 constexpr int kAlpha = -60;
11210 constexpr int kGamma = -32;
11211
11212 struct cached_power // c = f * 2^e ~= 10^k
11213 {
11214 std::uint64_t f;
11215 int e;
11216 int k;
11217 };
11218
11219 /*!
11220 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
11221 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
11222 satisfies (Definition 3.2 from [1])
11223
11224 alpha <= e_c + e + q <= gamma.
11225 */
get_cached_power_for_binary_exponent(int e)11226 inline cached_power get_cached_power_for_binary_exponent(int e)
11227 {
11228 // Now
11229 //
11230 // alpha <= e_c + e + q <= gamma (1)
11231 // ==> f_c * 2^alpha <= c * 2^e * 2^q
11232 //
11233 // and since the c's are normalized, 2^(q-1) <= f_c,
11234 //
11235 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
11236 // ==> 2^(alpha - e - 1) <= c
11237 //
11238 // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
11239 //
11240 // k = ceil( log_10( 2^(alpha - e - 1) ) )
11241 // = ceil( (alpha - e - 1) * log_10(2) )
11242 //
11243 // From the paper:
11244 // "In theory the result of the procedure could be wrong since c is rounded,
11245 // and the computation itself is approximated [...]. In practice, however,
11246 // this simple function is sufficient."
11247 //
11248 // For IEEE double precision floating-point numbers converted into
11249 // normalized diyfp's w = f * 2^e, with q = 64,
11250 //
11251 // e >= -1022 (min IEEE exponent)
11252 // -52 (p - 1)
11253 // -52 (p - 1, possibly normalize denormal IEEE numbers)
11254 // -11 (normalize the diyfp)
11255 // = -1137
11256 //
11257 // and
11258 //
11259 // e <= +1023 (max IEEE exponent)
11260 // -52 (p - 1)
11261 // -11 (normalize the diyfp)
11262 // = 960
11263 //
11264 // This binary exponent range [-1137,960] results in a decimal exponent
11265 // range [-307,324]. One does not need to store a cached power for each
11266 // k in this range. For each such k it suffices to find a cached power
11267 // such that the exponent of the product lies in [alpha,gamma].
11268 // This implies that the difference of the decimal exponents of adjacent
11269 // table entries must be less than or equal to
11270 //
11271 // floor( (gamma - alpha) * log_10(2) ) = 8.
11272 //
11273 // (A smaller distance gamma-alpha would require a larger table.)
11274
11275 // NB:
11276 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
11277
11278 constexpr int kCachedPowersMinDecExp = -300;
11279 constexpr int kCachedPowersDecStep = 8;
11280
11281 static constexpr std::array<cached_power, 79> kCachedPowers =
11282 {
11283 {
11284 { 0xAB70FE17C79AC6CA, -1060, -300 },
11285 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
11286 { 0xBE5691EF416BD60C, -1007, -284 },
11287 { 0x8DD01FAD907FFC3C, -980, -276 },
11288 { 0xD3515C2831559A83, -954, -268 },
11289 { 0x9D71AC8FADA6C9B5, -927, -260 },
11290 { 0xEA9C227723EE8BCB, -901, -252 },
11291 { 0xAECC49914078536D, -874, -244 },
11292 { 0x823C12795DB6CE57, -847, -236 },
11293 { 0xC21094364DFB5637, -821, -228 },
11294 { 0x9096EA6F3848984F, -794, -220 },
11295 { 0xD77485CB25823AC7, -768, -212 },
11296 { 0xA086CFCD97BF97F4, -741, -204 },
11297 { 0xEF340A98172AACE5, -715, -196 },
11298 { 0xB23867FB2A35B28E, -688, -188 },
11299 { 0x84C8D4DFD2C63F3B, -661, -180 },
11300 { 0xC5DD44271AD3CDBA, -635, -172 },
11301 { 0x936B9FCEBB25C996, -608, -164 },
11302 { 0xDBAC6C247D62A584, -582, -156 },
11303 { 0xA3AB66580D5FDAF6, -555, -148 },
11304 { 0xF3E2F893DEC3F126, -529, -140 },
11305 { 0xB5B5ADA8AAFF80B8, -502, -132 },
11306 { 0x87625F056C7C4A8B, -475, -124 },
11307 { 0xC9BCFF6034C13053, -449, -116 },
11308 { 0x964E858C91BA2655, -422, -108 },
11309 { 0xDFF9772470297EBD, -396, -100 },
11310 { 0xA6DFBD9FB8E5B88F, -369, -92 },
11311 { 0xF8A95FCF88747D94, -343, -84 },
11312 { 0xB94470938FA89BCF, -316, -76 },
11313 { 0x8A08F0F8BF0F156B, -289, -68 },
11314 { 0xCDB02555653131B6, -263, -60 },
11315 { 0x993FE2C6D07B7FAC, -236, -52 },
11316 { 0xE45C10C42A2B3B06, -210, -44 },
11317 { 0xAA242499697392D3, -183, -36 },
11318 { 0xFD87B5F28300CA0E, -157, -28 },
11319 { 0xBCE5086492111AEB, -130, -20 },
11320 { 0x8CBCCC096F5088CC, -103, -12 },
11321 { 0xD1B71758E219652C, -77, -4 },
11322 { 0x9C40000000000000, -50, 4 },
11323 { 0xE8D4A51000000000, -24, 12 },
11324 { 0xAD78EBC5AC620000, 3, 20 },
11325 { 0x813F3978F8940984, 30, 28 },
11326 { 0xC097CE7BC90715B3, 56, 36 },
11327 { 0x8F7E32CE7BEA5C70, 83, 44 },
11328 { 0xD5D238A4ABE98068, 109, 52 },
11329 { 0x9F4F2726179A2245, 136, 60 },
11330 { 0xED63A231D4C4FB27, 162, 68 },
11331 { 0xB0DE65388CC8ADA8, 189, 76 },
11332 { 0x83C7088E1AAB65DB, 216, 84 },
11333 { 0xC45D1DF942711D9A, 242, 92 },
11334 { 0x924D692CA61BE758, 269, 100 },
11335 { 0xDA01EE641A708DEA, 295, 108 },
11336 { 0xA26DA3999AEF774A, 322, 116 },
11337 { 0xF209787BB47D6B85, 348, 124 },
11338 { 0xB454E4A179DD1877, 375, 132 },
11339 { 0x865B86925B9BC5C2, 402, 140 },
11340 { 0xC83553C5C8965D3D, 428, 148 },
11341 { 0x952AB45CFA97A0B3, 455, 156 },
11342 { 0xDE469FBD99A05FE3, 481, 164 },
11343 { 0xA59BC234DB398C25, 508, 172 },
11344 { 0xF6C69A72A3989F5C, 534, 180 },
11345 { 0xB7DCBF5354E9BECE, 561, 188 },
11346 { 0x88FCF317F22241E2, 588, 196 },
11347 { 0xCC20CE9BD35C78A5, 614, 204 },
11348 { 0x98165AF37B2153DF, 641, 212 },
11349 { 0xE2A0B5DC971F303A, 667, 220 },
11350 { 0xA8D9D1535CE3B396, 694, 228 },
11351 { 0xFB9B7CD9A4A7443C, 720, 236 },
11352 { 0xBB764C4CA7A44410, 747, 244 },
11353 { 0x8BAB8EEFB6409C1A, 774, 252 },
11354 { 0xD01FEF10A657842C, 800, 260 },
11355 { 0x9B10A4E5E9913129, 827, 268 },
11356 { 0xE7109BFBA19C0C9D, 853, 276 },
11357 { 0xAC2820D9623BF429, 880, 284 },
11358 { 0x80444B5E7AA7CF85, 907, 292 },
11359 { 0xBF21E44003ACDD2D, 933, 300 },
11360 { 0x8E679C2F5E44FF8F, 960, 308 },
11361 { 0xD433179D9C8CB841, 986, 316 },
11362 { 0x9E19DB92B4E31BA9, 1013, 324 },
11363 }
11364 };
11365
11366 // This computation gives exactly the same results for k as
11367 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
11368 // for |e| <= 1500, but doesn't require floating-point operations.
11369 // NB: log_10(2) ~= 78913 / 2^18
11370 assert(e >= -1500);
11371 assert(e <= 1500);
11372 const int f = kAlpha - e - 1;
11373 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
11374
11375 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
11376 assert(index >= 0);
11377 assert(static_cast<std::size_t>(index) < kCachedPowers.size());
11378
11379 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
11380 assert(kAlpha <= cached.e + e + 64);
11381 assert(kGamma >= cached.e + e + 64);
11382
11383 return cached;
11384 }
11385
11386 /*!
11387 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
11388 For n == 0, returns 1 and sets pow10 := 1.
11389 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)11390 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
11391 {
11392 // LCOV_EXCL_START
11393 if (n >= 1000000000)
11394 {
11395 pow10 = 1000000000;
11396 return 10;
11397 }
11398 // LCOV_EXCL_STOP
11399 else if (n >= 100000000)
11400 {
11401 pow10 = 100000000;
11402 return 9;
11403 }
11404 else if (n >= 10000000)
11405 {
11406 pow10 = 10000000;
11407 return 8;
11408 }
11409 else if (n >= 1000000)
11410 {
11411 pow10 = 1000000;
11412 return 7;
11413 }
11414 else if (n >= 100000)
11415 {
11416 pow10 = 100000;
11417 return 6;
11418 }
11419 else if (n >= 10000)
11420 {
11421 pow10 = 10000;
11422 return 5;
11423 }
11424 else if (n >= 1000)
11425 {
11426 pow10 = 1000;
11427 return 4;
11428 }
11429 else if (n >= 100)
11430 {
11431 pow10 = 100;
11432 return 3;
11433 }
11434 else if (n >= 10)
11435 {
11436 pow10 = 10;
11437 return 2;
11438 }
11439 else
11440 {
11441 pow10 = 1;
11442 return 1;
11443 }
11444 }
11445
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)11446 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
11447 std::uint64_t rest, std::uint64_t ten_k)
11448 {
11449 assert(len >= 1);
11450 assert(dist <= delta);
11451 assert(rest <= delta);
11452 assert(ten_k > 0);
11453
11454 // <--------------------------- delta ---->
11455 // <---- dist --------->
11456 // --------------[------------------+-------------------]--------------
11457 // M- w M+
11458 //
11459 // ten_k
11460 // <------>
11461 // <---- rest ---->
11462 // --------------[------------------+----+--------------]--------------
11463 // w V
11464 // = buf * 10^k
11465 //
11466 // ten_k represents a unit-in-the-last-place in the decimal representation
11467 // stored in buf.
11468 // Decrement buf by ten_k while this takes buf closer to w.
11469
11470 // The tests are written in this order to avoid overflow in unsigned
11471 // integer arithmetic.
11472
11473 while (rest < dist
11474 and delta - rest >= ten_k
11475 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
11476 {
11477 assert(buf[len - 1] != '0');
11478 buf[len - 1]--;
11479 rest += ten_k;
11480 }
11481 }
11482
11483 /*!
11484 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
11485 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
11486 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)11487 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
11488 diyfp M_minus, diyfp w, diyfp M_plus)
11489 {
11490 static_assert(kAlpha >= -60, "internal error");
11491 static_assert(kGamma <= -32, "internal error");
11492
11493 // Generates the digits (and the exponent) of a decimal floating-point
11494 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
11495 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
11496 //
11497 // <--------------------------- delta ---->
11498 // <---- dist --------->
11499 // --------------[------------------+-------------------]--------------
11500 // M- w M+
11501 //
11502 // Grisu2 generates the digits of M+ from left to right and stops as soon as
11503 // V is in [M-,M+].
11504
11505 assert(M_plus.e >= kAlpha);
11506 assert(M_plus.e <= kGamma);
11507
11508 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
11509 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
11510
11511 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
11512 //
11513 // M+ = f * 2^e
11514 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
11515 // = ((p1 ) * 2^-e + (p2 )) * 2^e
11516 // = p1 + p2 * 2^e
11517
11518 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
11519
11520 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.)
11521 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
11522
11523 // 1)
11524 //
11525 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
11526
11527 assert(p1 > 0);
11528
11529 std::uint32_t pow10;
11530 const int k = find_largest_pow10(p1, pow10);
11531
11532 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
11533 //
11534 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
11535 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
11536 //
11537 // M+ = p1 + p2 * 2^e
11538 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
11539 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
11540 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
11541 //
11542 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
11543 //
11544 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
11545 //
11546 // but stop as soon as
11547 //
11548 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
11549
11550 int n = k;
11551 while (n > 0)
11552 {
11553 // Invariants:
11554 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
11555 // pow10 = 10^(n-1) <= p1 < 10^n
11556 //
11557 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
11558 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
11559 //
11560 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
11561 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
11562 //
11563 assert(d <= 9);
11564 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11565 //
11566 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
11567 //
11568 p1 = r;
11569 n--;
11570 //
11571 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
11572 // pow10 = 10^n
11573 //
11574
11575 // Now check if enough digits have been generated.
11576 // Compute
11577 //
11578 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
11579 //
11580 // Note:
11581 // Since rest and delta share the same exponent e, it suffices to
11582 // compare the significands.
11583 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
11584 if (rest <= delta)
11585 {
11586 // V = buffer * 10^n, with M- <= V <= M+.
11587
11588 decimal_exponent += n;
11589
11590 // We may now just stop. But instead look if the buffer could be
11591 // decremented to bring V closer to w.
11592 //
11593 // pow10 = 10^n is now 1 ulp in the decimal representation V.
11594 // The rounding procedure works with diyfp's with an implicit
11595 // exponent of e.
11596 //
11597 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
11598 //
11599 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
11600 grisu2_round(buffer, length, dist, delta, rest, ten_n);
11601
11602 return;
11603 }
11604
11605 pow10 /= 10;
11606 //
11607 // pow10 = 10^(n-1) <= p1 < 10^n
11608 // Invariants restored.
11609 }
11610
11611 // 2)
11612 //
11613 // The digits of the integral part have been generated:
11614 //
11615 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
11616 // = buffer + p2 * 2^e
11617 //
11618 // Now generate the digits of the fractional part p2 * 2^e.
11619 //
11620 // Note:
11621 // No decimal point is generated: the exponent is adjusted instead.
11622 //
11623 // p2 actually represents the fraction
11624 //
11625 // p2 * 2^e
11626 // = p2 / 2^-e
11627 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
11628 //
11629 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
11630 //
11631 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
11632 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
11633 //
11634 // using
11635 //
11636 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
11637 // = ( d) * 2^-e + ( r)
11638 //
11639 // or
11640 // 10^m * p2 * 2^e = d + r * 2^e
11641 //
11642 // i.e.
11643 //
11644 // M+ = buffer + p2 * 2^e
11645 // = buffer + 10^-m * (d + r * 2^e)
11646 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
11647 //
11648 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
11649
11650 assert(p2 > delta);
11651
11652 int m = 0;
11653 for (;;)
11654 {
11655 // Invariant:
11656 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
11657 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
11658 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
11659 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
11660 //
11661 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
11662 p2 *= 10;
11663 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
11664 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
11665 //
11666 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
11667 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
11668 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
11669 //
11670 assert(d <= 9);
11671 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11672 //
11673 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
11674 //
11675 p2 = r;
11676 m++;
11677 //
11678 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
11679 // Invariant restored.
11680
11681 // Check if enough digits have been generated.
11682 //
11683 // 10^-m * p2 * 2^e <= delta * 2^e
11684 // p2 * 2^e <= 10^m * delta * 2^e
11685 // p2 <= 10^m * delta
11686 delta *= 10;
11687 dist *= 10;
11688 if (p2 <= delta)
11689 {
11690 break;
11691 }
11692 }
11693
11694 // V = buffer * 10^-m, with M- <= V <= M+.
11695
11696 decimal_exponent -= m;
11697
11698 // 1 ulp in the decimal representation is now 10^-m.
11699 // Since delta and dist are now scaled by 10^m, we need to do the
11700 // same with ulp in order to keep the units in sync.
11701 //
11702 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
11703 //
11704 const std::uint64_t ten_m = one.f;
11705 grisu2_round(buffer, length, dist, delta, p2, ten_m);
11706
11707 // By construction this algorithm generates the shortest possible decimal
11708 // number (Loitsch, Theorem 6.2) which rounds back to w.
11709 // For an input number of precision p, at least
11710 //
11711 // N = 1 + ceil(p * log_10(2))
11712 //
11713 // decimal digits are sufficient to identify all binary floating-point
11714 // numbers (Matula, "In-and-Out conversions").
11715 // This implies that the algorithm does not produce more than N decimal
11716 // digits.
11717 //
11718 // N = 17 for p = 53 (IEEE double precision)
11719 // N = 9 for p = 24 (IEEE single precision)
11720 }
11721
11722 /*!
11723 v = buf * 10^decimal_exponent
11724 len is the length of the buffer (number of decimal digits)
11725 The buffer must be large enough, i.e. >= max_digits10.
11726 */
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)11727 inline void grisu2(char* buf, int& len, int& decimal_exponent,
11728 diyfp m_minus, diyfp v, diyfp m_plus)
11729 {
11730 assert(m_plus.e == m_minus.e);
11731 assert(m_plus.e == v.e);
11732
11733 // --------(-----------------------+-----------------------)-------- (A)
11734 // m- v m+
11735 //
11736 // --------------------(-----------+-----------------------)-------- (B)
11737 // m- v m+
11738 //
11739 // First scale v (and m- and m+) such that the exponent is in the range
11740 // [alpha, gamma].
11741
11742 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
11743
11744 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
11745
11746 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
11747 const diyfp w = diyfp::mul(v, c_minus_k);
11748 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
11749 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
11750
11751 // ----(---+---)---------------(---+---)---------------(---+---)----
11752 // w- w w+
11753 // = c*m- = c*v = c*m+
11754 //
11755 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
11756 // w+ are now off by a small amount.
11757 // In fact:
11758 //
11759 // w - v * 10^k < 1 ulp
11760 //
11761 // To account for this inaccuracy, add resp. subtract 1 ulp.
11762 //
11763 // --------+---[---------------(---+---)---------------]---+--------
11764 // w- M- w M+ w+
11765 //
11766 // Now any number in [M-, M+] (bounds included) will round to w when input,
11767 // regardless of how the input rounding algorithm breaks ties.
11768 //
11769 // And digit_gen generates the shortest possible such number in [M-, M+].
11770 // Note that this does not mean that Grisu2 always generates the shortest
11771 // possible number in the interval (m-, m+).
11772 const diyfp M_minus(w_minus.f + 1, w_minus.e);
11773 const diyfp M_plus (w_plus.f - 1, w_plus.e );
11774
11775 decimal_exponent = -cached.k; // = -(-k) = k
11776
11777 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
11778 }
11779
11780 /*!
11781 v = buf * 10^decimal_exponent
11782 len is the length of the buffer (number of decimal digits)
11783 The buffer must be large enough, i.e. >= max_digits10.
11784 */
11785 template <typename FloatType>
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)11786 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
11787 {
11788 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
11789 "internal error: not enough precision");
11790
11791 assert(std::isfinite(value));
11792 assert(value > 0);
11793
11794 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
11795 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
11796 // decimal representations are not exactly "short".
11797 //
11798 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
11799 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
11800 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
11801 // does.
11802 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
11803 // representation using the corresponding std::from_chars function recovers value exactly". That
11804 // indicates that single precision floating-point numbers should be recovered using
11805 // 'std::strtof'.
11806 //
11807 // NB: If the neighbors are computed for single-precision numbers, there is a single float
11808 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
11809 // value is off by 1 ulp.
11810 #if 0
11811 const boundaries w = compute_boundaries(static_cast<double>(value));
11812 #else
11813 const boundaries w = compute_boundaries(value);
11814 #endif
11815
11816 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
11817 }
11818
11819 /*!
11820 @brief appends a decimal representation of e to buf
11821 @return a pointer to the element following the exponent.
11822 @pre -1000 < e < 1000
11823 */
append_exponent(char * buf,int e)11824 inline char* append_exponent(char* buf, int e)
11825 {
11826 assert(e > -1000);
11827 assert(e < 1000);
11828
11829 if (e < 0)
11830 {
11831 e = -e;
11832 *buf++ = '-';
11833 }
11834 else
11835 {
11836 *buf++ = '+';
11837 }
11838
11839 auto k = static_cast<std::uint32_t>(e);
11840 if (k < 10)
11841 {
11842 // Always print at least two digits in the exponent.
11843 // This is for compatibility with printf("%g").
11844 *buf++ = '0';
11845 *buf++ = static_cast<char>('0' + k);
11846 }
11847 else if (k < 100)
11848 {
11849 *buf++ = static_cast<char>('0' + k / 10);
11850 k %= 10;
11851 *buf++ = static_cast<char>('0' + k);
11852 }
11853 else
11854 {
11855 *buf++ = static_cast<char>('0' + k / 100);
11856 k %= 100;
11857 *buf++ = static_cast<char>('0' + k / 10);
11858 k %= 10;
11859 *buf++ = static_cast<char>('0' + k);
11860 }
11861
11862 return buf;
11863 }
11864
11865 /*!
11866 @brief prettify v = buf * 10^decimal_exponent
11867
11868 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
11869 notation. Otherwise it will be printed in exponential notation.
11870
11871 @pre min_exp < 0
11872 @pre max_exp > 0
11873 */
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)11874 inline char* format_buffer(char* buf, int len, int decimal_exponent,
11875 int min_exp, int max_exp)
11876 {
11877 assert(min_exp < 0);
11878 assert(max_exp > 0);
11879
11880 const int k = len;
11881 const int n = len + decimal_exponent;
11882
11883 // v = buf * 10^(n-k)
11884 // k is the length of the buffer (number of decimal digits)
11885 // n is the position of the decimal point relative to the start of the buffer.
11886
11887 if (k <= n and n <= max_exp)
11888 {
11889 // digits[000]
11890 // len <= max_exp + 2
11891
11892 std::memset(buf + k, '0', static_cast<size_t>(n - k));
11893 // Make it look like a floating-point number (#362, #378)
11894 buf[n + 0] = '.';
11895 buf[n + 1] = '0';
11896 return buf + (n + 2);
11897 }
11898
11899 if (0 < n and n <= max_exp)
11900 {
11901 // dig.its
11902 // len <= max_digits10 + 1
11903
11904 assert(k > n);
11905
11906 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
11907 buf[n] = '.';
11908 return buf + (k + 1);
11909 }
11910
11911 if (min_exp < n and n <= 0)
11912 {
11913 // 0.[000]digits
11914 // len <= 2 + (-min_exp - 1) + max_digits10
11915
11916 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
11917 buf[0] = '0';
11918 buf[1] = '.';
11919 std::memset(buf + 2, '0', static_cast<size_t>(-n));
11920 return buf + (2 + (-n) + k);
11921 }
11922
11923 if (k == 1)
11924 {
11925 // dE+123
11926 // len <= 1 + 5
11927
11928 buf += 1;
11929 }
11930 else
11931 {
11932 // d.igitsE+123
11933 // len <= max_digits10 + 1 + 5
11934
11935 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
11936 buf[1] = '.';
11937 buf += 1 + k;
11938 }
11939
11940 *buf++ = 'e';
11941 return append_exponent(buf, n - 1);
11942 }
11943
11944 } // namespace dtoa_impl
11945
11946 /*!
11947 @brief generates a decimal representation of the floating-point number value in [first, last).
11948
11949 The format of the resulting decimal representation is similar to printf's %g
11950 format. Returns an iterator pointing past-the-end of the decimal representation.
11951
11952 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
11953 @note The buffer must be large enough.
11954 @note The result is NOT null-terminated.
11955 */
11956 template <typename FloatType>
to_chars(char * first,const char * last,FloatType value)11957 char* to_chars(char* first, const char* last, FloatType value)
11958 {
11959 static_cast<void>(last); // maybe unused - fix warning
11960 assert(std::isfinite(value));
11961
11962 // Use signbit(value) instead of (value < 0) since signbit works for -0.
11963 if (std::signbit(value))
11964 {
11965 value = -value;
11966 *first++ = '-';
11967 }
11968
11969 if (value == 0) // +-0
11970 {
11971 *first++ = '0';
11972 // Make it look like a floating-point number (#362, #378)
11973 *first++ = '.';
11974 *first++ = '0';
11975 return first;
11976 }
11977
11978 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
11979
11980 // Compute v = buffer * 10^decimal_exponent.
11981 // The decimal digits are stored in the buffer, which needs to be interpreted
11982 // as an unsigned decimal integer.
11983 // len is the length of the buffer, i.e. the number of decimal digits.
11984 int len = 0;
11985 int decimal_exponent = 0;
11986 dtoa_impl::grisu2(first, len, decimal_exponent, value);
11987
11988 assert(len <= std::numeric_limits<FloatType>::max_digits10);
11989
11990 // Format the buffer like printf("%.*g", prec, value)
11991 constexpr int kMinExp = -4;
11992 // Use digits10 here to increase compatibility with version 2.
11993 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
11994
11995 assert(last - first >= kMaxExp + 2);
11996 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
11997 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
11998
11999 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
12000 }
12001
12002 } // namespace detail
12003 } // namespace nlohmann
12004
12005 // #include <nlohmann/detail/exceptions.hpp>
12006
12007 // #include <nlohmann/detail/macro_scope.hpp>
12008
12009 // #include <nlohmann/detail/meta/cpp_future.hpp>
12010
12011 // #include <nlohmann/detail/output/binary_writer.hpp>
12012
12013 // #include <nlohmann/detail/output/output_adapters.hpp>
12014
12015 // #include <nlohmann/detail/value_t.hpp>
12016
12017
12018 namespace nlohmann
12019 {
12020 namespace detail
12021 {
12022 ///////////////////
12023 // serialization //
12024 ///////////////////
12025
12026 /// how to treat decoding errors
12027 enum class error_handler_t
12028 {
12029 strict, ///< throw a type_error exception in case of invalid UTF-8
12030 replace, ///< replace invalid UTF-8 sequences with U+FFFD
12031 ignore ///< ignore invalid UTF-8 sequences
12032 };
12033
12034 template<typename BasicJsonType>
12035 class serializer
12036 {
12037 using string_t = typename BasicJsonType::string_t;
12038 using number_float_t = typename BasicJsonType::number_float_t;
12039 using number_integer_t = typename BasicJsonType::number_integer_t;
12040 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12041 static constexpr std::uint8_t UTF8_ACCEPT = 0;
12042 static constexpr std::uint8_t UTF8_REJECT = 1;
12043
12044 public:
12045 /*!
12046 @param[in] s output stream to serialize to
12047 @param[in] ichar indentation character to use
12048 @param[in] error_handler_ how to react on decoding errors
12049 */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)12050 serializer(output_adapter_t<char> s, const char ichar,
12051 error_handler_t error_handler_ = error_handler_t::strict)
12052 : o(std::move(s))
12053 , loc(std::localeconv())
12054 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
12055 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
12056 , indent_char(ichar)
12057 , indent_string(512, indent_char)
12058 , error_handler(error_handler_)
12059 {}
12060
12061 // delete because of pointer members
12062 serializer(const serializer&) = delete;
12063 serializer& operator=(const serializer&) = delete;
12064 serializer(serializer&&) = delete;
12065 serializer& operator=(serializer&&) = delete;
12066 ~serializer() = default;
12067
12068 /*!
12069 @brief internal implementation of the serialization function
12070
12071 This function is called by the public member function dump and organizes
12072 the serialization internally. The indentation level is propagated as
12073 additional parameter. In case of arrays and objects, the function is
12074 called recursively.
12075
12076 - strings and object keys are escaped using `escape_string()`
12077 - integer numbers are converted implicitly via `operator<<`
12078 - floating-point numbers are converted to a string using `"%g"` format
12079
12080 @param[in] val value to serialize
12081 @param[in] pretty_print whether the output shall be pretty-printed
12082 @param[in] indent_step the indent level
12083 @param[in] current_indent the current indent level (only used internally)
12084 */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)12085 void dump(const BasicJsonType& val, const bool pretty_print,
12086 const bool ensure_ascii,
12087 const unsigned int indent_step,
12088 const unsigned int current_indent = 0)
12089 {
12090 switch (val.m_type)
12091 {
12092 case value_t::object:
12093 {
12094 if (val.m_value.object->empty())
12095 {
12096 o->write_characters("{}", 2);
12097 return;
12098 }
12099
12100 if (pretty_print)
12101 {
12102 o->write_characters("{\n", 2);
12103
12104 // variable to hold indentation for recursive calls
12105 const auto new_indent = current_indent + indent_step;
12106 if (JSON_UNLIKELY(indent_string.size() < new_indent))
12107 {
12108 indent_string.resize(indent_string.size() * 2, ' ');
12109 }
12110
12111 // first n-1 elements
12112 auto i = val.m_value.object->cbegin();
12113 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12114 {
12115 o->write_characters(indent_string.c_str(), new_indent);
12116 o->write_character('\"');
12117 dump_escaped(i->first, ensure_ascii);
12118 o->write_characters("\": ", 3);
12119 dump(i->second, true, ensure_ascii, indent_step, new_indent);
12120 o->write_characters(",\n", 2);
12121 }
12122
12123 // last element
12124 assert(i != val.m_value.object->cend());
12125 assert(std::next(i) == val.m_value.object->cend());
12126 o->write_characters(indent_string.c_str(), new_indent);
12127 o->write_character('\"');
12128 dump_escaped(i->first, ensure_ascii);
12129 o->write_characters("\": ", 3);
12130 dump(i->second, true, ensure_ascii, indent_step, new_indent);
12131
12132 o->write_character('\n');
12133 o->write_characters(indent_string.c_str(), current_indent);
12134 o->write_character('}');
12135 }
12136 else
12137 {
12138 o->write_character('{');
12139
12140 // first n-1 elements
12141 auto i = val.m_value.object->cbegin();
12142 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12143 {
12144 o->write_character('\"');
12145 dump_escaped(i->first, ensure_ascii);
12146 o->write_characters("\":", 2);
12147 dump(i->second, false, ensure_ascii, indent_step, current_indent);
12148 o->write_character(',');
12149 }
12150
12151 // last element
12152 assert(i != val.m_value.object->cend());
12153 assert(std::next(i) == val.m_value.object->cend());
12154 o->write_character('\"');
12155 dump_escaped(i->first, ensure_ascii);
12156 o->write_characters("\":", 2);
12157 dump(i->second, false, ensure_ascii, indent_step, current_indent);
12158
12159 o->write_character('}');
12160 }
12161
12162 return;
12163 }
12164
12165 case value_t::array:
12166 {
12167 if (val.m_value.array->empty())
12168 {
12169 o->write_characters("[]", 2);
12170 return;
12171 }
12172
12173 if (pretty_print)
12174 {
12175 o->write_characters("[\n", 2);
12176
12177 // variable to hold indentation for recursive calls
12178 const auto new_indent = current_indent + indent_step;
12179 if (JSON_UNLIKELY(indent_string.size() < new_indent))
12180 {
12181 indent_string.resize(indent_string.size() * 2, ' ');
12182 }
12183
12184 // first n-1 elements
12185 for (auto i = val.m_value.array->cbegin();
12186 i != val.m_value.array->cend() - 1; ++i)
12187 {
12188 o->write_characters(indent_string.c_str(), new_indent);
12189 dump(*i, true, ensure_ascii, indent_step, new_indent);
12190 o->write_characters(",\n", 2);
12191 }
12192
12193 // last element
12194 assert(not val.m_value.array->empty());
12195 o->write_characters(indent_string.c_str(), new_indent);
12196 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
12197
12198 o->write_character('\n');
12199 o->write_characters(indent_string.c_str(), current_indent);
12200 o->write_character(']');
12201 }
12202 else
12203 {
12204 o->write_character('[');
12205
12206 // first n-1 elements
12207 for (auto i = val.m_value.array->cbegin();
12208 i != val.m_value.array->cend() - 1; ++i)
12209 {
12210 dump(*i, false, ensure_ascii, indent_step, current_indent);
12211 o->write_character(',');
12212 }
12213
12214 // last element
12215 assert(not val.m_value.array->empty());
12216 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
12217
12218 o->write_character(']');
12219 }
12220
12221 return;
12222 }
12223
12224 case value_t::string:
12225 {
12226 o->write_character('\"');
12227 dump_escaped(*val.m_value.string, ensure_ascii);
12228 o->write_character('\"');
12229 return;
12230 }
12231
12232 case value_t::boolean:
12233 {
12234 if (val.m_value.boolean)
12235 {
12236 o->write_characters("true", 4);
12237 }
12238 else
12239 {
12240 o->write_characters("false", 5);
12241 }
12242 return;
12243 }
12244
12245 case value_t::number_integer:
12246 {
12247 dump_integer(val.m_value.number_integer);
12248 return;
12249 }
12250
12251 case value_t::number_unsigned:
12252 {
12253 dump_integer(val.m_value.number_unsigned);
12254 return;
12255 }
12256
12257 case value_t::number_float:
12258 {
12259 dump_float(val.m_value.number_float);
12260 return;
12261 }
12262
12263 case value_t::discarded:
12264 {
12265 o->write_characters("<discarded>", 11);
12266 return;
12267 }
12268
12269 case value_t::null:
12270 {
12271 o->write_characters("null", 4);
12272 return;
12273 }
12274
12275 default: // LCOV_EXCL_LINE
12276 assert(false); // LCOV_EXCL_LINE
12277 }
12278 }
12279
12280 private:
12281 /*!
12282 @brief dump escaped string
12283
12284 Escape a string by replacing certain special characters by a sequence of an
12285 escape character (backslash) and another character and other control
12286 characters by a sequence of "\u" followed by a four-digit hex
12287 representation. The escaped string is written to output stream @a o.
12288
12289 @param[in] s the string to escape
12290 @param[in] ensure_ascii whether to escape non-ASCII characters with
12291 \uXXXX sequences
12292
12293 @complexity Linear in the length of string @a s.
12294 */
dump_escaped(const string_t & s,const bool ensure_ascii)12295 void dump_escaped(const string_t& s, const bool ensure_ascii)
12296 {
12297 std::uint32_t codepoint;
12298 std::uint8_t state = UTF8_ACCEPT;
12299 std::size_t bytes = 0; // number of bytes written to string_buffer
12300
12301 // number of bytes written at the point of the last valid byte
12302 std::size_t bytes_after_last_accept = 0;
12303 std::size_t undumped_chars = 0;
12304
12305 for (std::size_t i = 0; i < s.size(); ++i)
12306 {
12307 const auto byte = static_cast<uint8_t>(s[i]);
12308
12309 switch (decode(state, codepoint, byte))
12310 {
12311 case UTF8_ACCEPT: // decode found a new code point
12312 {
12313 switch (codepoint)
12314 {
12315 case 0x08: // backspace
12316 {
12317 string_buffer[bytes++] = '\\';
12318 string_buffer[bytes++] = 'b';
12319 break;
12320 }
12321
12322 case 0x09: // horizontal tab
12323 {
12324 string_buffer[bytes++] = '\\';
12325 string_buffer[bytes++] = 't';
12326 break;
12327 }
12328
12329 case 0x0A: // newline
12330 {
12331 string_buffer[bytes++] = '\\';
12332 string_buffer[bytes++] = 'n';
12333 break;
12334 }
12335
12336 case 0x0C: // formfeed
12337 {
12338 string_buffer[bytes++] = '\\';
12339 string_buffer[bytes++] = 'f';
12340 break;
12341 }
12342
12343 case 0x0D: // carriage return
12344 {
12345 string_buffer[bytes++] = '\\';
12346 string_buffer[bytes++] = 'r';
12347 break;
12348 }
12349
12350 case 0x22: // quotation mark
12351 {
12352 string_buffer[bytes++] = '\\';
12353 string_buffer[bytes++] = '\"';
12354 break;
12355 }
12356
12357 case 0x5C: // reverse solidus
12358 {
12359 string_buffer[bytes++] = '\\';
12360 string_buffer[bytes++] = '\\';
12361 break;
12362 }
12363
12364 default:
12365 {
12366 // escape control characters (0x00..0x1F) or, if
12367 // ensure_ascii parameter is used, non-ASCII characters
12368 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
12369 {
12370 if (codepoint <= 0xFFFF)
12371 {
12372 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
12373 static_cast<std::uint16_t>(codepoint));
12374 bytes += 6;
12375 }
12376 else
12377 {
12378 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
12379 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
12380 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
12381 bytes += 12;
12382 }
12383 }
12384 else
12385 {
12386 // copy byte to buffer (all previous bytes
12387 // been copied have in default case above)
12388 string_buffer[bytes++] = s[i];
12389 }
12390 break;
12391 }
12392 }
12393
12394 // write buffer and reset index; there must be 13 bytes
12395 // left, as this is the maximal number of bytes to be
12396 // written ("\uxxxx\uxxxx\0") for one code point
12397 if (string_buffer.size() - bytes < 13)
12398 {
12399 o->write_characters(string_buffer.data(), bytes);
12400 bytes = 0;
12401 }
12402
12403 // remember the byte position of this accept
12404 bytes_after_last_accept = bytes;
12405 undumped_chars = 0;
12406 break;
12407 }
12408
12409 case UTF8_REJECT: // decode found invalid UTF-8 byte
12410 {
12411 switch (error_handler)
12412 {
12413 case error_handler_t::strict:
12414 {
12415 std::string sn(3, '\0');
12416 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
12417 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
12418 }
12419
12420 case error_handler_t::ignore:
12421 case error_handler_t::replace:
12422 {
12423 // in case we saw this character the first time, we
12424 // would like to read it again, because the byte
12425 // may be OK for itself, but just not OK for the
12426 // previous sequence
12427 if (undumped_chars > 0)
12428 {
12429 --i;
12430 }
12431
12432 // reset length buffer to the last accepted index;
12433 // thus removing/ignoring the invalid characters
12434 bytes = bytes_after_last_accept;
12435
12436 if (error_handler == error_handler_t::replace)
12437 {
12438 // add a replacement character
12439 if (ensure_ascii)
12440 {
12441 string_buffer[bytes++] = '\\';
12442 string_buffer[bytes++] = 'u';
12443 string_buffer[bytes++] = 'f';
12444 string_buffer[bytes++] = 'f';
12445 string_buffer[bytes++] = 'f';
12446 string_buffer[bytes++] = 'd';
12447 }
12448 else
12449 {
12450 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
12451 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
12452 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
12453 }
12454
12455 // write buffer and reset index; there must be 13 bytes
12456 // left, as this is the maximal number of bytes to be
12457 // written ("\uxxxx\uxxxx\0") for one code point
12458 if (string_buffer.size() - bytes < 13)
12459 {
12460 o->write_characters(string_buffer.data(), bytes);
12461 bytes = 0;
12462 }
12463
12464 bytes_after_last_accept = bytes;
12465 }
12466
12467 undumped_chars = 0;
12468
12469 // continue processing the string
12470 state = UTF8_ACCEPT;
12471 break;
12472 }
12473
12474 default: // LCOV_EXCL_LINE
12475 assert(false); // LCOV_EXCL_LINE
12476 }
12477 break;
12478 }
12479
12480 default: // decode found yet incomplete multi-byte code point
12481 {
12482 if (not ensure_ascii)
12483 {
12484 // code point will not be escaped - copy byte to buffer
12485 string_buffer[bytes++] = s[i];
12486 }
12487 ++undumped_chars;
12488 break;
12489 }
12490 }
12491 }
12492
12493 // we finished processing the string
12494 if (JSON_LIKELY(state == UTF8_ACCEPT))
12495 {
12496 // write buffer
12497 if (bytes > 0)
12498 {
12499 o->write_characters(string_buffer.data(), bytes);
12500 }
12501 }
12502 else
12503 {
12504 // we finish reading, but do not accept: string was incomplete
12505 switch (error_handler)
12506 {
12507 case error_handler_t::strict:
12508 {
12509 std::string sn(3, '\0');
12510 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
12511 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
12512 }
12513
12514 case error_handler_t::ignore:
12515 {
12516 // write all accepted bytes
12517 o->write_characters(string_buffer.data(), bytes_after_last_accept);
12518 break;
12519 }
12520
12521 case error_handler_t::replace:
12522 {
12523 // write all accepted bytes
12524 o->write_characters(string_buffer.data(), bytes_after_last_accept);
12525 // add a replacement character
12526 if (ensure_ascii)
12527 {
12528 o->write_characters("\\ufffd", 6);
12529 }
12530 else
12531 {
12532 o->write_characters("\xEF\xBF\xBD", 3);
12533 }
12534 break;
12535 }
12536
12537 default: // LCOV_EXCL_LINE
12538 assert(false); // LCOV_EXCL_LINE
12539 }
12540 }
12541 }
12542
12543 /*!
12544 @brief count digits
12545
12546 Count the number of decimal (base 10) digits for an input unsigned integer.
12547
12548 @param[in] x unsigned integer number to count its digits
12549 @return number of decimal digits
12550 */
count_digits(number_unsigned_t x)12551 inline unsigned int count_digits(number_unsigned_t x) noexcept
12552 {
12553 unsigned int n_digits = 1;
12554 for (;;)
12555 {
12556 if (x < 10)
12557 {
12558 return n_digits;
12559 }
12560 if (x < 100)
12561 {
12562 return n_digits + 1;
12563 }
12564 if (x < 1000)
12565 {
12566 return n_digits + 2;
12567 }
12568 if (x < 10000)
12569 {
12570 return n_digits + 3;
12571 }
12572 x = x / 10000u;
12573 n_digits += 4;
12574 }
12575 }
12576
12577 /*!
12578 @brief dump an integer
12579
12580 Dump a given integer to output stream @a o. Works internally with
12581 @a number_buffer.
12582
12583 @param[in] x integer number (signed or unsigned) to dump
12584 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
12585 */
12586 template<typename NumberType, detail::enable_if_t<
12587 std::is_same<NumberType, number_unsigned_t>::value or
12588 std::is_same<NumberType, number_integer_t>::value,
12589 int> = 0>
dump_integer(NumberType x)12590 void dump_integer(NumberType x)
12591 {
12592 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
12593 {
12594 {
12595 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
12596 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
12597 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
12598 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
12599 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
12600 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
12601 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
12602 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
12603 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
12604 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
12605 }
12606 };
12607
12608 // special case for "0"
12609 if (x == 0)
12610 {
12611 o->write_character('0');
12612 return;
12613 }
12614
12615 // use a pointer to fill the buffer
12616 auto buffer_ptr = number_buffer.begin();
12617
12618 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
12619 number_unsigned_t abs_value;
12620
12621 unsigned int n_chars;
12622
12623 if (is_negative)
12624 {
12625 *buffer_ptr = '-';
12626 abs_value = static_cast<number_unsigned_t>(std::abs(static_cast<std::intmax_t>(x)));
12627
12628 // account one more byte for the minus sign
12629 n_chars = 1 + count_digits(abs_value);
12630 }
12631 else
12632 {
12633 abs_value = static_cast<number_unsigned_t>(x);
12634 n_chars = count_digits(abs_value);
12635 }
12636
12637 // spare 1 byte for '\0'
12638 assert(n_chars < number_buffer.size() - 1);
12639
12640 // jump to the end to generate the string from backward
12641 // so we later avoid reversing the result
12642 buffer_ptr += n_chars;
12643
12644 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
12645 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
12646 while (abs_value >= 100)
12647 {
12648 const auto digits_index = static_cast<unsigned>((abs_value % 100));
12649 abs_value /= 100;
12650 *(--buffer_ptr) = digits_to_99[digits_index][1];
12651 *(--buffer_ptr) = digits_to_99[digits_index][0];
12652 }
12653
12654 if (abs_value >= 10)
12655 {
12656 const auto digits_index = static_cast<unsigned>(abs_value);
12657 *(--buffer_ptr) = digits_to_99[digits_index][1];
12658 *(--buffer_ptr) = digits_to_99[digits_index][0];
12659 }
12660 else
12661 {
12662 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
12663 }
12664
12665 o->write_characters(number_buffer.data(), n_chars);
12666 }
12667
12668 /*!
12669 @brief dump a floating-point number
12670
12671 Dump a given floating-point number to output stream @a o. Works internally
12672 with @a number_buffer.
12673
12674 @param[in] x floating-point number to dump
12675 */
dump_float(number_float_t x)12676 void dump_float(number_float_t x)
12677 {
12678 // NaN / inf
12679 if (not std::isfinite(x))
12680 {
12681 o->write_characters("null", 4);
12682 return;
12683 }
12684
12685 // If number_float_t is an IEEE-754 single or double precision number,
12686 // use the Grisu2 algorithm to produce short numbers which are
12687 // guaranteed to round-trip, using strtof and strtod, resp.
12688 //
12689 // NB: The test below works if <long double> == <double>.
12690 static constexpr bool is_ieee_single_or_double
12691 = (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 24 and std::numeric_limits<number_float_t>::max_exponent == 128) or
12692 (std::numeric_limits<number_float_t>::is_iec559 and std::numeric_limits<number_float_t>::digits == 53 and std::numeric_limits<number_float_t>::max_exponent == 1024);
12693
12694 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
12695 }
12696
dump_float(number_float_t x,std::true_type)12697 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
12698 {
12699 char* begin = number_buffer.data();
12700 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
12701
12702 o->write_characters(begin, static_cast<size_t>(end - begin));
12703 }
12704
dump_float(number_float_t x,std::false_type)12705 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
12706 {
12707 // get number of digits for a float -> text -> float round-trip
12708 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
12709
12710 // the actual conversion
12711 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
12712
12713 // negative value indicates an error
12714 assert(len > 0);
12715 // check if buffer was large enough
12716 assert(static_cast<std::size_t>(len) < number_buffer.size());
12717
12718 // erase thousands separator
12719 if (thousands_sep != '\0')
12720 {
12721 const auto end = std::remove(number_buffer.begin(),
12722 number_buffer.begin() + len, thousands_sep);
12723 std::fill(end, number_buffer.end(), '\0');
12724 assert((end - number_buffer.begin()) <= len);
12725 len = (end - number_buffer.begin());
12726 }
12727
12728 // convert decimal point to '.'
12729 if (decimal_point != '\0' and decimal_point != '.')
12730 {
12731 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
12732 if (dec_pos != number_buffer.end())
12733 {
12734 *dec_pos = '.';
12735 }
12736 }
12737
12738 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
12739
12740 // determine if need to append ".0"
12741 const bool value_is_int_like =
12742 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
12743 [](char c)
12744 {
12745 return c == '.' or c == 'e';
12746 });
12747
12748 if (value_is_int_like)
12749 {
12750 o->write_characters(".0", 2);
12751 }
12752 }
12753
12754 /*!
12755 @brief check whether a string is UTF-8 encoded
12756
12757 The function checks each byte of a string whether it is UTF-8 encoded. The
12758 result of the check is stored in the @a state parameter. The function must
12759 be called initially with state 0 (accept). State 1 means the string must
12760 be rejected, because the current byte is not allowed. If the string is
12761 completely processed, but the state is non-zero, the string ended
12762 prematurely; that is, the last byte indicated more bytes should have
12763 followed.
12764
12765 @param[in,out] state the state of the decoding
12766 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
12767 @param[in] byte next byte to decode
12768 @return new state
12769
12770 @note The function has been edited: a std::array is used.
12771
12772 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
12773 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
12774 */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)12775 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
12776 {
12777 static const std::array<std::uint8_t, 400> utf8d =
12778 {
12779 {
12780 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
12781 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
12782 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
12783 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
12784 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
12785 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
12786 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
12787 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
12788 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
12789 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
12790 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
12791 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
12792 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
12793 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
12794 }
12795 };
12796
12797 const std::uint8_t type = utf8d[byte];
12798
12799 codep = (state != UTF8_ACCEPT)
12800 ? (byte & 0x3fu) | (codep << 6u)
12801 : (0xFFu >> type) & (byte);
12802
12803 state = utf8d[256u + state * 16u + type];
12804 return state;
12805 }
12806
12807 private:
12808 /// the output of the serializer
12809 output_adapter_t<char> o = nullptr;
12810
12811 /// a (hopefully) large enough character buffer
12812 std::array<char, 64> number_buffer{{}};
12813
12814 /// the locale
12815 const std::lconv* loc = nullptr;
12816 /// the locale's thousand separator character
12817 const char thousands_sep = '\0';
12818 /// the locale's decimal point character
12819 const char decimal_point = '\0';
12820
12821 /// string buffer
12822 std::array<char, 512> string_buffer{{}};
12823
12824 /// the indentation character
12825 const char indent_char;
12826 /// the indentation string
12827 string_t indent_string;
12828
12829 /// error_handler how to react on decoding errors
12830 const error_handler_t error_handler;
12831 };
12832 } // namespace detail
12833 } // namespace nlohmann
12834
12835 // #include <nlohmann/detail/value_t.hpp>
12836
12837 // #include <nlohmann/json_fwd.hpp>
12838
12839
12840 /*!
12841 @brief namespace for Niels Lohmann
12842 @see https://github.com/nlohmann
12843 @since version 1.0.0
12844 */
12845 namespace nlohmann
12846 {
12847
12848 /*!
12849 @brief a class to store JSON values
12850
12851 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
12852 in @ref object_t)
12853 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
12854 in @ref array_t)
12855 @tparam StringType type for JSON strings and object keys (`std::string` by
12856 default; will be used in @ref string_t)
12857 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
12858 in @ref boolean_t)
12859 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
12860 default; will be used in @ref number_integer_t)
12861 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
12862 `uint64_t` by default; will be used in @ref number_unsigned_t)
12863 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
12864 default; will be used in @ref number_float_t)
12865 @tparam AllocatorType type of the allocator to use (`std::allocator` by
12866 default)
12867 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
12868 and `from_json()` (@ref adl_serializer by default)
12869
12870 @requirement The class satisfies the following concept requirements:
12871 - Basic
12872 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
12873 JSON values can be default constructed. The result will be a JSON null
12874 value.
12875 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
12876 A JSON value can be constructed from an rvalue argument.
12877 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
12878 A JSON value can be copy-constructed from an lvalue expression.
12879 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
12880 A JSON value van be assigned from an rvalue argument.
12881 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
12882 A JSON value can be copy-assigned from an lvalue expression.
12883 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
12884 JSON values can be destructed.
12885 - Layout
12886 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
12887 JSON values have
12888 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
12889 All non-static data members are private and standard layout types, the
12890 class has no virtual functions or (virtual) base classes.
12891 - Library-wide
12892 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
12893 JSON values can be compared with `==`, see @ref
12894 operator==(const_reference,const_reference).
12895 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
12896 JSON values can be compared with `<`, see @ref
12897 operator<(const_reference,const_reference).
12898 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
12899 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
12900 other compatible types, using unqualified function call @ref swap().
12901 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
12902 JSON values can be compared against `std::nullptr_t` objects which are used
12903 to model the `null` value.
12904 - Container
12905 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
12906 JSON values can be used like STL containers and provide iterator access.
12907 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
12908 JSON values can be used like STL containers and provide reverse iterator
12909 access.
12910
12911 @invariant The member variables @a m_value and @a m_type have the following
12912 relationship:
12913 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
12914 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
12915 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
12916 The invariants are checked by member function assert_invariant().
12917
12918 @internal
12919 @note ObjectType trick from http://stackoverflow.com/a/9860911
12920 @endinternal
12921
12922 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
12923 Format](http://rfc7159.net/rfc7159)
12924
12925 @since version 1.0.0
12926
12927 @nosubgrouping
12928 */
12929 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12930 class basic_json
12931 {
12932 private:
12933 template<detail::value_t> friend struct detail::external_constructor;
12934 friend ::nlohmann::json_pointer<basic_json>;
12935 friend ::nlohmann::detail::parser<basic_json>;
12936 friend ::nlohmann::detail::serializer<basic_json>;
12937 template<typename BasicJsonType>
12938 friend class ::nlohmann::detail::iter_impl;
12939 template<typename BasicJsonType, typename CharType>
12940 friend class ::nlohmann::detail::binary_writer;
12941 template<typename BasicJsonType, typename SAX>
12942 friend class ::nlohmann::detail::binary_reader;
12943 template<typename BasicJsonType>
12944 friend class ::nlohmann::detail::json_sax_dom_parser;
12945 template<typename BasicJsonType>
12946 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12947
12948 /// workaround type for MSVC
12949 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
12950
12951 // convenience aliases for types residing in namespace detail;
12952 using lexer = ::nlohmann::detail::lexer<basic_json>;
12953 using parser = ::nlohmann::detail::parser<basic_json>;
12954
12955 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
12956 template<typename BasicJsonType>
12957 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
12958 template<typename BasicJsonType>
12959 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
12960 template<typename Iterator>
12961 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
12962 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
12963
12964 template<typename CharType>
12965 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
12966
12967 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
12968 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
12969
12970 using serializer = ::nlohmann::detail::serializer<basic_json>;
12971
12972 public:
12973 using value_t = detail::value_t;
12974 /// JSON Pointer, see @ref nlohmann::json_pointer
12975 using json_pointer = ::nlohmann::json_pointer<basic_json>;
12976 template<typename T, typename SFINAE>
12977 using json_serializer = JSONSerializer<T, SFINAE>;
12978 /// how to treat decoding errors
12979 using error_handler_t = detail::error_handler_t;
12980 /// helper type for initializer lists of basic_json values
12981 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
12982
12983 using input_format_t = detail::input_format_t;
12984 /// SAX interface type, see @ref nlohmann::json_sax
12985 using json_sax_t = json_sax<basic_json>;
12986
12987 ////////////////
12988 // exceptions //
12989 ////////////////
12990
12991 /// @name exceptions
12992 /// Classes to implement user-defined exceptions.
12993 /// @{
12994
12995 /// @copydoc detail::exception
12996 using exception = detail::exception;
12997 /// @copydoc detail::parse_error
12998 using parse_error = detail::parse_error;
12999 /// @copydoc detail::invalid_iterator
13000 using invalid_iterator = detail::invalid_iterator;
13001 /// @copydoc detail::type_error
13002 using type_error = detail::type_error;
13003 /// @copydoc detail::out_of_range
13004 using out_of_range = detail::out_of_range;
13005 /// @copydoc detail::other_error
13006 using other_error = detail::other_error;
13007
13008 /// @}
13009
13010
13011 /////////////////////
13012 // container types //
13013 /////////////////////
13014
13015 /// @name container types
13016 /// The canonic container types to use @ref basic_json like any other STL
13017 /// container.
13018 /// @{
13019
13020 /// the type of elements in a basic_json container
13021 using value_type = basic_json;
13022
13023 /// the type of an element reference
13024 using reference = value_type&;
13025 /// the type of an element const reference
13026 using const_reference = const value_type&;
13027
13028 /// a type to represent differences between iterators
13029 using difference_type = std::ptrdiff_t;
13030 /// a type to represent container sizes
13031 using size_type = std::size_t;
13032
13033 /// the allocator type
13034 using allocator_type = AllocatorType<basic_json>;
13035
13036 /// the type of an element pointer
13037 using pointer = typename std::allocator_traits<allocator_type>::pointer;
13038 /// the type of an element const pointer
13039 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
13040
13041 /// an iterator for a basic_json container
13042 using iterator = iter_impl<basic_json>;
13043 /// a const iterator for a basic_json container
13044 using const_iterator = iter_impl<const basic_json>;
13045 /// a reverse iterator for a basic_json container
13046 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
13047 /// a const reverse iterator for a basic_json container
13048 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
13049
13050 /// @}
13051
13052
13053 /*!
13054 @brief returns the allocator associated with the container
13055 */
get_allocator()13056 static allocator_type get_allocator()
13057 {
13058 return allocator_type();
13059 }
13060
13061 /*!
13062 @brief returns version information on the library
13063
13064 This function returns a JSON object with information about the library,
13065 including the version number and information on the platform and compiler.
13066
13067 @return JSON object holding version information
13068 key | description
13069 ----------- | ---------------
13070 `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).
13071 `copyright` | The copyright line for the library as string.
13072 `name` | The name of the library as string.
13073 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
13074 `url` | The URL of the project as string.
13075 `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).
13076
13077 @liveexample{The following code shows an example output of the `meta()`
13078 function.,meta}
13079
13080 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13081 changes to any JSON value.
13082
13083 @complexity Constant.
13084
13085 @since 2.1.0
13086 */
13087 JSON_NODISCARD
meta()13088 static basic_json meta()
13089 {
13090 basic_json result;
13091
13092 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
13093 result["name"] = "JSON for Modern C++";
13094 result["url"] = "https://github.com/nlohmann/json";
13095 result["version"]["string"] =
13096 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
13097 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
13098 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
13099 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
13100 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
13101 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
13102
13103 #ifdef _WIN32
13104 result["platform"] = "win32";
13105 #elif defined __linux__
13106 result["platform"] = "linux";
13107 #elif defined __APPLE__
13108 result["platform"] = "apple";
13109 #elif defined __unix__
13110 result["platform"] = "unix";
13111 #else
13112 result["platform"] = "unknown";
13113 #endif
13114
13115 #if defined(__ICC) || defined(__INTEL_COMPILER)
13116 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
13117 #elif defined(__clang__)
13118 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
13119 #elif defined(__GNUC__) || defined(__GNUG__)
13120 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
13121 #elif defined(__HP_cc) || defined(__HP_aCC)
13122 result["compiler"] = "hp"
13123 #elif defined(__IBMCPP__)
13124 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
13125 #elif defined(_MSC_VER)
13126 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
13127 #elif defined(__PGI)
13128 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
13129 #elif defined(__SUNPRO_CC)
13130 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
13131 #else
13132 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
13133 #endif
13134
13135 #ifdef __cplusplus
13136 result["compiler"]["c++"] = std::to_string(__cplusplus);
13137 #else
13138 result["compiler"]["c++"] = "unknown";
13139 #endif
13140 return result;
13141 }
13142
13143
13144 ///////////////////////////
13145 // JSON value data types //
13146 ///////////////////////////
13147
13148 /// @name JSON value data types
13149 /// The data types to store a JSON value. These types are derived from
13150 /// the template arguments passed to class @ref basic_json.
13151 /// @{
13152
13153 #if defined(JSON_HAS_CPP_14)
13154 // Use transparent comparator if possible, combined with perfect forwarding
13155 // on find() and count() calls prevents unnecessary string construction.
13156 using object_comparator_t = std::less<>;
13157 #else
13158 using object_comparator_t = std::less<StringType>;
13159 #endif
13160
13161 /*!
13162 @brief a type for an object
13163
13164 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
13165 > An object is an unordered collection of zero or more name/value pairs,
13166 > where a name is a string and a value is a string, number, boolean, null,
13167 > object, or array.
13168
13169 To store objects in C++, a type is defined by the template parameters
13170 described below.
13171
13172 @tparam ObjectType the container to store objects (e.g., `std::map` or
13173 `std::unordered_map`)
13174 @tparam StringType the type of the keys or names (e.g., `std::string`).
13175 The comparison function `std::less<StringType>` is used to order elements
13176 inside the container.
13177 @tparam AllocatorType the allocator to use for objects (e.g.,
13178 `std::allocator`)
13179
13180 #### Default type
13181
13182 With the default values for @a ObjectType (`std::map`), @a StringType
13183 (`std::string`), and @a AllocatorType (`std::allocator`), the default
13184 value for @a object_t is:
13185
13186 @code {.cpp}
13187 std::map<
13188 std::string, // key_type
13189 basic_json, // value_type
13190 std::less<std::string>, // key_compare
13191 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
13192 >
13193 @endcode
13194
13195 #### Behavior
13196
13197 The choice of @a object_t influences the behavior of the JSON class. With
13198 the default type, objects have the following behavior:
13199
13200 - When all names are unique, objects will be interoperable in the sense
13201 that all software implementations receiving that object will agree on
13202 the name-value mappings.
13203 - When the names within an object are not unique, it is unspecified which
13204 one of the values for a given key will be chosen. For instance,
13205 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
13206 `{"key": 2}`.
13207 - Internally, name/value pairs are stored in lexicographical order of the
13208 names. Objects will also be serialized (see @ref dump) in this order.
13209 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
13210 and serialized as `{"a": 2, "b": 1}`.
13211 - When comparing objects, the order of the name/value pairs is irrelevant.
13212 This makes objects interoperable in the sense that they will not be
13213 affected by these differences. For instance, `{"b": 1, "a": 2}` and
13214 `{"a": 2, "b": 1}` will be treated as equal.
13215
13216 #### Limits
13217
13218 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13219 > An implementation may set limits on the maximum depth of nesting.
13220
13221 In this class, the object's limit of nesting is not explicitly constrained.
13222 However, a maximum depth of nesting may be introduced by the compiler or
13223 runtime environment. A theoretical limit can be queried by calling the
13224 @ref max_size function of a JSON object.
13225
13226 #### Storage
13227
13228 Objects are stored as pointers in a @ref basic_json type. That is, for any
13229 access to object values, a pointer of type `object_t*` must be
13230 dereferenced.
13231
13232 @sa @ref array_t -- type for an array value
13233
13234 @since version 1.0.0
13235
13236 @note The order name/value pairs are added to the object is *not*
13237 preserved by the library. Therefore, iterating an object may return
13238 name/value pairs in a different order than they were originally stored. In
13239 fact, keys will be traversed in alphabetical order as `std::map` with
13240 `std::less` is used by default. Please note this behavior conforms to [RFC
13241 7159](http://rfc7159.net/rfc7159), because any order implements the
13242 specified "unordered" nature of JSON objects.
13243 */
13244 using object_t = ObjectType<StringType,
13245 basic_json,
13246 object_comparator_t,
13247 AllocatorType<std::pair<const StringType,
13248 basic_json>>>;
13249
13250 /*!
13251 @brief a type for an array
13252
13253 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
13254 > An array is an ordered sequence of zero or more values.
13255
13256 To store objects in C++, a type is defined by the template parameters
13257 explained below.
13258
13259 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
13260 `std::list`)
13261 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
13262
13263 #### Default type
13264
13265 With the default values for @a ArrayType (`std::vector`) and @a
13266 AllocatorType (`std::allocator`), the default value for @a array_t is:
13267
13268 @code {.cpp}
13269 std::vector<
13270 basic_json, // value_type
13271 std::allocator<basic_json> // allocator_type
13272 >
13273 @endcode
13274
13275 #### Limits
13276
13277 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13278 > An implementation may set limits on the maximum depth of nesting.
13279
13280 In this class, the array's limit of nesting is not explicitly constrained.
13281 However, a maximum depth of nesting may be introduced by the compiler or
13282 runtime environment. A theoretical limit can be queried by calling the
13283 @ref max_size function of a JSON array.
13284
13285 #### Storage
13286
13287 Arrays are stored as pointers in a @ref basic_json type. That is, for any
13288 access to array values, a pointer of type `array_t*` must be dereferenced.
13289
13290 @sa @ref object_t -- type for an object value
13291
13292 @since version 1.0.0
13293 */
13294 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13295
13296 /*!
13297 @brief a type for a string
13298
13299 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
13300 > A string is a sequence of zero or more Unicode characters.
13301
13302 To store objects in C++, a type is defined by the template parameter
13303 described below. Unicode values are split by the JSON class into
13304 byte-sized characters during deserialization.
13305
13306 @tparam StringType the container to store strings (e.g., `std::string`).
13307 Note this container is used for keys/names in objects, see @ref object_t.
13308
13309 #### Default type
13310
13311 With the default values for @a StringType (`std::string`), the default
13312 value for @a string_t is:
13313
13314 @code {.cpp}
13315 std::string
13316 @endcode
13317
13318 #### Encoding
13319
13320 Strings are stored in UTF-8 encoding. Therefore, functions like
13321 `std::string::size()` or `std::string::length()` return the number of
13322 bytes in the string rather than the number of characters or glyphs.
13323
13324 #### String comparison
13325
13326 [RFC 7159](http://rfc7159.net/rfc7159) states:
13327 > Software implementations are typically required to test names of object
13328 > members for equality. Implementations that transform the textual
13329 > representation into sequences of Unicode code units and then perform the
13330 > comparison numerically, code unit by code unit, are interoperable in the
13331 > sense that implementations will agree in all cases on equality or
13332 > inequality of two strings. For example, implementations that compare
13333 > strings with escaped characters unconverted may incorrectly find that
13334 > `"a\\b"` and `"a\u005Cb"` are not equal.
13335
13336 This implementation is interoperable as it does compare strings code unit
13337 by code unit.
13338
13339 #### Storage
13340
13341 String values are stored as pointers in a @ref basic_json type. That is,
13342 for any access to string values, a pointer of type `string_t*` must be
13343 dereferenced.
13344
13345 @since version 1.0.0
13346 */
13347 using string_t = StringType;
13348
13349 /*!
13350 @brief a type for a boolean
13351
13352 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
13353 type which differentiates the two literals `true` and `false`.
13354
13355 To store objects in C++, a type is defined by the template parameter @a
13356 BooleanType which chooses the type to use.
13357
13358 #### Default type
13359
13360 With the default values for @a BooleanType (`bool`), the default value for
13361 @a boolean_t is:
13362
13363 @code {.cpp}
13364 bool
13365 @endcode
13366
13367 #### Storage
13368
13369 Boolean values are stored directly inside a @ref basic_json type.
13370
13371 @since version 1.0.0
13372 */
13373 using boolean_t = BooleanType;
13374
13375 /*!
13376 @brief a type for a number (integer)
13377
13378 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13379 > The representation of numbers is similar to that used in most
13380 > programming languages. A number is represented in base 10 using decimal
13381 > digits. It contains an integer component that may be prefixed with an
13382 > optional minus sign, which may be followed by a fraction part and/or an
13383 > exponent part. Leading zeros are not allowed. (...) Numeric values that
13384 > cannot be represented in the grammar below (such as Infinity and NaN)
13385 > are not permitted.
13386
13387 This description includes both integer and floating-point numbers.
13388 However, C++ allows more precise storage if it is known whether the number
13389 is a signed integer, an unsigned integer or a floating-point number.
13390 Therefore, three different types, @ref number_integer_t, @ref
13391 number_unsigned_t and @ref number_float_t are used.
13392
13393 To store integer numbers in C++, a type is defined by the template
13394 parameter @a NumberIntegerType which chooses the type to use.
13395
13396 #### Default type
13397
13398 With the default values for @a NumberIntegerType (`int64_t`), the default
13399 value for @a number_integer_t is:
13400
13401 @code {.cpp}
13402 int64_t
13403 @endcode
13404
13405 #### Default behavior
13406
13407 - The restrictions about leading zeros is not enforced in C++. Instead,
13408 leading zeros in integer literals lead to an interpretation as octal
13409 number. Internally, the value will be stored as decimal number. For
13410 instance, the C++ integer literal `010` will be serialized to `8`.
13411 During deserialization, leading zeros yield an error.
13412 - Not-a-number (NaN) values will be serialized to `null`.
13413
13414 #### Limits
13415
13416 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13417 > An implementation may set limits on the range and precision of numbers.
13418
13419 When the default type is used, the maximal integer number that can be
13420 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
13421 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
13422 that are out of range will yield over/underflow when used in a
13423 constructor. During deserialization, too large or small integer numbers
13424 will be automatically be stored as @ref number_unsigned_t or @ref
13425 number_float_t.
13426
13427 [RFC 7159](http://rfc7159.net/rfc7159) further states:
13428 > Note that when such software is used, numbers that are integers and are
13429 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
13430 > that implementations will agree exactly on their numeric values.
13431
13432 As this range is a subrange of the exactly supported range [INT64_MIN,
13433 INT64_MAX], this class's integer type is interoperable.
13434
13435 #### Storage
13436
13437 Integer number values are stored directly inside a @ref basic_json type.
13438
13439 @sa @ref number_float_t -- type for number values (floating-point)
13440
13441 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
13442
13443 @since version 1.0.0
13444 */
13445 using number_integer_t = NumberIntegerType;
13446
13447 /*!
13448 @brief a type for a number (unsigned)
13449
13450 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13451 > The representation of numbers is similar to that used in most
13452 > programming languages. A number is represented in base 10 using decimal
13453 > digits. It contains an integer component that may be prefixed with an
13454 > optional minus sign, which may be followed by a fraction part and/or an
13455 > exponent part. Leading zeros are not allowed. (...) Numeric values that
13456 > cannot be represented in the grammar below (such as Infinity and NaN)
13457 > are not permitted.
13458
13459 This description includes both integer and floating-point numbers.
13460 However, C++ allows more precise storage if it is known whether the number
13461 is a signed integer, an unsigned integer or a floating-point number.
13462 Therefore, three different types, @ref number_integer_t, @ref
13463 number_unsigned_t and @ref number_float_t are used.
13464
13465 To store unsigned integer numbers in C++, a type is defined by the
13466 template parameter @a NumberUnsignedType which chooses the type to use.
13467
13468 #### Default type
13469
13470 With the default values for @a NumberUnsignedType (`uint64_t`), the
13471 default value for @a number_unsigned_t is:
13472
13473 @code {.cpp}
13474 uint64_t
13475 @endcode
13476
13477 #### Default behavior
13478
13479 - The restrictions about leading zeros is not enforced in C++. Instead,
13480 leading zeros in integer literals lead to an interpretation as octal
13481 number. Internally, the value will be stored as decimal number. For
13482 instance, the C++ integer literal `010` will be serialized to `8`.
13483 During deserialization, leading zeros yield an error.
13484 - Not-a-number (NaN) values will be serialized to `null`.
13485
13486 #### Limits
13487
13488 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13489 > An implementation may set limits on the range and precision of numbers.
13490
13491 When the default type is used, the maximal integer number that can be
13492 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
13493 number that can be stored is `0`. Integer numbers that are out of range
13494 will yield over/underflow when used in a constructor. During
13495 deserialization, too large or small integer numbers will be automatically
13496 be stored as @ref number_integer_t or @ref number_float_t.
13497
13498 [RFC 7159](http://rfc7159.net/rfc7159) further states:
13499 > Note that when such software is used, numbers that are integers and are
13500 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
13501 > that implementations will agree exactly on their numeric values.
13502
13503 As this range is a subrange (when considered in conjunction with the
13504 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
13505 this class's integer type is interoperable.
13506
13507 #### Storage
13508
13509 Integer number values are stored directly inside a @ref basic_json type.
13510
13511 @sa @ref number_float_t -- type for number values (floating-point)
13512 @sa @ref number_integer_t -- type for number values (integer)
13513
13514 @since version 2.0.0
13515 */
13516 using number_unsigned_t = NumberUnsignedType;
13517
13518 /*!
13519 @brief a type for a number (floating-point)
13520
13521 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13522 > The representation of numbers is similar to that used in most
13523 > programming languages. A number is represented in base 10 using decimal
13524 > digits. It contains an integer component that may be prefixed with an
13525 > optional minus sign, which may be followed by a fraction part and/or an
13526 > exponent part. Leading zeros are not allowed. (...) Numeric values that
13527 > cannot be represented in the grammar below (such as Infinity and NaN)
13528 > are not permitted.
13529
13530 This description includes both integer and floating-point numbers.
13531 However, C++ allows more precise storage if it is known whether the number
13532 is a signed integer, an unsigned integer or a floating-point number.
13533 Therefore, three different types, @ref number_integer_t, @ref
13534 number_unsigned_t and @ref number_float_t are used.
13535
13536 To store floating-point numbers in C++, a type is defined by the template
13537 parameter @a NumberFloatType which chooses the type to use.
13538
13539 #### Default type
13540
13541 With the default values for @a NumberFloatType (`double`), the default
13542 value for @a number_float_t is:
13543
13544 @code {.cpp}
13545 double
13546 @endcode
13547
13548 #### Default behavior
13549
13550 - The restrictions about leading zeros is not enforced in C++. Instead,
13551 leading zeros in floating-point literals will be ignored. Internally,
13552 the value will be stored as decimal number. For instance, the C++
13553 floating-point literal `01.2` will be serialized to `1.2`. During
13554 deserialization, leading zeros yield an error.
13555 - Not-a-number (NaN) values will be serialized to `null`.
13556
13557 #### Limits
13558
13559 [RFC 7159](http://rfc7159.net/rfc7159) states:
13560 > This specification allows implementations to set limits on the range and
13561 > precision of numbers accepted. Since software that implements IEEE
13562 > 754-2008 binary64 (double precision) numbers is generally available and
13563 > widely used, good interoperability can be achieved by implementations
13564 > that expect no more precision or range than these provide, in the sense
13565 > that implementations will approximate JSON numbers within the expected
13566 > precision.
13567
13568 This implementation does exactly follow this approach, as it uses double
13569 precision floating-point numbers. Note values smaller than
13570 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
13571 will be stored as NaN internally and be serialized to `null`.
13572
13573 #### Storage
13574
13575 Floating-point number values are stored directly inside a @ref basic_json
13576 type.
13577
13578 @sa @ref number_integer_t -- type for number values (integer)
13579
13580 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
13581
13582 @since version 1.0.0
13583 */
13584 using number_float_t = NumberFloatType;
13585
13586 /// @}
13587
13588 private:
13589
13590 /// helper for exception-safe object creation
13591 template<typename T, typename... Args>
create(Args &&...args)13592 static T* create(Args&& ... args)
13593 {
13594 AllocatorType<T> alloc;
13595 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13596
13597 auto deleter = [&](T * object)
13598 {
13599 AllocatorTraits::deallocate(alloc, object, 1);
13600 };
13601 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13602 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
13603 assert(object != nullptr);
13604 return object.release();
13605 }
13606
13607 ////////////////////////
13608 // JSON value storage //
13609 ////////////////////////
13610
13611 /*!
13612 @brief a JSON value
13613
13614 The actual storage for a JSON value of the @ref basic_json class. This
13615 union combines the different storage types for the JSON value types
13616 defined in @ref value_t.
13617
13618 JSON type | value_t type | used type
13619 --------- | --------------- | ------------------------
13620 object | object | pointer to @ref object_t
13621 array | array | pointer to @ref array_t
13622 string | string | pointer to @ref string_t
13623 boolean | boolean | @ref boolean_t
13624 number | number_integer | @ref number_integer_t
13625 number | number_unsigned | @ref number_unsigned_t
13626 number | number_float | @ref number_float_t
13627 null | null | *no value is stored*
13628
13629 @note Variable-length types (objects, arrays, and strings) are stored as
13630 pointers. The size of the union should not exceed 64 bits if the default
13631 value types are used.
13632
13633 @since version 1.0.0
13634 */
13635 union json_value
13636 {
13637 /// object (stored with pointer to save storage)
13638 object_t* object;
13639 /// array (stored with pointer to save storage)
13640 array_t* array;
13641 /// string (stored with pointer to save storage)
13642 string_t* string;
13643 /// boolean
13644 boolean_t boolean;
13645 /// number (integer)
13646 number_integer_t number_integer;
13647 /// number (unsigned integer)
13648 number_unsigned_t number_unsigned;
13649 /// number (floating-point)
13650 number_float_t number_float;
13651
13652 /// default constructor (for null values)
13653 json_value() = default;
13654 /// constructor for booleans
json_value(boolean_t v)13655 json_value(boolean_t v) noexcept : boolean(v) {}
13656 /// constructor for numbers (integer)
json_value(number_integer_t v)13657 json_value(number_integer_t v) noexcept : number_integer(v) {}
13658 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)13659 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
13660 /// constructor for numbers (floating-point)
json_value(number_float_t v)13661 json_value(number_float_t v) noexcept : number_float(v) {}
13662 /// constructor for empty values of a given type
json_value(value_t t)13663 json_value(value_t t)
13664 {
13665 switch (t)
13666 {
13667 case value_t::object:
13668 {
13669 object = create<object_t>();
13670 break;
13671 }
13672
13673 case value_t::array:
13674 {
13675 array = create<array_t>();
13676 break;
13677 }
13678
13679 case value_t::string:
13680 {
13681 string = create<string_t>("");
13682 break;
13683 }
13684
13685 case value_t::boolean:
13686 {
13687 boolean = boolean_t(false);
13688 break;
13689 }
13690
13691 case value_t::number_integer:
13692 {
13693 number_integer = number_integer_t(0);
13694 break;
13695 }
13696
13697 case value_t::number_unsigned:
13698 {
13699 number_unsigned = number_unsigned_t(0);
13700 break;
13701 }
13702
13703 case value_t::number_float:
13704 {
13705 number_float = number_float_t(0.0);
13706 break;
13707 }
13708
13709 case value_t::null:
13710 {
13711 object = nullptr; // silence warning, see #821
13712 break;
13713 }
13714
13715 default:
13716 {
13717 object = nullptr; // silence warning, see #821
13718 if (JSON_UNLIKELY(t == value_t::null))
13719 {
13720 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.6.1")); // LCOV_EXCL_LINE
13721 }
13722 break;
13723 }
13724 }
13725 }
13726
13727 /// constructor for strings
json_value(const string_t & value)13728 json_value(const string_t& value)
13729 {
13730 string = create<string_t>(value);
13731 }
13732
13733 /// constructor for rvalue strings
json_value(string_t && value)13734 json_value(string_t&& value)
13735 {
13736 string = create<string_t>(std::move(value));
13737 }
13738
13739 /// constructor for objects
json_value(const object_t & value)13740 json_value(const object_t& value)
13741 {
13742 object = create<object_t>(value);
13743 }
13744
13745 /// constructor for rvalue objects
json_value(object_t && value)13746 json_value(object_t&& value)
13747 {
13748 object = create<object_t>(std::move(value));
13749 }
13750
13751 /// constructor for arrays
json_value(const array_t & value)13752 json_value(const array_t& value)
13753 {
13754 array = create<array_t>(value);
13755 }
13756
13757 /// constructor for rvalue arrays
json_value(array_t && value)13758 json_value(array_t&& value)
13759 {
13760 array = create<array_t>(std::move(value));
13761 }
13762
destroy(value_t t)13763 void destroy(value_t t) noexcept
13764 {
13765 switch (t)
13766 {
13767 case value_t::object:
13768 {
13769 AllocatorType<object_t> alloc;
13770 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
13771 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
13772 break;
13773 }
13774
13775 case value_t::array:
13776 {
13777 AllocatorType<array_t> alloc;
13778 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
13779 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
13780 break;
13781 }
13782
13783 case value_t::string:
13784 {
13785 AllocatorType<string_t> alloc;
13786 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
13787 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
13788 break;
13789 }
13790
13791 default:
13792 {
13793 break;
13794 }
13795 }
13796 }
13797 };
13798
13799 /*!
13800 @brief checks the class invariants
13801
13802 This function asserts the class invariants. It needs to be called at the
13803 end of every constructor to make sure that created objects respect the
13804 invariant. Furthermore, it has to be called each time the type of a JSON
13805 value is changed, because the invariant expresses a relationship between
13806 @a m_type and @a m_value.
13807 */
assert_invariant() const13808 void assert_invariant() const noexcept
13809 {
13810 assert(m_type != value_t::object or m_value.object != nullptr);
13811 assert(m_type != value_t::array or m_value.array != nullptr);
13812 assert(m_type != value_t::string or m_value.string != nullptr);
13813 }
13814
13815 public:
13816 //////////////////////////
13817 // JSON parser callback //
13818 //////////////////////////
13819
13820 /*!
13821 @brief parser event types
13822
13823 The parser callback distinguishes the following events:
13824 - `object_start`: the parser read `{` and started to process a JSON object
13825 - `key`: the parser read a key of a value in an object
13826 - `object_end`: the parser read `}` and finished processing a JSON object
13827 - `array_start`: the parser read `[` and started to process a JSON array
13828 - `array_end`: the parser read `]` and finished processing a JSON array
13829 - `value`: the parser finished reading a JSON value
13830
13831 @image html callback_events.png "Example when certain parse events are triggered"
13832
13833 @sa @ref parser_callback_t for more information and examples
13834 */
13835 using parse_event_t = typename parser::parse_event_t;
13836
13837 /*!
13838 @brief per-element parser callback type
13839
13840 With a parser callback function, the result of parsing a JSON text can be
13841 influenced. When passed to @ref parse, it is called on certain events
13842 (passed as @ref parse_event_t via parameter @a event) with a set recursion
13843 depth @a depth and context JSON value @a parsed. The return value of the
13844 callback function is a boolean indicating whether the element that emitted
13845 the callback shall be kept or not.
13846
13847 We distinguish six scenarios (determined by the event type) in which the
13848 callback function can be called. The following table describes the values
13849 of the parameters @a depth, @a event, and @a parsed.
13850
13851 parameter @a event | description | parameter @a depth | parameter @a parsed
13852 ------------------ | ----------- | ------------------ | -------------------
13853 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
13854 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
13855 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
13856 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
13857 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
13858 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
13859
13860 @image html callback_events.png "Example when certain parse events are triggered"
13861
13862 Discarding a value (i.e., returning `false`) has different effects
13863 depending on the context in which function was called:
13864
13865 - Discarded values in structured types are skipped. That is, the parser
13866 will behave as if the discarded value was never read.
13867 - In case a value outside a structured type is skipped, it is replaced
13868 with `null`. This case happens if the top-level element is skipped.
13869
13870 @param[in] depth the depth of the recursion during parsing
13871
13872 @param[in] event an event of type parse_event_t indicating the context in
13873 the callback function has been called
13874
13875 @param[in,out] parsed the current intermediate parse result; note that
13876 writing to this value has no effect for parse_event_t::key events
13877
13878 @return Whether the JSON value which called the function during parsing
13879 should be kept (`true`) or not (`false`). In the latter case, it is either
13880 skipped completely or replaced by an empty discarded object.
13881
13882 @sa @ref parse for examples
13883
13884 @since version 1.0.0
13885 */
13886 using parser_callback_t = typename parser::parser_callback_t;
13887
13888 //////////////////
13889 // constructors //
13890 //////////////////
13891
13892 /// @name constructors and destructors
13893 /// Constructors of class @ref basic_json, copy/move constructor, copy
13894 /// assignment, static functions creating objects, and the destructor.
13895 /// @{
13896
13897 /*!
13898 @brief create an empty value with a given type
13899
13900 Create an empty JSON value with a given type. The value will be default
13901 initialized with an empty value which depends on the type:
13902
13903 Value type | initial value
13904 ----------- | -------------
13905 null | `null`
13906 boolean | `false`
13907 string | `""`
13908 number | `0`
13909 object | `{}`
13910 array | `[]`
13911
13912 @param[in] v the type of the value to create
13913
13914 @complexity Constant.
13915
13916 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13917 changes to any JSON value.
13918
13919 @liveexample{The following code shows the constructor for different @ref
13920 value_t values,basic_json__value_t}
13921
13922 @sa @ref clear() -- restores the postcondition of this constructor
13923
13924 @since version 1.0.0
13925 */
basic_json(const value_t v)13926 basic_json(const value_t v)
13927 : m_type(v), m_value(v)
13928 {
13929 assert_invariant();
13930 }
13931
13932 /*!
13933 @brief create a null object
13934
13935 Create a `null` JSON value. It either takes a null pointer as parameter
13936 (explicitly creating `null`) or no parameter (implicitly creating `null`).
13937 The passed null pointer itself is not read -- it is only used to choose
13938 the right constructor.
13939
13940 @complexity Constant.
13941
13942 @exceptionsafety No-throw guarantee: this constructor never throws
13943 exceptions.
13944
13945 @liveexample{The following code shows the constructor with and without a
13946 null pointer parameter.,basic_json__nullptr_t}
13947
13948 @since version 1.0.0
13949 */
basic_json(std::nullptr_t=nullptr)13950 basic_json(std::nullptr_t = nullptr) noexcept
13951 : basic_json(value_t::null)
13952 {
13953 assert_invariant();
13954 }
13955
13956 /*!
13957 @brief create a JSON value
13958
13959 This is a "catch all" constructor for all compatible JSON types; that is,
13960 types for which a `to_json()` method exists. The constructor forwards the
13961 parameter @a val to that method (to `json_serializer<U>::to_json` method
13962 with `U = uncvref_t<CompatibleType>`, to be exact).
13963
13964 Template type @a CompatibleType includes, but is not limited to, the
13965 following types:
13966 - **arrays**: @ref array_t and all kinds of compatible containers such as
13967 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
13968 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
13969 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
13970 which a @ref basic_json value can be constructed.
13971 - **objects**: @ref object_t and all kinds of compatible associative
13972 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
13973 and `std::unordered_multimap` with a `key_type` compatible to
13974 @ref string_t and a `value_type` from which a @ref basic_json value can
13975 be constructed.
13976 - **strings**: @ref string_t, string literals, and all compatible string
13977 containers can be used.
13978 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
13979 @ref number_float_t, and all convertible number types such as `int`,
13980 `size_t`, `int64_t`, `float` or `double` can be used.
13981 - **boolean**: @ref boolean_t / `bool` can be used.
13982
13983 See the examples below.
13984
13985 @tparam CompatibleType a type such that:
13986 - @a CompatibleType is not derived from `std::istream`,
13987 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
13988 constructors),
13989 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
13990 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
13991 @ref json_pointer, @ref iterator, etc ...)
13992 - @ref @ref json_serializer<U> has a
13993 `to_json(basic_json_t&, CompatibleType&&)` method
13994
13995 @tparam U = `uncvref_t<CompatibleType>`
13996
13997 @param[in] val the value to be forwarded to the respective constructor
13998
13999 @complexity Usually linear in the size of the passed @a val, also
14000 depending on the implementation of the called `to_json()`
14001 method.
14002
14003 @exceptionsafety Depends on the called constructor. For types directly
14004 supported by the library (i.e., all types for which no `to_json()` function
14005 was provided), strong guarantee holds: if an exception is thrown, there are
14006 no changes to any JSON value.
14007
14008 @liveexample{The following code shows the constructor with several
14009 compatible types.,basic_json__CompatibleType}
14010
14011 @since version 2.1.0
14012 */
14013 template <typename CompatibleType,
14014 typename U = detail::uncvref_t<CompatibleType>,
14015 detail::enable_if_t<
14016 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val)14017 basic_json(CompatibleType && val) noexcept(noexcept(
14018 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
14019 std::forward<CompatibleType>(val))))
14020 {
14021 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
14022 assert_invariant();
14023 }
14024
14025 /*!
14026 @brief create a JSON value from an existing one
14027
14028 This is a constructor for existing @ref basic_json types.
14029 It does not hijack copy/move constructors, since the parameter has different
14030 template arguments than the current ones.
14031
14032 The constructor tries to convert the internal @ref m_value of the parameter.
14033
14034 @tparam BasicJsonType a type such that:
14035 - @a BasicJsonType is a @ref basic_json type.
14036 - @a BasicJsonType has different template arguments than @ref basic_json_t.
14037
14038 @param[in] val the @ref basic_json value to be converted.
14039
14040 @complexity Usually linear in the size of the passed @a val, also
14041 depending on the implementation of the called `to_json()`
14042 method.
14043
14044 @exceptionsafety Depends on the called constructor. For types directly
14045 supported by the library (i.e., all types for which no `to_json()` function
14046 was provided), strong guarantee holds: if an exception is thrown, there are
14047 no changes to any JSON value.
14048
14049 @since version 3.2.0
14050 */
14051 template <typename BasicJsonType,
14052 detail::enable_if_t<
14053 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType & val)14054 basic_json(const BasicJsonType& val)
14055 {
14056 using other_boolean_t = typename BasicJsonType::boolean_t;
14057 using other_number_float_t = typename BasicJsonType::number_float_t;
14058 using other_number_integer_t = typename BasicJsonType::number_integer_t;
14059 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
14060 using other_string_t = typename BasicJsonType::string_t;
14061 using other_object_t = typename BasicJsonType::object_t;
14062 using other_array_t = typename BasicJsonType::array_t;
14063
14064 switch (val.type())
14065 {
14066 case value_t::boolean:
14067 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
14068 break;
14069 case value_t::number_float:
14070 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
14071 break;
14072 case value_t::number_integer:
14073 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
14074 break;
14075 case value_t::number_unsigned:
14076 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
14077 break;
14078 case value_t::string:
14079 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
14080 break;
14081 case value_t::object:
14082 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
14083 break;
14084 case value_t::array:
14085 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
14086 break;
14087 case value_t::null:
14088 *this = nullptr;
14089 break;
14090 case value_t::discarded:
14091 m_type = value_t::discarded;
14092 break;
14093 default: // LCOV_EXCL_LINE
14094 assert(false); // LCOV_EXCL_LINE
14095 }
14096 assert_invariant();
14097 }
14098
14099 /*!
14100 @brief create a container (array or object) from an initializer list
14101
14102 Creates a JSON value of type array or object from the passed initializer
14103 list @a init. In case @a type_deduction is `true` (default), the type of
14104 the JSON value to be created is deducted from the initializer list @a init
14105 according to the following rules:
14106
14107 1. If the list is empty, an empty JSON object value `{}` is created.
14108 2. If the list consists of pairs whose first element is a string, a JSON
14109 object value is created where the first elements of the pairs are
14110 treated as keys and the second elements are as values.
14111 3. In all other cases, an array is created.
14112
14113 The rules aim to create the best fit between a C++ initializer list and
14114 JSON values. The rationale is as follows:
14115
14116 1. The empty initializer list is written as `{}` which is exactly an empty
14117 JSON object.
14118 2. C++ has no way of describing mapped types other than to list a list of
14119 pairs. As JSON requires that keys must be of type string, rule 2 is the
14120 weakest constraint one can pose on initializer lists to interpret them
14121 as an object.
14122 3. In all other cases, the initializer list could not be interpreted as
14123 JSON object type, so interpreting it as JSON array type is safe.
14124
14125 With the rules described above, the following JSON values cannot be
14126 expressed by an initializer list:
14127
14128 - the empty array (`[]`): use @ref array(initializer_list_t)
14129 with an empty initializer list in this case
14130 - arrays whose elements satisfy rule 2: use @ref
14131 array(initializer_list_t) with the same initializer list
14132 in this case
14133
14134 @note When used without parentheses around an empty initializer list, @ref
14135 basic_json() is called instead of this function, yielding the JSON null
14136 value.
14137
14138 @param[in] init initializer list with JSON values
14139
14140 @param[in] type_deduction internal parameter; when set to `true`, the type
14141 of the JSON value is deducted from the initializer list @a init; when set
14142 to `false`, the type provided via @a manual_type is forced. This mode is
14143 used by the functions @ref array(initializer_list_t) and
14144 @ref object(initializer_list_t).
14145
14146 @param[in] manual_type internal parameter; when @a type_deduction is set
14147 to `false`, the created JSON value will use the provided type (only @ref
14148 value_t::array and @ref value_t::object are valid); when @a type_deduction
14149 is set to `true`, this parameter has no effect
14150
14151 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
14152 `value_t::object`, but @a init contains an element which is not a pair
14153 whose first element is a string. In this case, the constructor could not
14154 create an object. If @a type_deduction would have be `true`, an array
14155 would have been created. See @ref object(initializer_list_t)
14156 for an example.
14157
14158 @complexity Linear in the size of the initializer list @a init.
14159
14160 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14161 changes to any JSON value.
14162
14163 @liveexample{The example below shows how JSON values are created from
14164 initializer lists.,basic_json__list_init_t}
14165
14166 @sa @ref array(initializer_list_t) -- create a JSON array
14167 value from an initializer list
14168 @sa @ref object(initializer_list_t) -- create a JSON object
14169 value from an initializer list
14170
14171 @since version 1.0.0
14172 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)14173 basic_json(initializer_list_t init,
14174 bool type_deduction = true,
14175 value_t manual_type = value_t::array)
14176 {
14177 // check if each element is an array with two elements whose first
14178 // element is a string
14179 bool is_an_object = std::all_of(init.begin(), init.end(),
14180 [](const detail::json_ref<basic_json>& element_ref)
14181 {
14182 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
14183 });
14184
14185 // adjust type if type deduction is not wanted
14186 if (not type_deduction)
14187 {
14188 // if array is wanted, do not create an object though possible
14189 if (manual_type == value_t::array)
14190 {
14191 is_an_object = false;
14192 }
14193
14194 // if object is wanted but impossible, throw an exception
14195 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
14196 {
14197 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
14198 }
14199 }
14200
14201 if (is_an_object)
14202 {
14203 // the initializer list is a list of pairs -> create object
14204 m_type = value_t::object;
14205 m_value = value_t::object;
14206
14207 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
14208 {
14209 auto element = element_ref.moved_or_copied();
14210 m_value.object->emplace(
14211 std::move(*((*element.m_value.array)[0].m_value.string)),
14212 std::move((*element.m_value.array)[1]));
14213 });
14214 }
14215 else
14216 {
14217 // the initializer list describes an array -> create array
14218 m_type = value_t::array;
14219 m_value.array = create<array_t>(init.begin(), init.end());
14220 }
14221
14222 assert_invariant();
14223 }
14224
14225 /*!
14226 @brief explicitly create an array from an initializer list
14227
14228 Creates a JSON array value from a given initializer list. That is, given a
14229 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
14230 initializer list is empty, the empty array `[]` is created.
14231
14232 @note This function is only needed to express two edge cases that cannot
14233 be realized with the initializer list constructor (@ref
14234 basic_json(initializer_list_t, bool, value_t)). These cases
14235 are:
14236 1. creating an array whose elements are all pairs whose first element is a
14237 string -- in this case, the initializer list constructor would create an
14238 object, taking the first elements as keys
14239 2. creating an empty array -- passing the empty initializer list to the
14240 initializer list constructor yields an empty object
14241
14242 @param[in] init initializer list with JSON values to create an array from
14243 (optional)
14244
14245 @return JSON array value
14246
14247 @complexity Linear in the size of @a init.
14248
14249 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14250 changes to any JSON value.
14251
14252 @liveexample{The following code shows an example for the `array`
14253 function.,array}
14254
14255 @sa @ref basic_json(initializer_list_t, bool, value_t) --
14256 create a JSON value from an initializer list
14257 @sa @ref object(initializer_list_t) -- create a JSON object
14258 value from an initializer list
14259
14260 @since version 1.0.0
14261 */
14262 JSON_NODISCARD
array(initializer_list_t init={})14263 static basic_json array(initializer_list_t init = {})
14264 {
14265 return basic_json(init, false, value_t::array);
14266 }
14267
14268 /*!
14269 @brief explicitly create an object from an initializer list
14270
14271 Creates a JSON object value from a given initializer list. The initializer
14272 lists elements must be pairs, and their first elements must be strings. If
14273 the initializer list is empty, the empty object `{}` is created.
14274
14275 @note This function is only added for symmetry reasons. In contrast to the
14276 related function @ref array(initializer_list_t), there are
14277 no cases which can only be expressed by this function. That is, any
14278 initializer list @a init can also be passed to the initializer list
14279 constructor @ref basic_json(initializer_list_t, bool, value_t).
14280
14281 @param[in] init initializer list to create an object from (optional)
14282
14283 @return JSON object value
14284
14285 @throw type_error.301 if @a init is not a list of pairs whose first
14286 elements are strings. In this case, no object can be created. When such a
14287 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
14288 an array would have been created from the passed initializer list @a init.
14289 See example below.
14290
14291 @complexity Linear in the size of @a init.
14292
14293 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14294 changes to any JSON value.
14295
14296 @liveexample{The following code shows an example for the `object`
14297 function.,object}
14298
14299 @sa @ref basic_json(initializer_list_t, bool, value_t) --
14300 create a JSON value from an initializer list
14301 @sa @ref array(initializer_list_t) -- create a JSON array
14302 value from an initializer list
14303
14304 @since version 1.0.0
14305 */
14306 JSON_NODISCARD
object(initializer_list_t init={})14307 static basic_json object(initializer_list_t init = {})
14308 {
14309 return basic_json(init, false, value_t::object);
14310 }
14311
14312 /*!
14313 @brief construct an array with count copies of given value
14314
14315 Constructs a JSON array value by creating @a cnt copies of a passed value.
14316 In case @a cnt is `0`, an empty array is created.
14317
14318 @param[in] cnt the number of JSON copies of @a val to create
14319 @param[in] val the JSON value to copy
14320
14321 @post `std::distance(begin(),end()) == cnt` holds.
14322
14323 @complexity Linear in @a cnt.
14324
14325 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14326 changes to any JSON value.
14327
14328 @liveexample{The following code shows examples for the @ref
14329 basic_json(size_type\, const basic_json&)
14330 constructor.,basic_json__size_type_basic_json}
14331
14332 @since version 1.0.0
14333 */
basic_json(size_type cnt,const basic_json & val)14334 basic_json(size_type cnt, const basic_json& val)
14335 : m_type(value_t::array)
14336 {
14337 m_value.array = create<array_t>(cnt, val);
14338 assert_invariant();
14339 }
14340
14341 /*!
14342 @brief construct a JSON container given an iterator range
14343
14344 Constructs the JSON value with the contents of the range `[first, last)`.
14345 The semantics depends on the different types a JSON value can have:
14346 - In case of a null type, invalid_iterator.206 is thrown.
14347 - In case of other primitive types (number, boolean, or string), @a first
14348 must be `begin()` and @a last must be `end()`. In this case, the value is
14349 copied. Otherwise, invalid_iterator.204 is thrown.
14350 - In case of structured types (array, object), the constructor behaves as
14351 similar versions for `std::vector` or `std::map`; that is, a JSON array
14352 or object is constructed from the values in the range.
14353
14354 @tparam InputIT an input iterator type (@ref iterator or @ref
14355 const_iterator)
14356
14357 @param[in] first begin of the range to copy from (included)
14358 @param[in] last end of the range to copy from (excluded)
14359
14360 @pre Iterators @a first and @a last must be initialized. **This
14361 precondition is enforced with an assertion (see warning).** If
14362 assertions are switched off, a violation of this precondition yields
14363 undefined behavior.
14364
14365 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
14366 checked efficiently. Only certain edge cases are detected; see the
14367 description of the exceptions below. A violation of this precondition
14368 yields undefined behavior.
14369
14370 @warning A precondition is enforced with a runtime assertion that will
14371 result in calling `std::abort` if this precondition is not met.
14372 Assertions can be disabled by defining `NDEBUG` at compile time.
14373 See https://en.cppreference.com/w/cpp/error/assert for more
14374 information.
14375
14376 @throw invalid_iterator.201 if iterators @a first and @a last are not
14377 compatible (i.e., do not belong to the same JSON value). In this case,
14378 the range `[first, last)` is undefined.
14379 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
14380 primitive type (number, boolean, or string), but @a first does not point
14381 to the first element any more. In this case, the range `[first, last)` is
14382 undefined. See example code below.
14383 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
14384 null value. In this case, the range `[first, last)` is undefined.
14385
14386 @complexity Linear in distance between @a first and @a last.
14387
14388 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14389 changes to any JSON value.
14390
14391 @liveexample{The example below shows several ways to create JSON values by
14392 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
14393
14394 @since version 1.0.0
14395 */
14396 template<class InputIT, typename std::enable_if<
14397 std::is_same<InputIT, typename basic_json_t::iterator>::value or
14398 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)14399 basic_json(InputIT first, InputIT last)
14400 {
14401 assert(first.m_object != nullptr);
14402 assert(last.m_object != nullptr);
14403
14404 // make sure iterator fits the current value
14405 if (JSON_UNLIKELY(first.m_object != last.m_object))
14406 {
14407 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
14408 }
14409
14410 // copy type from first iterator
14411 m_type = first.m_object->m_type;
14412
14413 // check if iterator range is complete for primitive values
14414 switch (m_type)
14415 {
14416 case value_t::boolean:
14417 case value_t::number_float:
14418 case value_t::number_integer:
14419 case value_t::number_unsigned:
14420 case value_t::string:
14421 {
14422 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
14423 or not last.m_it.primitive_iterator.is_end()))
14424 {
14425 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
14426 }
14427 break;
14428 }
14429
14430 default:
14431 break;
14432 }
14433
14434 switch (m_type)
14435 {
14436 case value_t::number_integer:
14437 {
14438 m_value.number_integer = first.m_object->m_value.number_integer;
14439 break;
14440 }
14441
14442 case value_t::number_unsigned:
14443 {
14444 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
14445 break;
14446 }
14447
14448 case value_t::number_float:
14449 {
14450 m_value.number_float = first.m_object->m_value.number_float;
14451 break;
14452 }
14453
14454 case value_t::boolean:
14455 {
14456 m_value.boolean = first.m_object->m_value.boolean;
14457 break;
14458 }
14459
14460 case value_t::string:
14461 {
14462 m_value = *first.m_object->m_value.string;
14463 break;
14464 }
14465
14466 case value_t::object:
14467 {
14468 m_value.object = create<object_t>(first.m_it.object_iterator,
14469 last.m_it.object_iterator);
14470 break;
14471 }
14472
14473 case value_t::array:
14474 {
14475 m_value.array = create<array_t>(first.m_it.array_iterator,
14476 last.m_it.array_iterator);
14477 break;
14478 }
14479
14480 default:
14481 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
14482 std::string(first.m_object->type_name())));
14483 }
14484
14485 assert_invariant();
14486 }
14487
14488
14489 ///////////////////////////////////////
14490 // other constructors and destructor //
14491 ///////////////////////////////////////
14492
14493 /// @private
basic_json(const detail::json_ref<basic_json> & ref)14494 basic_json(const detail::json_ref<basic_json>& ref)
14495 : basic_json(ref.moved_or_copied())
14496 {}
14497
14498 /*!
14499 @brief copy constructor
14500
14501 Creates a copy of a given JSON value.
14502
14503 @param[in] other the JSON value to copy
14504
14505 @post `*this == other`
14506
14507 @complexity Linear in the size of @a other.
14508
14509 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14510 changes to any JSON value.
14511
14512 @requirement This function helps `basic_json` satisfying the
14513 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14514 requirements:
14515 - The complexity is linear.
14516 - As postcondition, it holds: `other == basic_json(other)`.
14517
14518 @liveexample{The following code shows an example for the copy
14519 constructor.,basic_json__basic_json}
14520
14521 @since version 1.0.0
14522 */
basic_json(const basic_json & other)14523 basic_json(const basic_json& other)
14524 : m_type(other.m_type)
14525 {
14526 // check of passed value is valid
14527 other.assert_invariant();
14528
14529 switch (m_type)
14530 {
14531 case value_t::object:
14532 {
14533 m_value = *other.m_value.object;
14534 break;
14535 }
14536
14537 case value_t::array:
14538 {
14539 m_value = *other.m_value.array;
14540 break;
14541 }
14542
14543 case value_t::string:
14544 {
14545 m_value = *other.m_value.string;
14546 break;
14547 }
14548
14549 case value_t::boolean:
14550 {
14551 m_value = other.m_value.boolean;
14552 break;
14553 }
14554
14555 case value_t::number_integer:
14556 {
14557 m_value = other.m_value.number_integer;
14558 break;
14559 }
14560
14561 case value_t::number_unsigned:
14562 {
14563 m_value = other.m_value.number_unsigned;
14564 break;
14565 }
14566
14567 case value_t::number_float:
14568 {
14569 m_value = other.m_value.number_float;
14570 break;
14571 }
14572
14573 default:
14574 break;
14575 }
14576
14577 assert_invariant();
14578 }
14579
14580 /*!
14581 @brief move constructor
14582
14583 Move constructor. Constructs a JSON value with the contents of the given
14584 value @a other using move semantics. It "steals" the resources from @a
14585 other and leaves it as JSON null value.
14586
14587 @param[in,out] other value to move to this object
14588
14589 @post `*this` has the same value as @a other before the call.
14590 @post @a other is a JSON null value.
14591
14592 @complexity Constant.
14593
14594 @exceptionsafety No-throw guarantee: this constructor never throws
14595 exceptions.
14596
14597 @requirement This function helps `basic_json` satisfying the
14598 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
14599 requirements.
14600
14601 @liveexample{The code below shows the move constructor explicitly called
14602 via std::move.,basic_json__moveconstructor}
14603
14604 @since version 1.0.0
14605 */
basic_json(basic_json && other)14606 basic_json(basic_json&& other) noexcept
14607 : m_type(std::move(other.m_type)),
14608 m_value(std::move(other.m_value))
14609 {
14610 // check that passed value is valid
14611 other.assert_invariant();
14612
14613 // invalidate payload
14614 other.m_type = value_t::null;
14615 other.m_value = {};
14616
14617 assert_invariant();
14618 }
14619
14620 /*!
14621 @brief copy assignment
14622
14623 Copy assignment operator. Copies a JSON value via the "copy and swap"
14624 strategy: It is expressed in terms of the copy constructor, destructor,
14625 and the `swap()` member function.
14626
14627 @param[in] other value to copy from
14628
14629 @complexity Linear.
14630
14631 @requirement This function helps `basic_json` satisfying the
14632 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14633 requirements:
14634 - The complexity is linear.
14635
14636 @liveexample{The code below shows and example for the copy assignment. It
14637 creates a copy of value `a` which is then swapped with `b`. Finally\, the
14638 copy of `a` (which is the null value after the swap) is
14639 destroyed.,basic_json__copyassignment}
14640
14641 @since version 1.0.0
14642 */
operator =(basic_json other)14643 basic_json& operator=(basic_json other) noexcept (
14644 std::is_nothrow_move_constructible<value_t>::value and
14645 std::is_nothrow_move_assignable<value_t>::value and
14646 std::is_nothrow_move_constructible<json_value>::value and
14647 std::is_nothrow_move_assignable<json_value>::value
14648 )
14649 {
14650 // check that passed value is valid
14651 other.assert_invariant();
14652
14653 using std::swap;
14654 swap(m_type, other.m_type);
14655 swap(m_value, other.m_value);
14656
14657 assert_invariant();
14658 return *this;
14659 }
14660
14661 /*!
14662 @brief destructor
14663
14664 Destroys the JSON value and frees all allocated memory.
14665
14666 @complexity Linear.
14667
14668 @requirement This function helps `basic_json` satisfying the
14669 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14670 requirements:
14671 - The complexity is linear.
14672 - All stored elements are destroyed and all memory is freed.
14673
14674 @since version 1.0.0
14675 */
~basic_json()14676 ~basic_json() noexcept
14677 {
14678 assert_invariant();
14679 m_value.destroy(m_type);
14680 }
14681
14682 /// @}
14683
14684 public:
14685 ///////////////////////
14686 // object inspection //
14687 ///////////////////////
14688
14689 /// @name object inspection
14690 /// Functions to inspect the type of a JSON value.
14691 /// @{
14692
14693 /*!
14694 @brief serialization
14695
14696 Serialization function for JSON values. The function tries to mimic
14697 Python's `json.dumps()` function, and currently supports its @a indent
14698 and @a ensure_ascii parameters.
14699
14700 @param[in] indent If indent is nonnegative, then array elements and object
14701 members will be pretty-printed with that indent level. An indent level of
14702 `0` will only insert newlines. `-1` (the default) selects the most compact
14703 representation.
14704 @param[in] indent_char The character to use for indentation if @a indent is
14705 greater than `0`. The default is ` ` (space).
14706 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
14707 in the output are escaped with `\uXXXX` sequences, and the result consists
14708 of ASCII characters only.
14709 @param[in] error_handler how to react on decoding errors; there are three
14710 possible values: `strict` (throws and exception in case a decoding error
14711 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
14712 and `ignore` (ignore invalid UTF-8 sequences during serialization).
14713
14714 @return string containing the serialization of the JSON value
14715
14716 @throw type_error.316 if a string stored inside the JSON value is not
14717 UTF-8 encoded
14718
14719 @complexity Linear.
14720
14721 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14722 changes in the JSON value.
14723
14724 @liveexample{The following example shows the effect of different @a indent\,
14725 @a indent_char\, and @a ensure_ascii parameters to the result of the
14726 serialization.,dump}
14727
14728 @see https://docs.python.org/2/library/json.html#json.dump
14729
14730 @since version 1.0.0; indentation character @a indent_char, option
14731 @a ensure_ascii and exceptions added in version 3.0.0; error
14732 handlers added in version 3.4.0.
14733 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const14734 string_t dump(const int indent = -1,
14735 const char indent_char = ' ',
14736 const bool ensure_ascii = false,
14737 const error_handler_t error_handler = error_handler_t::strict) const
14738 {
14739 string_t result;
14740 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14741
14742 if (indent >= 0)
14743 {
14744 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
14745 }
14746 else
14747 {
14748 s.dump(*this, false, ensure_ascii, 0);
14749 }
14750
14751 return result;
14752 }
14753
14754 /*!
14755 @brief return the type of the JSON value (explicit)
14756
14757 Return the type of the JSON value as a value from the @ref value_t
14758 enumeration.
14759
14760 @return the type of the JSON value
14761 Value type | return value
14762 ------------------------- | -------------------------
14763 null | value_t::null
14764 boolean | value_t::boolean
14765 string | value_t::string
14766 number (integer) | value_t::number_integer
14767 number (unsigned integer) | value_t::number_unsigned
14768 number (floating-point) | value_t::number_float
14769 object | value_t::object
14770 array | value_t::array
14771 discarded | value_t::discarded
14772
14773 @complexity Constant.
14774
14775 @exceptionsafety No-throw guarantee: this member function never throws
14776 exceptions.
14777
14778 @liveexample{The following code exemplifies `type()` for all JSON
14779 types.,type}
14780
14781 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
14782 @sa @ref type_name() -- return the type as string
14783
14784 @since version 1.0.0
14785 */
type() const14786 constexpr value_t type() const noexcept
14787 {
14788 return m_type;
14789 }
14790
14791 /*!
14792 @brief return whether type is primitive
14793
14794 This function returns true if and only if the JSON type is primitive
14795 (string, number, boolean, or null).
14796
14797 @return `true` if type is primitive (string, number, boolean, or null),
14798 `false` otherwise.
14799
14800 @complexity Constant.
14801
14802 @exceptionsafety No-throw guarantee: this member function never throws
14803 exceptions.
14804
14805 @liveexample{The following code exemplifies `is_primitive()` for all JSON
14806 types.,is_primitive}
14807
14808 @sa @ref is_structured() -- returns whether JSON value is structured
14809 @sa @ref is_null() -- returns whether JSON value is `null`
14810 @sa @ref is_string() -- returns whether JSON value is a string
14811 @sa @ref is_boolean() -- returns whether JSON value is a boolean
14812 @sa @ref is_number() -- returns whether JSON value is a number
14813
14814 @since version 1.0.0
14815 */
is_primitive() const14816 constexpr bool is_primitive() const noexcept
14817 {
14818 return is_null() or is_string() or is_boolean() or is_number();
14819 }
14820
14821 /*!
14822 @brief return whether type is structured
14823
14824 This function returns true if and only if the JSON type is structured
14825 (array or object).
14826
14827 @return `true` if type is structured (array or object), `false` otherwise.
14828
14829 @complexity Constant.
14830
14831 @exceptionsafety No-throw guarantee: this member function never throws
14832 exceptions.
14833
14834 @liveexample{The following code exemplifies `is_structured()` for all JSON
14835 types.,is_structured}
14836
14837 @sa @ref is_primitive() -- returns whether value is primitive
14838 @sa @ref is_array() -- returns whether value is an array
14839 @sa @ref is_object() -- returns whether value is an object
14840
14841 @since version 1.0.0
14842 */
is_structured() const14843 constexpr bool is_structured() const noexcept
14844 {
14845 return is_array() or is_object();
14846 }
14847
14848 /*!
14849 @brief return whether value is null
14850
14851 This function returns true if and only if the JSON value is null.
14852
14853 @return `true` if type is null, `false` otherwise.
14854
14855 @complexity Constant.
14856
14857 @exceptionsafety No-throw guarantee: this member function never throws
14858 exceptions.
14859
14860 @liveexample{The following code exemplifies `is_null()` for all JSON
14861 types.,is_null}
14862
14863 @since version 1.0.0
14864 */
is_null() const14865 constexpr bool is_null() const noexcept
14866 {
14867 return m_type == value_t::null;
14868 }
14869
14870 /*!
14871 @brief return whether value is a boolean
14872
14873 This function returns true if and only if the JSON value is a boolean.
14874
14875 @return `true` if type is boolean, `false` otherwise.
14876
14877 @complexity Constant.
14878
14879 @exceptionsafety No-throw guarantee: this member function never throws
14880 exceptions.
14881
14882 @liveexample{The following code exemplifies `is_boolean()` for all JSON
14883 types.,is_boolean}
14884
14885 @since version 1.0.0
14886 */
is_boolean() const14887 constexpr bool is_boolean() const noexcept
14888 {
14889 return m_type == value_t::boolean;
14890 }
14891
14892 /*!
14893 @brief return whether value is a number
14894
14895 This function returns true if and only if the JSON value is a number. This
14896 includes both integer (signed and unsigned) and floating-point values.
14897
14898 @return `true` if type is number (regardless whether integer, unsigned
14899 integer or floating-type), `false` otherwise.
14900
14901 @complexity Constant.
14902
14903 @exceptionsafety No-throw guarantee: this member function never throws
14904 exceptions.
14905
14906 @liveexample{The following code exemplifies `is_number()` for all JSON
14907 types.,is_number}
14908
14909 @sa @ref is_number_integer() -- check if value is an integer or unsigned
14910 integer number
14911 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14912 number
14913 @sa @ref is_number_float() -- check if value is a floating-point number
14914
14915 @since version 1.0.0
14916 */
is_number() const14917 constexpr bool is_number() const noexcept
14918 {
14919 return is_number_integer() or is_number_float();
14920 }
14921
14922 /*!
14923 @brief return whether value is an integer number
14924
14925 This function returns true if and only if the JSON value is a signed or
14926 unsigned integer number. This excludes floating-point values.
14927
14928 @return `true` if type is an integer or unsigned integer number, `false`
14929 otherwise.
14930
14931 @complexity Constant.
14932
14933 @exceptionsafety No-throw guarantee: this member function never throws
14934 exceptions.
14935
14936 @liveexample{The following code exemplifies `is_number_integer()` for all
14937 JSON types.,is_number_integer}
14938
14939 @sa @ref is_number() -- check if value is a number
14940 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14941 number
14942 @sa @ref is_number_float() -- check if value is a floating-point number
14943
14944 @since version 1.0.0
14945 */
is_number_integer() const14946 constexpr bool is_number_integer() const noexcept
14947 {
14948 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
14949 }
14950
14951 /*!
14952 @brief return whether value is an unsigned integer number
14953
14954 This function returns true if and only if the JSON value is an unsigned
14955 integer number. This excludes floating-point and signed integer values.
14956
14957 @return `true` if type is an unsigned integer number, `false` otherwise.
14958
14959 @complexity Constant.
14960
14961 @exceptionsafety No-throw guarantee: this member function never throws
14962 exceptions.
14963
14964 @liveexample{The following code exemplifies `is_number_unsigned()` for all
14965 JSON types.,is_number_unsigned}
14966
14967 @sa @ref is_number() -- check if value is a number
14968 @sa @ref is_number_integer() -- check if value is an integer or unsigned
14969 integer number
14970 @sa @ref is_number_float() -- check if value is a floating-point number
14971
14972 @since version 2.0.0
14973 */
is_number_unsigned() const14974 constexpr bool is_number_unsigned() const noexcept
14975 {
14976 return m_type == value_t::number_unsigned;
14977 }
14978
14979 /*!
14980 @brief return whether value is a floating-point number
14981
14982 This function returns true if and only if the JSON value is a
14983 floating-point number. This excludes signed and unsigned integer values.
14984
14985 @return `true` if type is a floating-point number, `false` otherwise.
14986
14987 @complexity Constant.
14988
14989 @exceptionsafety No-throw guarantee: this member function never throws
14990 exceptions.
14991
14992 @liveexample{The following code exemplifies `is_number_float()` for all
14993 JSON types.,is_number_float}
14994
14995 @sa @ref is_number() -- check if value is number
14996 @sa @ref is_number_integer() -- check if value is an integer number
14997 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14998 number
14999
15000 @since version 1.0.0
15001 */
is_number_float() const15002 constexpr bool is_number_float() const noexcept
15003 {
15004 return m_type == value_t::number_float;
15005 }
15006
15007 /*!
15008 @brief return whether value is an object
15009
15010 This function returns true if and only if the JSON value is an object.
15011
15012 @return `true` if type is object, `false` otherwise.
15013
15014 @complexity Constant.
15015
15016 @exceptionsafety No-throw guarantee: this member function never throws
15017 exceptions.
15018
15019 @liveexample{The following code exemplifies `is_object()` for all JSON
15020 types.,is_object}
15021
15022 @since version 1.0.0
15023 */
is_object() const15024 constexpr bool is_object() const noexcept
15025 {
15026 return m_type == value_t::object;
15027 }
15028
15029 /*!
15030 @brief return whether value is an array
15031
15032 This function returns true if and only if the JSON value is an array.
15033
15034 @return `true` if type is array, `false` otherwise.
15035
15036 @complexity Constant.
15037
15038 @exceptionsafety No-throw guarantee: this member function never throws
15039 exceptions.
15040
15041 @liveexample{The following code exemplifies `is_array()` for all JSON
15042 types.,is_array}
15043
15044 @since version 1.0.0
15045 */
is_array() const15046 constexpr bool is_array() const noexcept
15047 {
15048 return m_type == value_t::array;
15049 }
15050
15051 /*!
15052 @brief return whether value is a string
15053
15054 This function returns true if and only if the JSON value is a string.
15055
15056 @return `true` if type is string, `false` otherwise.
15057
15058 @complexity Constant.
15059
15060 @exceptionsafety No-throw guarantee: this member function never throws
15061 exceptions.
15062
15063 @liveexample{The following code exemplifies `is_string()` for all JSON
15064 types.,is_string}
15065
15066 @since version 1.0.0
15067 */
is_string() const15068 constexpr bool is_string() const noexcept
15069 {
15070 return m_type == value_t::string;
15071 }
15072
15073 /*!
15074 @brief return whether value is discarded
15075
15076 This function returns true if and only if the JSON value was discarded
15077 during parsing with a callback function (see @ref parser_callback_t).
15078
15079 @note This function will always be `false` for JSON values after parsing.
15080 That is, discarded values can only occur during parsing, but will be
15081 removed when inside a structured value or replaced by null in other cases.
15082
15083 @return `true` if type is discarded, `false` otherwise.
15084
15085 @complexity Constant.
15086
15087 @exceptionsafety No-throw guarantee: this member function never throws
15088 exceptions.
15089
15090 @liveexample{The following code exemplifies `is_discarded()` for all JSON
15091 types.,is_discarded}
15092
15093 @since version 1.0.0
15094 */
is_discarded() const15095 constexpr bool is_discarded() const noexcept
15096 {
15097 return m_type == value_t::discarded;
15098 }
15099
15100 /*!
15101 @brief return the type of the JSON value (implicit)
15102
15103 Implicitly return the type of the JSON value as a value from the @ref
15104 value_t enumeration.
15105
15106 @return the type of the JSON value
15107
15108 @complexity Constant.
15109
15110 @exceptionsafety No-throw guarantee: this member function never throws
15111 exceptions.
15112
15113 @liveexample{The following code exemplifies the @ref value_t operator for
15114 all JSON types.,operator__value_t}
15115
15116 @sa @ref type() -- return the type of the JSON value (explicit)
15117 @sa @ref type_name() -- return the type as string
15118
15119 @since version 1.0.0
15120 */
operator value_t() const15121 constexpr operator value_t() const noexcept
15122 {
15123 return m_type;
15124 }
15125
15126 /// @}
15127
15128 private:
15129 //////////////////
15130 // value access //
15131 //////////////////
15132
15133 /// get a boolean (explicit)
get_impl(boolean_t *) const15134 boolean_t get_impl(boolean_t* /*unused*/) const
15135 {
15136 if (JSON_LIKELY(is_boolean()))
15137 {
15138 return m_value.boolean;
15139 }
15140
15141 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
15142 }
15143
15144 /// get a pointer to the value (object)
get_impl_ptr(object_t *)15145 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
15146 {
15147 return is_object() ? m_value.object : nullptr;
15148 }
15149
15150 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const15151 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
15152 {
15153 return is_object() ? m_value.object : nullptr;
15154 }
15155
15156 /// get a pointer to the value (array)
get_impl_ptr(array_t *)15157 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
15158 {
15159 return is_array() ? m_value.array : nullptr;
15160 }
15161
15162 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const15163 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
15164 {
15165 return is_array() ? m_value.array : nullptr;
15166 }
15167
15168 /// get a pointer to the value (string)
get_impl_ptr(string_t *)15169 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
15170 {
15171 return is_string() ? m_value.string : nullptr;
15172 }
15173
15174 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const15175 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
15176 {
15177 return is_string() ? m_value.string : nullptr;
15178 }
15179
15180 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)15181 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
15182 {
15183 return is_boolean() ? &m_value.boolean : nullptr;
15184 }
15185
15186 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const15187 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
15188 {
15189 return is_boolean() ? &m_value.boolean : nullptr;
15190 }
15191
15192 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)15193 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
15194 {
15195 return is_number_integer() ? &m_value.number_integer : nullptr;
15196 }
15197
15198 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const15199 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
15200 {
15201 return is_number_integer() ? &m_value.number_integer : nullptr;
15202 }
15203
15204 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)15205 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
15206 {
15207 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15208 }
15209
15210 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const15211 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
15212 {
15213 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15214 }
15215
15216 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)15217 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
15218 {
15219 return is_number_float() ? &m_value.number_float : nullptr;
15220 }
15221
15222 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const15223 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
15224 {
15225 return is_number_float() ? &m_value.number_float : nullptr;
15226 }
15227
15228 /*!
15229 @brief helper function to implement get_ref()
15230
15231 This function helps to implement get_ref() without code duplication for
15232 const and non-const overloads
15233
15234 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
15235
15236 @throw type_error.303 if ReferenceType does not match underlying value
15237 type of the current JSON
15238 */
15239 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)15240 static ReferenceType get_ref_impl(ThisType& obj)
15241 {
15242 // delegate the call to get_ptr<>()
15243 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
15244
15245 if (JSON_LIKELY(ptr != nullptr))
15246 {
15247 return *ptr;
15248 }
15249
15250 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
15251 }
15252
15253 public:
15254 /// @name value access
15255 /// Direct access to the stored value of a JSON value.
15256 /// @{
15257
15258 /*!
15259 @brief get special-case overload
15260
15261 This overloads avoids a lot of template boilerplate, it can be seen as the
15262 identity method
15263
15264 @tparam BasicJsonType == @ref basic_json
15265
15266 @return a copy of *this
15267
15268 @complexity Constant.
15269
15270 @since version 2.1.0
15271 */
15272 template<typename BasicJsonType, detail::enable_if_t<
15273 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
15274 int> = 0>
get() const15275 basic_json get() const
15276 {
15277 return *this;
15278 }
15279
15280 /*!
15281 @brief get special-case overload
15282
15283 This overloads converts the current @ref basic_json in a different
15284 @ref basic_json type
15285
15286 @tparam BasicJsonType == @ref basic_json
15287
15288 @return a copy of *this, converted into @tparam BasicJsonType
15289
15290 @complexity Depending on the implementation of the called `from_json()`
15291 method.
15292
15293 @since version 3.2.0
15294 */
15295 template<typename BasicJsonType, detail::enable_if_t<
15296 not std::is_same<BasicJsonType, basic_json>::value and
15297 detail::is_basic_json<BasicJsonType>::value, int> = 0>
15298 BasicJsonType get() const
15299 {
15300 return *this;
15301 }
15302
15303 /*!
15304 @brief get a value (explicit)
15305
15306 Explicit type conversion between the JSON value and a compatible value
15307 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
15308 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
15309 The value is converted by calling the @ref json_serializer<ValueType>
15310 `from_json()` method.
15311
15312 The function is equivalent to executing
15313 @code {.cpp}
15314 ValueType ret;
15315 JSONSerializer<ValueType>::from_json(*this, ret);
15316 return ret;
15317 @endcode
15318
15319 This overloads is chosen if:
15320 - @a ValueType is not @ref basic_json,
15321 - @ref json_serializer<ValueType> has a `from_json()` method of the form
15322 `void from_json(const basic_json&, ValueType&)`, and
15323 - @ref json_serializer<ValueType> does not have a `from_json()` method of
15324 the form `ValueType from_json(const basic_json&)`
15325
15326 @tparam ValueTypeCV the provided value type
15327 @tparam ValueType the returned value type
15328
15329 @return copy of the JSON value, converted to @a ValueType
15330
15331 @throw what @ref json_serializer<ValueType> `from_json()` method throws
15332
15333 @liveexample{The example below shows several conversions from JSON values
15334 to other types. There a few things to note: (1) Floating-point numbers can
15335 be converted to integers\, (2) A JSON array can be converted to a standard
15336 `std::vector<short>`\, (3) A JSON object can be converted to C++
15337 associative containers such as `std::unordered_map<std::string\,
15338 json>`.,get__ValueType_const}
15339
15340 @since version 2.1.0
15341 */
15342 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
15343 detail::enable_if_t <
15344 not detail::is_basic_json<ValueType>::value and
15345 detail::has_from_json<basic_json_t, ValueType>::value and
15346 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15347 int> = 0>
15348 ValueType get() const noexcept(noexcept(
15349 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
15350 {
15351 // we cannot static_assert on ValueTypeCV being non-const, because
15352 // there is support for get<const basic_json_t>(), which is why we
15353 // still need the uncvref
15354 static_assert(not std::is_reference<ValueTypeCV>::value,
15355 "get() cannot be used with reference types, you might want to use get_ref()");
15356 static_assert(std::is_default_constructible<ValueType>::value,
15357 "types must be DefaultConstructible when used with get()");
15358
15359 ValueType ret;
15360 JSONSerializer<ValueType>::from_json(*this, ret);
15361 return ret;
15362 }
15363
15364 /*!
15365 @brief get a value (explicit); special case
15366
15367 Explicit type conversion between the JSON value and a compatible value
15368 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
15369 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
15370 The value is converted by calling the @ref json_serializer<ValueType>
15371 `from_json()` method.
15372
15373 The function is equivalent to executing
15374 @code {.cpp}
15375 return JSONSerializer<ValueTypeCV>::from_json(*this);
15376 @endcode
15377
15378 This overloads is chosen if:
15379 - @a ValueType is not @ref basic_json and
15380 - @ref json_serializer<ValueType> has a `from_json()` method of the form
15381 `ValueType from_json(const basic_json&)`
15382
15383 @note If @ref json_serializer<ValueType> has both overloads of
15384 `from_json()`, this one is chosen.
15385
15386 @tparam ValueTypeCV the provided value type
15387 @tparam ValueType the returned value type
15388
15389 @return copy of the JSON value, converted to @a ValueType
15390
15391 @throw what @ref json_serializer<ValueType> `from_json()` method throws
15392
15393 @since version 2.1.0
15394 */
15395 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
15396 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
15397 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15398 int> = 0>
15399 ValueType get() const noexcept(noexcept(
15400 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
15401 {
15402 static_assert(not std::is_reference<ValueTypeCV>::value,
15403 "get() cannot be used with reference types, you might want to use get_ref()");
15404 return JSONSerializer<ValueTypeCV>::from_json(*this);
15405 }
15406
15407 /*!
15408 @brief get a value (explicit)
15409
15410 Explicit type conversion between the JSON value and a compatible value.
15411 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
15412 `from_json()` method.
15413
15414 The function is equivalent to executing
15415 @code {.cpp}
15416 ValueType v;
15417 JSONSerializer<ValueType>::from_json(*this, v);
15418 @endcode
15419
15420 This overloads is chosen if:
15421 - @a ValueType is not @ref basic_json,
15422 - @ref json_serializer<ValueType> has a `from_json()` method of the form
15423 `void from_json(const basic_json&, ValueType&)`, and
15424
15425 @tparam ValueType the input parameter type.
15426
15427 @return the input parameter, allowing chaining calls.
15428
15429 @throw what @ref json_serializer<ValueType> `from_json()` method throws
15430
15431 @liveexample{The example below shows several conversions from JSON values
15432 to other types. There a few things to note: (1) Floating-point numbers can
15433 be converted to integers\, (2) A JSON array can be converted to a standard
15434 `std::vector<short>`\, (3) A JSON object can be converted to C++
15435 associative containers such as `std::unordered_map<std::string\,
15436 json>`.,get_to}
15437
15438 @since version 3.3.0
15439 */
15440 template<typename ValueType,
15441 detail::enable_if_t <
15442 not detail::is_basic_json<ValueType>::value and
15443 detail::has_from_json<basic_json_t, ValueType>::value,
15444 int> = 0>
15445 ValueType & get_to(ValueType& v) const noexcept(noexcept(
15446 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
15447 {
15448 JSONSerializer<ValueType>::from_json(*this, v);
15449 return v;
15450 }
15451
15452
15453 /*!
15454 @brief get a pointer value (implicit)
15455
15456 Implicit pointer access to the internally stored JSON value. No copies are
15457 made.
15458
15459 @warning Writing data to the pointee of the result yields an undefined
15460 state.
15461
15462 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
15463 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
15464 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
15465 assertion.
15466
15467 @return pointer to the internally stored JSON value if the requested
15468 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
15469
15470 @complexity Constant.
15471
15472 @liveexample{The example below shows how pointers to internal values of a
15473 JSON value can be requested. Note that no type conversions are made and a
15474 `nullptr` is returned if the value and the requested pointer type does not
15475 match.,get_ptr}
15476
15477 @since version 1.0.0
15478 */
15479 template<typename PointerType, typename std::enable_if<
15480 std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()15481 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15482 {
15483 // delegate the call to get_impl_ptr<>()
15484 return get_impl_ptr(static_cast<PointerType>(nullptr));
15485 }
15486
15487 /*!
15488 @brief get a pointer value (implicit)
15489 @copydoc get_ptr()
15490 */
15491 template<typename PointerType, typename std::enable_if<
15492 std::is_pointer<PointerType>::value and
15493 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const15494 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15495 {
15496 // delegate the call to get_impl_ptr<>() const
15497 return get_impl_ptr(static_cast<PointerType>(nullptr));
15498 }
15499
15500 /*!
15501 @brief get a pointer value (explicit)
15502
15503 Explicit pointer access to the internally stored JSON value. No copies are
15504 made.
15505
15506 @warning The pointer becomes invalid if the underlying JSON object
15507 changes.
15508
15509 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
15510 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
15511 @ref number_unsigned_t, or @ref number_float_t.
15512
15513 @return pointer to the internally stored JSON value if the requested
15514 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
15515
15516 @complexity Constant.
15517
15518 @liveexample{The example below shows how pointers to internal values of a
15519 JSON value can be requested. Note that no type conversions are made and a
15520 `nullptr` is returned if the value and the requested pointer type does not
15521 match.,get__PointerType}
15522
15523 @sa @ref get_ptr() for explicit pointer-member access
15524
15525 @since version 1.0.0
15526 */
15527 template<typename PointerType, typename std::enable_if<
15528 std::is_pointer<PointerType>::value, int>::type = 0>
get()15529 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
15530 {
15531 // delegate the call to get_ptr
15532 return get_ptr<PointerType>();
15533 }
15534
15535 /*!
15536 @brief get a pointer value (explicit)
15537 @copydoc get()
15538 */
15539 template<typename PointerType, typename std::enable_if<
15540 std::is_pointer<PointerType>::value, int>::type = 0>
get() const15541 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15542 {
15543 // delegate the call to get_ptr
15544 return get_ptr<PointerType>();
15545 }
15546
15547 /*!
15548 @brief get a reference value (implicit)
15549
15550 Implicit reference access to the internally stored JSON value. No copies
15551 are made.
15552
15553 @warning Writing data to the referee of the result yields an undefined
15554 state.
15555
15556 @tparam ReferenceType reference type; must be a reference to @ref array_t,
15557 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
15558 @ref number_float_t. Enforced by static assertion.
15559
15560 @return reference to the internally stored JSON value if the requested
15561 reference type @a ReferenceType fits to the JSON value; throws
15562 type_error.303 otherwise
15563
15564 @throw type_error.303 in case passed type @a ReferenceType is incompatible
15565 with the stored JSON value; see example below
15566
15567 @complexity Constant.
15568
15569 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
15570
15571 @since version 1.1.0
15572 */
15573 template<typename ReferenceType, typename std::enable_if<
15574 std::is_reference<ReferenceType>::value, int>::type = 0>
15575 ReferenceType get_ref()
15576 {
15577 // delegate call to get_ref_impl
15578 return get_ref_impl<ReferenceType>(*this);
15579 }
15580
15581 /*!
15582 @brief get a reference value (implicit)
15583 @copydoc get_ref()
15584 */
15585 template<typename ReferenceType, typename std::enable_if<
15586 std::is_reference<ReferenceType>::value and
15587 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
15588 ReferenceType get_ref() const
15589 {
15590 // delegate call to get_ref_impl
15591 return get_ref_impl<ReferenceType>(*this);
15592 }
15593
15594 /*!
15595 @brief get a value (implicit)
15596
15597 Implicit type conversion between the JSON value and a compatible value.
15598 The call is realized by calling @ref get() const.
15599
15600 @tparam ValueType non-pointer type compatible to the JSON value, for
15601 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
15602 `std::vector` types for JSON arrays. The character type of @ref string_t
15603 as well as an initializer list of this type is excluded to avoid
15604 ambiguities as these types implicitly convert to `std::string`.
15605
15606 @return copy of the JSON value, converted to type @a ValueType
15607
15608 @throw type_error.302 in case passed type @a ValueType is incompatible
15609 to the JSON value type (e.g., the JSON value is of type boolean, but a
15610 string is requested); see example below
15611
15612 @complexity Linear in the size of the JSON value.
15613
15614 @liveexample{The example below shows several conversions from JSON values
15615 to other types. There a few things to note: (1) Floating-point numbers can
15616 be converted to integers\, (2) A JSON array can be converted to a standard
15617 `std::vector<short>`\, (3) A JSON object can be converted to C++
15618 associative containers such as `std::unordered_map<std::string\,
15619 json>`.,operator__ValueType}
15620
15621 @since version 1.0.0
15622 */
15623 template < typename ValueType, typename std::enable_if <
15624 not std::is_pointer<ValueType>::value and
15625 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15626 not std::is_same<ValueType, typename string_t::value_type>::value and
15627 not detail::is_basic_json<ValueType>::value
15628
15629 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
15630 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15631 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
15632 and not std::is_same<ValueType, typename std::string_view>::value
15633 #endif
15634 #endif
15635 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
15636 , int >::type = 0 >
operator ValueType() const15637 operator ValueType() const
15638 {
15639 // delegate the call to get<>() const
15640 return get<ValueType>();
15641 }
15642
15643 /// @}
15644
15645
15646 ////////////////////
15647 // element access //
15648 ////////////////////
15649
15650 /// @name element access
15651 /// Access to the JSON value.
15652 /// @{
15653
15654 /*!
15655 @brief access specified array element with bounds checking
15656
15657 Returns a reference to the element at specified location @a idx, with
15658 bounds checking.
15659
15660 @param[in] idx index of the element to access
15661
15662 @return reference to the element at index @a idx
15663
15664 @throw type_error.304 if the JSON value is not an array; in this case,
15665 calling `at` with an index makes no sense. See example below.
15666 @throw out_of_range.401 if the index @a idx is out of range of the array;
15667 that is, `idx >= size()`. See example below.
15668
15669 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15670 changes in the JSON value.
15671
15672 @complexity Constant.
15673
15674 @since version 1.0.0
15675
15676 @liveexample{The example below shows how array elements can be read and
15677 written using `at()`. It also demonstrates the different exceptions that
15678 can be thrown.,at__size_type}
15679 */
at(size_type idx)15680 reference at(size_type idx)
15681 {
15682 // at only works for arrays
15683 if (JSON_LIKELY(is_array()))
15684 {
15685 JSON_TRY
15686 {
15687 return m_value.array->at(idx);
15688 }
15689 JSON_CATCH (std::out_of_range&)
15690 {
15691 // create better exception explanation
15692 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15693 }
15694 }
15695 else
15696 {
15697 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15698 }
15699 }
15700
15701 /*!
15702 @brief access specified array element with bounds checking
15703
15704 Returns a const reference to the element at specified location @a idx,
15705 with bounds checking.
15706
15707 @param[in] idx index of the element to access
15708
15709 @return const reference to the element at index @a idx
15710
15711 @throw type_error.304 if the JSON value is not an array; in this case,
15712 calling `at` with an index makes no sense. See example below.
15713 @throw out_of_range.401 if the index @a idx is out of range of the array;
15714 that is, `idx >= size()`. See example below.
15715
15716 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15717 changes in the JSON value.
15718
15719 @complexity Constant.
15720
15721 @since version 1.0.0
15722
15723 @liveexample{The example below shows how array elements can be read using
15724 `at()`. It also demonstrates the different exceptions that can be thrown.,
15725 at__size_type_const}
15726 */
at(size_type idx) const15727 const_reference at(size_type idx) const
15728 {
15729 // at only works for arrays
15730 if (JSON_LIKELY(is_array()))
15731 {
15732 JSON_TRY
15733 {
15734 return m_value.array->at(idx);
15735 }
15736 JSON_CATCH (std::out_of_range&)
15737 {
15738 // create better exception explanation
15739 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15740 }
15741 }
15742 else
15743 {
15744 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15745 }
15746 }
15747
15748 /*!
15749 @brief access specified object element with bounds checking
15750
15751 Returns a reference to the element at with specified key @a key, with
15752 bounds checking.
15753
15754 @param[in] key key of the element to access
15755
15756 @return reference to the element at key @a key
15757
15758 @throw type_error.304 if the JSON value is not an object; in this case,
15759 calling `at` with a key makes no sense. See example below.
15760 @throw out_of_range.403 if the key @a key is is not stored in the object;
15761 that is, `find(key) == end()`. See example below.
15762
15763 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15764 changes in the JSON value.
15765
15766 @complexity Logarithmic in the size of the container.
15767
15768 @sa @ref operator[](const typename object_t::key_type&) for unchecked
15769 access by reference
15770 @sa @ref value() for access by value with a default value
15771
15772 @since version 1.0.0
15773
15774 @liveexample{The example below shows how object elements can be read and
15775 written using `at()`. It also demonstrates the different exceptions that
15776 can be thrown.,at__object_t_key_type}
15777 */
at(const typename object_t::key_type & key)15778 reference at(const typename object_t::key_type& key)
15779 {
15780 // at only works for objects
15781 if (JSON_LIKELY(is_object()))
15782 {
15783 JSON_TRY
15784 {
15785 return m_value.object->at(key);
15786 }
15787 JSON_CATCH (std::out_of_range&)
15788 {
15789 // create better exception explanation
15790 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15791 }
15792 }
15793 else
15794 {
15795 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15796 }
15797 }
15798
15799 /*!
15800 @brief access specified object element with bounds checking
15801
15802 Returns a const reference to the element at with specified key @a key,
15803 with bounds checking.
15804
15805 @param[in] key key of the element to access
15806
15807 @return const reference to the element at key @a key
15808
15809 @throw type_error.304 if the JSON value is not an object; in this case,
15810 calling `at` with a key makes no sense. See example below.
15811 @throw out_of_range.403 if the key @a key is is not stored in the object;
15812 that is, `find(key) == end()`. See example below.
15813
15814 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15815 changes in the JSON value.
15816
15817 @complexity Logarithmic in the size of the container.
15818
15819 @sa @ref operator[](const typename object_t::key_type&) for unchecked
15820 access by reference
15821 @sa @ref value() for access by value with a default value
15822
15823 @since version 1.0.0
15824
15825 @liveexample{The example below shows how object elements can be read using
15826 `at()`. It also demonstrates the different exceptions that can be thrown.,
15827 at__object_t_key_type_const}
15828 */
at(const typename object_t::key_type & key) const15829 const_reference at(const typename object_t::key_type& key) const
15830 {
15831 // at only works for objects
15832 if (JSON_LIKELY(is_object()))
15833 {
15834 JSON_TRY
15835 {
15836 return m_value.object->at(key);
15837 }
15838 JSON_CATCH (std::out_of_range&)
15839 {
15840 // create better exception explanation
15841 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15842 }
15843 }
15844 else
15845 {
15846 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15847 }
15848 }
15849
15850 /*!
15851 @brief access specified array element
15852
15853 Returns a reference to the element at specified location @a idx.
15854
15855 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
15856 then the array is silently filled up with `null` values to make `idx` a
15857 valid reference to the last stored element.
15858
15859 @param[in] idx index of the element to access
15860
15861 @return reference to the element at index @a idx
15862
15863 @throw type_error.305 if the JSON value is not an array or null; in that
15864 cases, using the [] operator with an index makes no sense.
15865
15866 @complexity Constant if @a idx is in the range of the array. Otherwise
15867 linear in `idx - size()`.
15868
15869 @liveexample{The example below shows how array elements can be read and
15870 written using `[]` operator. Note the addition of `null`
15871 values.,operatorarray__size_type}
15872
15873 @since version 1.0.0
15874 */
operator [](size_type idx)15875 reference operator[](size_type idx)
15876 {
15877 // implicitly convert null value to an empty array
15878 if (is_null())
15879 {
15880 m_type = value_t::array;
15881 m_value.array = create<array_t>();
15882 assert_invariant();
15883 }
15884
15885 // operator[] only works for arrays
15886 if (JSON_LIKELY(is_array()))
15887 {
15888 // fill up array with null values if given idx is outside range
15889 if (idx >= m_value.array->size())
15890 {
15891 m_value.array->insert(m_value.array->end(),
15892 idx - m_value.array->size() + 1,
15893 basic_json());
15894 }
15895
15896 return m_value.array->operator[](idx);
15897 }
15898
15899 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15900 }
15901
15902 /*!
15903 @brief access specified array element
15904
15905 Returns a const reference to the element at specified location @a idx.
15906
15907 @param[in] idx index of the element to access
15908
15909 @return const reference to the element at index @a idx
15910
15911 @throw type_error.305 if the JSON value is not an array; in that case,
15912 using the [] operator with an index makes no sense.
15913
15914 @complexity Constant.
15915
15916 @liveexample{The example below shows how array elements can be read using
15917 the `[]` operator.,operatorarray__size_type_const}
15918
15919 @since version 1.0.0
15920 */
operator [](size_type idx) const15921 const_reference operator[](size_type idx) const
15922 {
15923 // const operator[] only works for arrays
15924 if (JSON_LIKELY(is_array()))
15925 {
15926 return m_value.array->operator[](idx);
15927 }
15928
15929 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15930 }
15931
15932 /*!
15933 @brief access specified object element
15934
15935 Returns a reference to the element at with specified key @a key.
15936
15937 @note If @a key is not found in the object, then it is silently added to
15938 the object and filled with a `null` value to make `key` a valid reference.
15939 In case the value was `null` before, it is converted to an object.
15940
15941 @param[in] key key of the element to access
15942
15943 @return reference to the element at key @a key
15944
15945 @throw type_error.305 if the JSON value is not an object or null; in that
15946 cases, using the [] operator with a key makes no sense.
15947
15948 @complexity Logarithmic in the size of the container.
15949
15950 @liveexample{The example below shows how object elements can be read and
15951 written using the `[]` operator.,operatorarray__key_type}
15952
15953 @sa @ref at(const typename object_t::key_type&) for access by reference
15954 with range checking
15955 @sa @ref value() for access by value with a default value
15956
15957 @since version 1.0.0
15958 */
operator [](const typename object_t::key_type & key)15959 reference operator[](const typename object_t::key_type& key)
15960 {
15961 // implicitly convert null value to an empty object
15962 if (is_null())
15963 {
15964 m_type = value_t::object;
15965 m_value.object = create<object_t>();
15966 assert_invariant();
15967 }
15968
15969 // operator[] only works for objects
15970 if (JSON_LIKELY(is_object()))
15971 {
15972 return m_value.object->operator[](key);
15973 }
15974
15975 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
15976 }
15977
15978 /*!
15979 @brief read-only access specified object element
15980
15981 Returns a const reference to the element at with specified key @a key. No
15982 bounds checking is performed.
15983
15984 @warning If the element with key @a key does not exist, the behavior is
15985 undefined.
15986
15987 @param[in] key key of the element to access
15988
15989 @return const reference to the element at key @a key
15990
15991 @pre The element with key @a key must exist. **This precondition is
15992 enforced with an assertion.**
15993
15994 @throw type_error.305 if the JSON value is not an object; in that case,
15995 using the [] operator with a key makes no sense.
15996
15997 @complexity Logarithmic in the size of the container.
15998
15999 @liveexample{The example below shows how object elements can be read using
16000 the `[]` operator.,operatorarray__key_type_const}
16001
16002 @sa @ref at(const typename object_t::key_type&) for access by reference
16003 with range checking
16004 @sa @ref value() for access by value with a default value
16005
16006 @since version 1.0.0
16007 */
operator [](const typename object_t::key_type & key) const16008 const_reference operator[](const typename object_t::key_type& key) const
16009 {
16010 // const operator[] only works for objects
16011 if (JSON_LIKELY(is_object()))
16012 {
16013 assert(m_value.object->find(key) != m_value.object->end());
16014 return m_value.object->find(key)->second;
16015 }
16016
16017 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16018 }
16019
16020 /*!
16021 @brief access specified object element
16022
16023 Returns a reference to the element at with specified key @a key.
16024
16025 @note If @a key is not found in the object, then it is silently added to
16026 the object and filled with a `null` value to make `key` a valid reference.
16027 In case the value was `null` before, it is converted to an object.
16028
16029 @param[in] key key of the element to access
16030
16031 @return reference to the element at key @a key
16032
16033 @throw type_error.305 if the JSON value is not an object or null; in that
16034 cases, using the [] operator with a key makes no sense.
16035
16036 @complexity Logarithmic in the size of the container.
16037
16038 @liveexample{The example below shows how object elements can be read and
16039 written using the `[]` operator.,operatorarray__key_type}
16040
16041 @sa @ref at(const typename object_t::key_type&) for access by reference
16042 with range checking
16043 @sa @ref value() for access by value with a default value
16044
16045 @since version 1.1.0
16046 */
16047 template<typename T>
operator [](T * key)16048 reference operator[](T* key)
16049 {
16050 // implicitly convert null to object
16051 if (is_null())
16052 {
16053 m_type = value_t::object;
16054 m_value = value_t::object;
16055 assert_invariant();
16056 }
16057
16058 // at only works for objects
16059 if (JSON_LIKELY(is_object()))
16060 {
16061 return m_value.object->operator[](key);
16062 }
16063
16064 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16065 }
16066
16067 /*!
16068 @brief read-only access specified object element
16069
16070 Returns a const reference to the element at with specified key @a key. No
16071 bounds checking is performed.
16072
16073 @warning If the element with key @a key does not exist, the behavior is
16074 undefined.
16075
16076 @param[in] key key of the element to access
16077
16078 @return const reference to the element at key @a key
16079
16080 @pre The element with key @a key must exist. **This precondition is
16081 enforced with an assertion.**
16082
16083 @throw type_error.305 if the JSON value is not an object; in that case,
16084 using the [] operator with a key makes no sense.
16085
16086 @complexity Logarithmic in the size of the container.
16087
16088 @liveexample{The example below shows how object elements can be read using
16089 the `[]` operator.,operatorarray__key_type_const}
16090
16091 @sa @ref at(const typename object_t::key_type&) for access by reference
16092 with range checking
16093 @sa @ref value() for access by value with a default value
16094
16095 @since version 1.1.0
16096 */
16097 template<typename T>
operator [](T * key) const16098 const_reference operator[](T* key) const
16099 {
16100 // at only works for objects
16101 if (JSON_LIKELY(is_object()))
16102 {
16103 assert(m_value.object->find(key) != m_value.object->end());
16104 return m_value.object->find(key)->second;
16105 }
16106
16107 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16108 }
16109
16110 /*!
16111 @brief access specified object element with default value
16112
16113 Returns either a copy of an object's element at the specified key @a key
16114 or a given default value if no element with key @a key exists.
16115
16116 The function is basically equivalent to executing
16117 @code {.cpp}
16118 try {
16119 return at(key);
16120 } catch(out_of_range) {
16121 return default_value;
16122 }
16123 @endcode
16124
16125 @note Unlike @ref at(const typename object_t::key_type&), this function
16126 does not throw if the given key @a key was not found.
16127
16128 @note Unlike @ref operator[](const typename object_t::key_type& key), this
16129 function does not implicitly add an element to the position defined by @a
16130 key. This function is furthermore also applicable to const objects.
16131
16132 @param[in] key key of the element to access
16133 @param[in] default_value the value to return if @a key is not found
16134
16135 @tparam ValueType type compatible to JSON values, for instance `int` for
16136 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
16137 JSON arrays. Note the type of the expected value at @a key and the default
16138 value @a default_value must be compatible.
16139
16140 @return copy of the element at key @a key or @a default_value if @a key
16141 is not found
16142
16143 @throw type_error.306 if the JSON value is not an object; in that case,
16144 using `value()` with a key makes no sense.
16145
16146 @complexity Logarithmic in the size of the container.
16147
16148 @liveexample{The example below shows how object elements can be queried
16149 with a default value.,basic_json__value}
16150
16151 @sa @ref at(const typename object_t::key_type&) for access by reference
16152 with range checking
16153 @sa @ref operator[](const typename object_t::key_type&) for unchecked
16154 access by reference
16155
16156 @since version 1.0.0
16157 */
16158 template<class ValueType, typename std::enable_if<
16159 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
16160 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
16161 {
16162 // at only works for objects
16163 if (JSON_LIKELY(is_object()))
16164 {
16165 // if key is found, return value and given default value otherwise
16166 const auto it = find(key);
16167 if (it != end())
16168 {
16169 return *it;
16170 }
16171
16172 return default_value;
16173 }
16174
16175 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
16176 }
16177
16178 /*!
16179 @brief overload for a default value of type const char*
16180 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
16181 */
value(const typename object_t::key_type & key,const char * default_value) const16182 string_t value(const typename object_t::key_type& key, const char* default_value) const
16183 {
16184 return value(key, string_t(default_value));
16185 }
16186
16187 /*!
16188 @brief access specified object element via JSON Pointer with default value
16189
16190 Returns either a copy of an object's element at the specified key @a key
16191 or a given default value if no element with key @a key exists.
16192
16193 The function is basically equivalent to executing
16194 @code {.cpp}
16195 try {
16196 return at(ptr);
16197 } catch(out_of_range) {
16198 return default_value;
16199 }
16200 @endcode
16201
16202 @note Unlike @ref at(const json_pointer&), this function does not throw
16203 if the given key @a key was not found.
16204
16205 @param[in] ptr a JSON pointer to the element to access
16206 @param[in] default_value the value to return if @a ptr found no value
16207
16208 @tparam ValueType type compatible to JSON values, for instance `int` for
16209 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
16210 JSON arrays. Note the type of the expected value at @a key and the default
16211 value @a default_value must be compatible.
16212
16213 @return copy of the element at key @a key or @a default_value if @a key
16214 is not found
16215
16216 @throw type_error.306 if the JSON value is not an object; in that case,
16217 using `value()` with a key makes no sense.
16218
16219 @complexity Logarithmic in the size of the container.
16220
16221 @liveexample{The example below shows how object elements can be queried
16222 with a default value.,basic_json__value_ptr}
16223
16224 @sa @ref operator[](const json_pointer&) for unchecked access by reference
16225
16226 @since version 2.0.2
16227 */
16228 template<class ValueType, typename std::enable_if<
16229 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
16230 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
16231 {
16232 // at only works for objects
16233 if (JSON_LIKELY(is_object()))
16234 {
16235 // if pointer resolves a value, return it or use default value
16236 JSON_TRY
16237 {
16238 return ptr.get_checked(this);
16239 }
16240 JSON_INTERNAL_CATCH (out_of_range&)
16241 {
16242 return default_value;
16243 }
16244 }
16245
16246 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
16247 }
16248
16249 /*!
16250 @brief overload for a default value of type const char*
16251 @copydoc basic_json::value(const json_pointer&, ValueType) const
16252 */
value(const json_pointer & ptr,const char * default_value) const16253 string_t value(const json_pointer& ptr, const char* default_value) const
16254 {
16255 return value(ptr, string_t(default_value));
16256 }
16257
16258 /*!
16259 @brief access the first element
16260
16261 Returns a reference to the first element in the container. For a JSON
16262 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
16263
16264 @return In case of a structured type (array or object), a reference to the
16265 first element is returned. In case of number, string, or boolean values, a
16266 reference to the value is returned.
16267
16268 @complexity Constant.
16269
16270 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
16271 or an empty array or object (undefined behavior, **guarded by
16272 assertions**).
16273 @post The JSON value remains unchanged.
16274
16275 @throw invalid_iterator.214 when called on `null` value
16276
16277 @liveexample{The following code shows an example for `front()`.,front}
16278
16279 @sa @ref back() -- access the last element
16280
16281 @since version 1.0.0
16282 */
front()16283 reference front()
16284 {
16285 return *begin();
16286 }
16287
16288 /*!
16289 @copydoc basic_json::front()
16290 */
front() const16291 const_reference front() const
16292 {
16293 return *cbegin();
16294 }
16295
16296 /*!
16297 @brief access the last element
16298
16299 Returns a reference to the last element in the container. For a JSON
16300 container `c`, the expression `c.back()` is equivalent to
16301 @code {.cpp}
16302 auto tmp = c.end();
16303 --tmp;
16304 return *tmp;
16305 @endcode
16306
16307 @return In case of a structured type (array or object), a reference to the
16308 last element is returned. In case of number, string, or boolean values, a
16309 reference to the value is returned.
16310
16311 @complexity Constant.
16312
16313 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
16314 or an empty array or object (undefined behavior, **guarded by
16315 assertions**).
16316 @post The JSON value remains unchanged.
16317
16318 @throw invalid_iterator.214 when called on a `null` value. See example
16319 below.
16320
16321 @liveexample{The following code shows an example for `back()`.,back}
16322
16323 @sa @ref front() -- access the first element
16324
16325 @since version 1.0.0
16326 */
back()16327 reference back()
16328 {
16329 auto tmp = end();
16330 --tmp;
16331 return *tmp;
16332 }
16333
16334 /*!
16335 @copydoc basic_json::back()
16336 */
back() const16337 const_reference back() const
16338 {
16339 auto tmp = cend();
16340 --tmp;
16341 return *tmp;
16342 }
16343
16344 /*!
16345 @brief remove element given an iterator
16346
16347 Removes the element specified by iterator @a pos. The iterator @a pos must
16348 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
16349 but is not dereferenceable) cannot be used as a value for @a pos.
16350
16351 If called on a primitive type other than `null`, the resulting JSON value
16352 will be `null`.
16353
16354 @param[in] pos iterator to the element to remove
16355 @return Iterator following the last removed element. If the iterator @a
16356 pos refers to the last element, the `end()` iterator is returned.
16357
16358 @tparam IteratorType an @ref iterator or @ref const_iterator
16359
16360 @post Invalidates iterators and references at or after the point of the
16361 erase, including the `end()` iterator.
16362
16363 @throw type_error.307 if called on a `null` value; example: `"cannot use
16364 erase() with null"`
16365 @throw invalid_iterator.202 if called on an iterator which does not belong
16366 to the current JSON value; example: `"iterator does not fit current
16367 value"`
16368 @throw invalid_iterator.205 if called on a primitive type with invalid
16369 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
16370 out of range"`
16371
16372 @complexity The complexity depends on the type:
16373 - objects: amortized constant
16374 - arrays: linear in distance between @a pos and the end of the container
16375 - strings: linear in the length of the string
16376 - other types: constant
16377
16378 @liveexample{The example shows the result of `erase()` for different JSON
16379 types.,erase__IteratorType}
16380
16381 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16382 the given range
16383 @sa @ref erase(const typename object_t::key_type&) -- removes the element
16384 from an object at the given key
16385 @sa @ref erase(const size_type) -- removes the element from an array at
16386 the given index
16387
16388 @since version 1.0.0
16389 */
16390 template<class IteratorType, typename std::enable_if<
16391 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16392 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
16393 = 0>
16394 IteratorType erase(IteratorType pos)
16395 {
16396 // make sure iterator fits the current value
16397 if (JSON_UNLIKELY(this != pos.m_object))
16398 {
16399 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16400 }
16401
16402 IteratorType result = end();
16403
16404 switch (m_type)
16405 {
16406 case value_t::boolean:
16407 case value_t::number_float:
16408 case value_t::number_integer:
16409 case value_t::number_unsigned:
16410 case value_t::string:
16411 {
16412 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
16413 {
16414 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
16415 }
16416
16417 if (is_string())
16418 {
16419 AllocatorType<string_t> alloc;
16420 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16421 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16422 m_value.string = nullptr;
16423 }
16424
16425 m_type = value_t::null;
16426 assert_invariant();
16427 break;
16428 }
16429
16430 case value_t::object:
16431 {
16432 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16433 break;
16434 }
16435
16436 case value_t::array:
16437 {
16438 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16439 break;
16440 }
16441
16442 default:
16443 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16444 }
16445
16446 return result;
16447 }
16448
16449 /*!
16450 @brief remove elements given an iterator range
16451
16452 Removes the element specified by the range `[first; last)`. The iterator
16453 @a first does not need to be dereferenceable if `first == last`: erasing
16454 an empty range is a no-op.
16455
16456 If called on a primitive type other than `null`, the resulting JSON value
16457 will be `null`.
16458
16459 @param[in] first iterator to the beginning of the range to remove
16460 @param[in] last iterator past the end of the range to remove
16461 @return Iterator following the last removed element. If the iterator @a
16462 second refers to the last element, the `end()` iterator is returned.
16463
16464 @tparam IteratorType an @ref iterator or @ref const_iterator
16465
16466 @post Invalidates iterators and references at or after the point of the
16467 erase, including the `end()` iterator.
16468
16469 @throw type_error.307 if called on a `null` value; example: `"cannot use
16470 erase() with null"`
16471 @throw invalid_iterator.203 if called on iterators which does not belong
16472 to the current JSON value; example: `"iterators do not fit current value"`
16473 @throw invalid_iterator.204 if called on a primitive type with invalid
16474 iterators (i.e., if `first != begin()` and `last != end()`); example:
16475 `"iterators out of range"`
16476
16477 @complexity The complexity depends on the type:
16478 - objects: `log(size()) + std::distance(first, last)`
16479 - arrays: linear in the distance between @a first and @a last, plus linear
16480 in the distance between @a last and end of the container
16481 - strings: linear in the length of the string
16482 - other types: constant
16483
16484 @liveexample{The example shows the result of `erase()` for different JSON
16485 types.,erase__IteratorType_IteratorType}
16486
16487 @sa @ref erase(IteratorType) -- removes the element at a given position
16488 @sa @ref erase(const typename object_t::key_type&) -- removes the element
16489 from an object at the given key
16490 @sa @ref erase(const size_type) -- removes the element from an array at
16491 the given index
16492
16493 @since version 1.0.0
16494 */
16495 template<class IteratorType, typename std::enable_if<
16496 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16497 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
16498 = 0>
16499 IteratorType erase(IteratorType first, IteratorType last)
16500 {
16501 // make sure iterator fits the current value
16502 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
16503 {
16504 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
16505 }
16506
16507 IteratorType result = end();
16508
16509 switch (m_type)
16510 {
16511 case value_t::boolean:
16512 case value_t::number_float:
16513 case value_t::number_integer:
16514 case value_t::number_unsigned:
16515 case value_t::string:
16516 {
16517 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16518 or not last.m_it.primitive_iterator.is_end()))
16519 {
16520 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
16521 }
16522
16523 if (is_string())
16524 {
16525 AllocatorType<string_t> alloc;
16526 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16527 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16528 m_value.string = nullptr;
16529 }
16530
16531 m_type = value_t::null;
16532 assert_invariant();
16533 break;
16534 }
16535
16536 case value_t::object:
16537 {
16538 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16539 last.m_it.object_iterator);
16540 break;
16541 }
16542
16543 case value_t::array:
16544 {
16545 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16546 last.m_it.array_iterator);
16547 break;
16548 }
16549
16550 default:
16551 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16552 }
16553
16554 return result;
16555 }
16556
16557 /*!
16558 @brief remove element from a JSON object given a key
16559
16560 Removes elements from a JSON object with the key value @a key.
16561
16562 @param[in] key value of the elements to remove
16563
16564 @return Number of elements removed. If @a ObjectType is the default
16565 `std::map` type, the return value will always be `0` (@a key was not
16566 found) or `1` (@a key was found).
16567
16568 @post References and iterators to the erased elements are invalidated.
16569 Other references and iterators are not affected.
16570
16571 @throw type_error.307 when called on a type other than JSON object;
16572 example: `"cannot use erase() with null"`
16573
16574 @complexity `log(size()) + count(key)`
16575
16576 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
16577
16578 @sa @ref erase(IteratorType) -- removes the element at a given position
16579 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16580 the given range
16581 @sa @ref erase(const size_type) -- removes the element from an array at
16582 the given index
16583
16584 @since version 1.0.0
16585 */
erase(const typename object_t::key_type & key)16586 size_type erase(const typename object_t::key_type& key)
16587 {
16588 // this erase only works for objects
16589 if (JSON_LIKELY(is_object()))
16590 {
16591 return m_value.object->erase(key);
16592 }
16593
16594 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16595 }
16596
16597 /*!
16598 @brief remove element from a JSON array given an index
16599
16600 Removes element from a JSON array at the index @a idx.
16601
16602 @param[in] idx index of the element to remove
16603
16604 @throw type_error.307 when called on a type other than JSON object;
16605 example: `"cannot use erase() with null"`
16606 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
16607 is out of range"`
16608
16609 @complexity Linear in distance between @a idx and the end of the container.
16610
16611 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
16612
16613 @sa @ref erase(IteratorType) -- removes the element at a given position
16614 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16615 the given range
16616 @sa @ref erase(const typename object_t::key_type&) -- removes the element
16617 from an object at the given key
16618
16619 @since version 1.0.0
16620 */
erase(const size_type idx)16621 void erase(const size_type idx)
16622 {
16623 // this erase only works for arrays
16624 if (JSON_LIKELY(is_array()))
16625 {
16626 if (JSON_UNLIKELY(idx >= size()))
16627 {
16628 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
16629 }
16630
16631 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
16632 }
16633 else
16634 {
16635 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16636 }
16637 }
16638
16639 /// @}
16640
16641
16642 ////////////
16643 // lookup //
16644 ////////////
16645
16646 /// @name lookup
16647 /// @{
16648
16649 /*!
16650 @brief find an element in a JSON object
16651
16652 Finds an element in a JSON object with key equivalent to @a key. If the
16653 element is not found or the JSON value is not an object, end() is
16654 returned.
16655
16656 @note This method always returns @ref end() when executed on a JSON type
16657 that is not an object.
16658
16659 @param[in] key key value of the element to search for.
16660
16661 @return Iterator to an element with key equivalent to @a key. If no such
16662 element is found or the JSON value is not an object, past-the-end (see
16663 @ref end()) iterator is returned.
16664
16665 @complexity Logarithmic in the size of the JSON object.
16666
16667 @liveexample{The example shows how `find()` is used.,find__key_type}
16668
16669 @sa @ref contains(KeyT&&) const -- checks whether a key exists
16670
16671 @since version 1.0.0
16672 */
16673 template<typename KeyT>
find(KeyT && key)16674 iterator find(KeyT&& key)
16675 {
16676 auto result = end();
16677
16678 if (is_object())
16679 {
16680 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16681 }
16682
16683 return result;
16684 }
16685
16686 /*!
16687 @brief find an element in a JSON object
16688 @copydoc find(KeyT&&)
16689 */
16690 template<typename KeyT>
find(KeyT && key) const16691 const_iterator find(KeyT&& key) const
16692 {
16693 auto result = cend();
16694
16695 if (is_object())
16696 {
16697 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16698 }
16699
16700 return result;
16701 }
16702
16703 /*!
16704 @brief returns the number of occurrences of a key in a JSON object
16705
16706 Returns the number of elements with key @a key. If ObjectType is the
16707 default `std::map` type, the return value will always be `0` (@a key was
16708 not found) or `1` (@a key was found).
16709
16710 @note This method always returns `0` when executed on a JSON type that is
16711 not an object.
16712
16713 @param[in] key key value of the element to count
16714
16715 @return Number of elements with key @a key. If the JSON value is not an
16716 object, the return value will be `0`.
16717
16718 @complexity Logarithmic in the size of the JSON object.
16719
16720 @liveexample{The example shows how `count()` is used.,count}
16721
16722 @since version 1.0.0
16723 */
16724 template<typename KeyT>
count(KeyT && key) const16725 size_type count(KeyT&& key) const
16726 {
16727 // return 0 for all nonobject types
16728 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16729 }
16730
16731 /*!
16732 @brief check the existence of an element in a JSON object
16733
16734 Check whether an element exists in a JSON object with key equivalent to
16735 @a key. If the element is not found or the JSON value is not an object,
16736 false is returned.
16737
16738 @note This method always returns false when executed on a JSON type
16739 that is not an object.
16740
16741 @param[in] key key value to check its existence.
16742
16743 @return true if an element with specified @a key exists. If no such
16744 element with such key is found or the JSON value is not an object,
16745 false is returned.
16746
16747 @complexity Logarithmic in the size of the JSON object.
16748
16749 @liveexample{The following code shows an example for `contains()`.,contains}
16750
16751 @sa @ref find(KeyT&&) -- returns an iterator to an object element
16752
16753 @since version 3.6.0
16754 */
16755 template<typename KeyT>
contains(KeyT && key) const16756 bool contains(KeyT&& key) const
16757 {
16758 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
16759 }
16760
16761 /// @}
16762
16763
16764 ///////////////
16765 // iterators //
16766 ///////////////
16767
16768 /// @name iterators
16769 /// @{
16770
16771 /*!
16772 @brief returns an iterator to the first element
16773
16774 Returns an iterator to the first element.
16775
16776 @image html range-begin-end.svg "Illustration from cppreference.com"
16777
16778 @return iterator to the first element
16779
16780 @complexity Constant.
16781
16782 @requirement This function helps `basic_json` satisfying the
16783 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16784 requirements:
16785 - The complexity is constant.
16786
16787 @liveexample{The following code shows an example for `begin()`.,begin}
16788
16789 @sa @ref cbegin() -- returns a const iterator to the beginning
16790 @sa @ref end() -- returns an iterator to the end
16791 @sa @ref cend() -- returns a const iterator to the end
16792
16793 @since version 1.0.0
16794 */
begin()16795 iterator begin() noexcept
16796 {
16797 iterator result(this);
16798 result.set_begin();
16799 return result;
16800 }
16801
16802 /*!
16803 @copydoc basic_json::cbegin()
16804 */
begin() const16805 const_iterator begin() const noexcept
16806 {
16807 return cbegin();
16808 }
16809
16810 /*!
16811 @brief returns a const iterator to the first element
16812
16813 Returns a const iterator to the first element.
16814
16815 @image html range-begin-end.svg "Illustration from cppreference.com"
16816
16817 @return const iterator to the first element
16818
16819 @complexity Constant.
16820
16821 @requirement This function helps `basic_json` satisfying the
16822 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16823 requirements:
16824 - The complexity is constant.
16825 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
16826
16827 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
16828
16829 @sa @ref begin() -- returns an iterator to the beginning
16830 @sa @ref end() -- returns an iterator to the end
16831 @sa @ref cend() -- returns a const iterator to the end
16832
16833 @since version 1.0.0
16834 */
cbegin() const16835 const_iterator cbegin() const noexcept
16836 {
16837 const_iterator result(this);
16838 result.set_begin();
16839 return result;
16840 }
16841
16842 /*!
16843 @brief returns an iterator to one past the last element
16844
16845 Returns an iterator to one past the last element.
16846
16847 @image html range-begin-end.svg "Illustration from cppreference.com"
16848
16849 @return iterator one past the last element
16850
16851 @complexity Constant.
16852
16853 @requirement This function helps `basic_json` satisfying the
16854 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16855 requirements:
16856 - The complexity is constant.
16857
16858 @liveexample{The following code shows an example for `end()`.,end}
16859
16860 @sa @ref cend() -- returns a const iterator to the end
16861 @sa @ref begin() -- returns an iterator to the beginning
16862 @sa @ref cbegin() -- returns a const iterator to the beginning
16863
16864 @since version 1.0.0
16865 */
end()16866 iterator end() noexcept
16867 {
16868 iterator result(this);
16869 result.set_end();
16870 return result;
16871 }
16872
16873 /*!
16874 @copydoc basic_json::cend()
16875 */
end() const16876 const_iterator end() const noexcept
16877 {
16878 return cend();
16879 }
16880
16881 /*!
16882 @brief returns a const iterator to one past the last element
16883
16884 Returns a const iterator to one past the last element.
16885
16886 @image html range-begin-end.svg "Illustration from cppreference.com"
16887
16888 @return const iterator one past the last element
16889
16890 @complexity Constant.
16891
16892 @requirement This function helps `basic_json` satisfying the
16893 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16894 requirements:
16895 - The complexity is constant.
16896 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
16897
16898 @liveexample{The following code shows an example for `cend()`.,cend}
16899
16900 @sa @ref end() -- returns an iterator to the end
16901 @sa @ref begin() -- returns an iterator to the beginning
16902 @sa @ref cbegin() -- returns a const iterator to the beginning
16903
16904 @since version 1.0.0
16905 */
cend() const16906 const_iterator cend() const noexcept
16907 {
16908 const_iterator result(this);
16909 result.set_end();
16910 return result;
16911 }
16912
16913 /*!
16914 @brief returns an iterator to the reverse-beginning
16915
16916 Returns an iterator to the reverse-beginning; that is, the last element.
16917
16918 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16919
16920 @complexity Constant.
16921
16922 @requirement This function helps `basic_json` satisfying the
16923 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16924 requirements:
16925 - The complexity is constant.
16926 - Has the semantics of `reverse_iterator(end())`.
16927
16928 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
16929
16930 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
16931 @sa @ref rend() -- returns a reverse iterator to the end
16932 @sa @ref crend() -- returns a const reverse iterator to the end
16933
16934 @since version 1.0.0
16935 */
rbegin()16936 reverse_iterator rbegin() noexcept
16937 {
16938 return reverse_iterator(end());
16939 }
16940
16941 /*!
16942 @copydoc basic_json::crbegin()
16943 */
rbegin() const16944 const_reverse_iterator rbegin() const noexcept
16945 {
16946 return crbegin();
16947 }
16948
16949 /*!
16950 @brief returns an iterator to the reverse-end
16951
16952 Returns an iterator to the reverse-end; that is, one before the first
16953 element.
16954
16955 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16956
16957 @complexity Constant.
16958
16959 @requirement This function helps `basic_json` satisfying the
16960 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16961 requirements:
16962 - The complexity is constant.
16963 - Has the semantics of `reverse_iterator(begin())`.
16964
16965 @liveexample{The following code shows an example for `rend()`.,rend}
16966
16967 @sa @ref crend() -- returns a const reverse iterator to the end
16968 @sa @ref rbegin() -- returns a reverse iterator to the beginning
16969 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
16970
16971 @since version 1.0.0
16972 */
rend()16973 reverse_iterator rend() noexcept
16974 {
16975 return reverse_iterator(begin());
16976 }
16977
16978 /*!
16979 @copydoc basic_json::crend()
16980 */
rend() const16981 const_reverse_iterator rend() const noexcept
16982 {
16983 return crend();
16984 }
16985
16986 /*!
16987 @brief returns a const reverse iterator to the last element
16988
16989 Returns a const iterator to the reverse-beginning; that is, the last
16990 element.
16991
16992 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16993
16994 @complexity Constant.
16995
16996 @requirement This function helps `basic_json` satisfying the
16997 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16998 requirements:
16999 - The complexity is constant.
17000 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
17001
17002 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
17003
17004 @sa @ref rbegin() -- returns a reverse iterator to the beginning
17005 @sa @ref rend() -- returns a reverse iterator to the end
17006 @sa @ref crend() -- returns a const reverse iterator to the end
17007
17008 @since version 1.0.0
17009 */
crbegin() const17010 const_reverse_iterator crbegin() const noexcept
17011 {
17012 return const_reverse_iterator(cend());
17013 }
17014
17015 /*!
17016 @brief returns a const reverse iterator to one before the first
17017
17018 Returns a const reverse iterator to the reverse-end; that is, one before
17019 the first element.
17020
17021 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
17022
17023 @complexity Constant.
17024
17025 @requirement This function helps `basic_json` satisfying the
17026 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
17027 requirements:
17028 - The complexity is constant.
17029 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
17030
17031 @liveexample{The following code shows an example for `crend()`.,crend}
17032
17033 @sa @ref rend() -- returns a reverse iterator to the end
17034 @sa @ref rbegin() -- returns a reverse iterator to the beginning
17035 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
17036
17037 @since version 1.0.0
17038 */
crend() const17039 const_reverse_iterator crend() const noexcept
17040 {
17041 return const_reverse_iterator(cbegin());
17042 }
17043
17044 public:
17045 /*!
17046 @brief wrapper to access iterator member functions in range-based for
17047
17048 This function allows to access @ref iterator::key() and @ref
17049 iterator::value() during range-based for loops. In these loops, a
17050 reference to the JSON values is returned, so there is no access to the
17051 underlying iterator.
17052
17053 For loop without iterator_wrapper:
17054
17055 @code{cpp}
17056 for (auto it = j_object.begin(); it != j_object.end(); ++it)
17057 {
17058 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17059 }
17060 @endcode
17061
17062 Range-based for loop without iterator proxy:
17063
17064 @code{cpp}
17065 for (auto it : j_object)
17066 {
17067 // "it" is of type json::reference and has no key() member
17068 std::cout << "value: " << it << '\n';
17069 }
17070 @endcode
17071
17072 Range-based for loop with iterator proxy:
17073
17074 @code{cpp}
17075 for (auto it : json::iterator_wrapper(j_object))
17076 {
17077 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17078 }
17079 @endcode
17080
17081 @note When iterating over an array, `key()` will return the index of the
17082 element as string (see example).
17083
17084 @param[in] ref reference to a JSON value
17085 @return iteration proxy object wrapping @a ref with an interface to use in
17086 range-based for loops
17087
17088 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
17089
17090 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17091 changes in the JSON value.
17092
17093 @complexity Constant.
17094
17095 @note The name of this function is not yet final and may change in the
17096 future.
17097
17098 @deprecated This stream operator is deprecated and will be removed in
17099 future 4.0.0 of the library. Please use @ref items() instead;
17100 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
17101 */
17102 JSON_DEPRECATED
iterator_wrapper(reference ref)17103 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
17104 {
17105 return ref.items();
17106 }
17107
17108 /*!
17109 @copydoc iterator_wrapper(reference)
17110 */
17111 JSON_DEPRECATED
iterator_wrapper(const_reference ref)17112 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
17113 {
17114 return ref.items();
17115 }
17116
17117 /*!
17118 @brief helper to access iterator member functions in range-based for
17119
17120 This function allows to access @ref iterator::key() and @ref
17121 iterator::value() during range-based for loops. In these loops, a
17122 reference to the JSON values is returned, so there is no access to the
17123 underlying iterator.
17124
17125 For loop without `items()` function:
17126
17127 @code{cpp}
17128 for (auto it = j_object.begin(); it != j_object.end(); ++it)
17129 {
17130 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17131 }
17132 @endcode
17133
17134 Range-based for loop without `items()` function:
17135
17136 @code{cpp}
17137 for (auto it : j_object)
17138 {
17139 // "it" is of type json::reference and has no key() member
17140 std::cout << "value: " << it << '\n';
17141 }
17142 @endcode
17143
17144 Range-based for loop with `items()` function:
17145
17146 @code{cpp}
17147 for (auto& el : j_object.items())
17148 {
17149 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
17150 }
17151 @endcode
17152
17153 The `items()` function also allows to use
17154 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
17155 (C++17):
17156
17157 @code{cpp}
17158 for (auto& [key, val] : j_object.items())
17159 {
17160 std::cout << "key: " << key << ", value:" << val << '\n';
17161 }
17162 @endcode
17163
17164 @note When iterating over an array, `key()` will return the index of the
17165 element as string (see example). For primitive types (e.g., numbers),
17166 `key()` returns an empty string.
17167
17168 @return iteration proxy object wrapping @a ref with an interface to use in
17169 range-based for loops
17170
17171 @liveexample{The following code shows how the function is used.,items}
17172
17173 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17174 changes in the JSON value.
17175
17176 @complexity Constant.
17177
17178 @since version 3.1.0, structured bindings support since 3.5.0.
17179 */
items()17180 iteration_proxy<iterator> items() noexcept
17181 {
17182 return iteration_proxy<iterator>(*this);
17183 }
17184
17185 /*!
17186 @copydoc items()
17187 */
items() const17188 iteration_proxy<const_iterator> items() const noexcept
17189 {
17190 return iteration_proxy<const_iterator>(*this);
17191 }
17192
17193 /// @}
17194
17195
17196 //////////////
17197 // capacity //
17198 //////////////
17199
17200 /// @name capacity
17201 /// @{
17202
17203 /*!
17204 @brief checks whether the container is empty.
17205
17206 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
17207
17208 @return The return value depends on the different types and is
17209 defined as follows:
17210 Value type | return value
17211 ----------- | -------------
17212 null | `true`
17213 boolean | `false`
17214 string | `false`
17215 number | `false`
17216 object | result of function `object_t::empty()`
17217 array | result of function `array_t::empty()`
17218
17219 @liveexample{The following code uses `empty()` to check if a JSON
17220 object contains any elements.,empty}
17221
17222 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17223 the Container concept; that is, their `empty()` functions have constant
17224 complexity.
17225
17226 @iterators No changes.
17227
17228 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17229
17230 @note This function does not return whether a string stored as JSON value
17231 is empty - it returns whether the JSON container itself is empty which is
17232 false in the case of a string.
17233
17234 @requirement This function helps `basic_json` satisfying the
17235 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17236 requirements:
17237 - The complexity is constant.
17238 - Has the semantics of `begin() == end()`.
17239
17240 @sa @ref size() -- returns the number of elements
17241
17242 @since version 1.0.0
17243 */
empty() const17244 bool empty() const noexcept
17245 {
17246 switch (m_type)
17247 {
17248 case value_t::null:
17249 {
17250 // null values are empty
17251 return true;
17252 }
17253
17254 case value_t::array:
17255 {
17256 // delegate call to array_t::empty()
17257 return m_value.array->empty();
17258 }
17259
17260 case value_t::object:
17261 {
17262 // delegate call to object_t::empty()
17263 return m_value.object->empty();
17264 }
17265
17266 default:
17267 {
17268 // all other types are nonempty
17269 return false;
17270 }
17271 }
17272 }
17273
17274 /*!
17275 @brief returns the number of elements
17276
17277 Returns the number of elements in a JSON value.
17278
17279 @return The return value depends on the different types and is
17280 defined as follows:
17281 Value type | return value
17282 ----------- | -------------
17283 null | `0`
17284 boolean | `1`
17285 string | `1`
17286 number | `1`
17287 object | result of function object_t::size()
17288 array | result of function array_t::size()
17289
17290 @liveexample{The following code calls `size()` on the different value
17291 types.,size}
17292
17293 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17294 the Container concept; that is, their size() functions have constant
17295 complexity.
17296
17297 @iterators No changes.
17298
17299 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17300
17301 @note This function does not return the length of a string stored as JSON
17302 value - it returns the number of elements in the JSON value which is 1 in
17303 the case of a string.
17304
17305 @requirement This function helps `basic_json` satisfying the
17306 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17307 requirements:
17308 - The complexity is constant.
17309 - Has the semantics of `std::distance(begin(), end())`.
17310
17311 @sa @ref empty() -- checks whether the container is empty
17312 @sa @ref max_size() -- returns the maximal number of elements
17313
17314 @since version 1.0.0
17315 */
size() const17316 size_type size() const noexcept
17317 {
17318 switch (m_type)
17319 {
17320 case value_t::null:
17321 {
17322 // null values are empty
17323 return 0;
17324 }
17325
17326 case value_t::array:
17327 {
17328 // delegate call to array_t::size()
17329 return m_value.array->size();
17330 }
17331
17332 case value_t::object:
17333 {
17334 // delegate call to object_t::size()
17335 return m_value.object->size();
17336 }
17337
17338 default:
17339 {
17340 // all other types have size 1
17341 return 1;
17342 }
17343 }
17344 }
17345
17346 /*!
17347 @brief returns the maximum possible number of elements
17348
17349 Returns the maximum number of elements a JSON value is able to hold due to
17350 system or library implementation limitations, i.e. `std::distance(begin(),
17351 end())` for the JSON value.
17352
17353 @return The return value depends on the different types and is
17354 defined as follows:
17355 Value type | return value
17356 ----------- | -------------
17357 null | `0` (same as `size()`)
17358 boolean | `1` (same as `size()`)
17359 string | `1` (same as `size()`)
17360 number | `1` (same as `size()`)
17361 object | result of function `object_t::max_size()`
17362 array | result of function `array_t::max_size()`
17363
17364 @liveexample{The following code calls `max_size()` on the different value
17365 types. Note the output is implementation specific.,max_size}
17366
17367 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17368 the Container concept; that is, their `max_size()` functions have constant
17369 complexity.
17370
17371 @iterators No changes.
17372
17373 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17374
17375 @requirement This function helps `basic_json` satisfying the
17376 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17377 requirements:
17378 - The complexity is constant.
17379 - Has the semantics of returning `b.size()` where `b` is the largest
17380 possible JSON value.
17381
17382 @sa @ref size() -- returns the number of elements
17383
17384 @since version 1.0.0
17385 */
max_size() const17386 size_type max_size() const noexcept
17387 {
17388 switch (m_type)
17389 {
17390 case value_t::array:
17391 {
17392 // delegate call to array_t::max_size()
17393 return m_value.array->max_size();
17394 }
17395
17396 case value_t::object:
17397 {
17398 // delegate call to object_t::max_size()
17399 return m_value.object->max_size();
17400 }
17401
17402 default:
17403 {
17404 // all other types have max_size() == size()
17405 return size();
17406 }
17407 }
17408 }
17409
17410 /// @}
17411
17412
17413 ///////////////
17414 // modifiers //
17415 ///////////////
17416
17417 /// @name modifiers
17418 /// @{
17419
17420 /*!
17421 @brief clears the contents
17422
17423 Clears the content of a JSON value and resets it to the default value as
17424 if @ref basic_json(value_t) would have been called with the current value
17425 type from @ref type():
17426
17427 Value type | initial value
17428 ----------- | -------------
17429 null | `null`
17430 boolean | `false`
17431 string | `""`
17432 number | `0`
17433 object | `{}`
17434 array | `[]`
17435
17436 @post Has the same effect as calling
17437 @code {.cpp}
17438 *this = basic_json(type());
17439 @endcode
17440
17441 @liveexample{The example below shows the effect of `clear()` to different
17442 JSON types.,clear}
17443
17444 @complexity Linear in the size of the JSON value.
17445
17446 @iterators All iterators, pointers and references related to this container
17447 are invalidated.
17448
17449 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17450
17451 @sa @ref basic_json(value_t) -- constructor that creates an object with the
17452 same value than calling `clear()`
17453
17454 @since version 1.0.0
17455 */
clear()17456 void clear() noexcept
17457 {
17458 switch (m_type)
17459 {
17460 case value_t::number_integer:
17461 {
17462 m_value.number_integer = 0;
17463 break;
17464 }
17465
17466 case value_t::number_unsigned:
17467 {
17468 m_value.number_unsigned = 0;
17469 break;
17470 }
17471
17472 case value_t::number_float:
17473 {
17474 m_value.number_float = 0.0;
17475 break;
17476 }
17477
17478 case value_t::boolean:
17479 {
17480 m_value.boolean = false;
17481 break;
17482 }
17483
17484 case value_t::string:
17485 {
17486 m_value.string->clear();
17487 break;
17488 }
17489
17490 case value_t::array:
17491 {
17492 m_value.array->clear();
17493 break;
17494 }
17495
17496 case value_t::object:
17497 {
17498 m_value.object->clear();
17499 break;
17500 }
17501
17502 default:
17503 break;
17504 }
17505 }
17506
17507 /*!
17508 @brief add an object to an array
17509
17510 Appends the given element @a val to the end of the JSON value. If the
17511 function is called on a JSON null value, an empty array is created before
17512 appending @a val.
17513
17514 @param[in] val the value to add to the JSON array
17515
17516 @throw type_error.308 when called on a type other than JSON array or
17517 null; example: `"cannot use push_back() with number"`
17518
17519 @complexity Amortized constant.
17520
17521 @liveexample{The example shows how `push_back()` and `+=` can be used to
17522 add elements to a JSON array. Note how the `null` value was silently
17523 converted to a JSON array.,push_back}
17524
17525 @since version 1.0.0
17526 */
push_back(basic_json && val)17527 void push_back(basic_json&& val)
17528 {
17529 // push_back only works for null objects or arrays
17530 if (JSON_UNLIKELY(not(is_null() or is_array())))
17531 {
17532 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17533 }
17534
17535 // transform null object into an array
17536 if (is_null())
17537 {
17538 m_type = value_t::array;
17539 m_value = value_t::array;
17540 assert_invariant();
17541 }
17542
17543 // add element to array (move semantics)
17544 m_value.array->push_back(std::move(val));
17545 // invalidate object: mark it null so we do not call the destructor
17546 // cppcheck-suppress accessMoved
17547 val.m_type = value_t::null;
17548 }
17549
17550 /*!
17551 @brief add an object to an array
17552 @copydoc push_back(basic_json&&)
17553 */
operator +=(basic_json && val)17554 reference operator+=(basic_json&& val)
17555 {
17556 push_back(std::move(val));
17557 return *this;
17558 }
17559
17560 /*!
17561 @brief add an object to an array
17562 @copydoc push_back(basic_json&&)
17563 */
push_back(const basic_json & val)17564 void push_back(const basic_json& val)
17565 {
17566 // push_back only works for null objects or arrays
17567 if (JSON_UNLIKELY(not(is_null() or is_array())))
17568 {
17569 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17570 }
17571
17572 // transform null object into an array
17573 if (is_null())
17574 {
17575 m_type = value_t::array;
17576 m_value = value_t::array;
17577 assert_invariant();
17578 }
17579
17580 // add element to array
17581 m_value.array->push_back(val);
17582 }
17583
17584 /*!
17585 @brief add an object to an array
17586 @copydoc push_back(basic_json&&)
17587 */
operator +=(const basic_json & val)17588 reference operator+=(const basic_json& val)
17589 {
17590 push_back(val);
17591 return *this;
17592 }
17593
17594 /*!
17595 @brief add an object to an object
17596
17597 Inserts the given element @a val to the JSON object. If the function is
17598 called on a JSON null value, an empty object is created before inserting
17599 @a val.
17600
17601 @param[in] val the value to add to the JSON object
17602
17603 @throw type_error.308 when called on a type other than JSON object or
17604 null; example: `"cannot use push_back() with number"`
17605
17606 @complexity Logarithmic in the size of the container, O(log(`size()`)).
17607
17608 @liveexample{The example shows how `push_back()` and `+=` can be used to
17609 add elements to a JSON object. Note how the `null` value was silently
17610 converted to a JSON object.,push_back__object_t__value}
17611
17612 @since version 1.0.0
17613 */
push_back(const typename object_t::value_type & val)17614 void push_back(const typename object_t::value_type& val)
17615 {
17616 // push_back only works for null objects or objects
17617 if (JSON_UNLIKELY(not(is_null() or is_object())))
17618 {
17619 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17620 }
17621
17622 // transform null object into an object
17623 if (is_null())
17624 {
17625 m_type = value_t::object;
17626 m_value = value_t::object;
17627 assert_invariant();
17628 }
17629
17630 // add element to array
17631 m_value.object->insert(val);
17632 }
17633
17634 /*!
17635 @brief add an object to an object
17636 @copydoc push_back(const typename object_t::value_type&)
17637 */
operator +=(const typename object_t::value_type & val)17638 reference operator+=(const typename object_t::value_type& val)
17639 {
17640 push_back(val);
17641 return *this;
17642 }
17643
17644 /*!
17645 @brief add an object to an object
17646
17647 This function allows to use `push_back` with an initializer list. In case
17648
17649 1. the current value is an object,
17650 2. the initializer list @a init contains only two elements, and
17651 3. the first element of @a init is a string,
17652
17653 @a init is converted into an object element and added using
17654 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
17655 is converted to a JSON value and added using @ref push_back(basic_json&&).
17656
17657 @param[in] init an initializer list
17658
17659 @complexity Linear in the size of the initializer list @a init.
17660
17661 @note This function is required to resolve an ambiguous overload error,
17662 because pairs like `{"key", "value"}` can be both interpreted as
17663 `object_t::value_type` or `std::initializer_list<basic_json>`, see
17664 https://github.com/nlohmann/json/issues/235 for more information.
17665
17666 @liveexample{The example shows how initializer lists are treated as
17667 objects when possible.,push_back__initializer_list}
17668 */
push_back(initializer_list_t init)17669 void push_back(initializer_list_t init)
17670 {
17671 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17672 {
17673 basic_json&& key = init.begin()->moved_or_copied();
17674 push_back(typename object_t::value_type(
17675 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
17676 }
17677 else
17678 {
17679 push_back(basic_json(init));
17680 }
17681 }
17682
17683 /*!
17684 @brief add an object to an object
17685 @copydoc push_back(initializer_list_t)
17686 */
operator +=(initializer_list_t init)17687 reference operator+=(initializer_list_t init)
17688 {
17689 push_back(init);
17690 return *this;
17691 }
17692
17693 /*!
17694 @brief add an object to an array
17695
17696 Creates a JSON value from the passed parameters @a args to the end of the
17697 JSON value. If the function is called on a JSON null value, an empty array
17698 is created before appending the value created from @a args.
17699
17700 @param[in] args arguments to forward to a constructor of @ref basic_json
17701 @tparam Args compatible types to create a @ref basic_json object
17702
17703 @throw type_error.311 when called on a type other than JSON array or
17704 null; example: `"cannot use emplace_back() with number"`
17705
17706 @complexity Amortized constant.
17707
17708 @liveexample{The example shows how `push_back()` can be used to add
17709 elements to a JSON array. Note how the `null` value was silently converted
17710 to a JSON array.,emplace_back}
17711
17712 @since version 2.0.8
17713 */
17714 template<class... Args>
emplace_back(Args &&...args)17715 void emplace_back(Args&& ... args)
17716 {
17717 // emplace_back only works for null objects or arrays
17718 if (JSON_UNLIKELY(not(is_null() or is_array())))
17719 {
17720 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
17721 }
17722
17723 // transform null object into an array
17724 if (is_null())
17725 {
17726 m_type = value_t::array;
17727 m_value = value_t::array;
17728 assert_invariant();
17729 }
17730
17731 // add element to array (perfect forwarding)
17732 m_value.array->emplace_back(std::forward<Args>(args)...);
17733 }
17734
17735 /*!
17736 @brief add an object to an object if key does not exist
17737
17738 Inserts a new element into a JSON object constructed in-place with the
17739 given @a args if there is no element with the key in the container. If the
17740 function is called on a JSON null value, an empty object is created before
17741 appending the value created from @a args.
17742
17743 @param[in] args arguments to forward to a constructor of @ref basic_json
17744 @tparam Args compatible types to create a @ref basic_json object
17745
17746 @return a pair consisting of an iterator to the inserted element, or the
17747 already-existing element if no insertion happened, and a bool
17748 denoting whether the insertion took place.
17749
17750 @throw type_error.311 when called on a type other than JSON object or
17751 null; example: `"cannot use emplace() with number"`
17752
17753 @complexity Logarithmic in the size of the container, O(log(`size()`)).
17754
17755 @liveexample{The example shows how `emplace()` can be used to add elements
17756 to a JSON object. Note how the `null` value was silently converted to a
17757 JSON object. Further note how no value is added if there was already one
17758 value stored with the same key.,emplace}
17759
17760 @since version 2.0.8
17761 */
17762 template<class... Args>
emplace(Args &&...args)17763 std::pair<iterator, bool> emplace(Args&& ... args)
17764 {
17765 // emplace only works for null objects or arrays
17766 if (JSON_UNLIKELY(not(is_null() or is_object())))
17767 {
17768 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
17769 }
17770
17771 // transform null object into an object
17772 if (is_null())
17773 {
17774 m_type = value_t::object;
17775 m_value = value_t::object;
17776 assert_invariant();
17777 }
17778
17779 // add element to array (perfect forwarding)
17780 auto res = m_value.object->emplace(std::forward<Args>(args)...);
17781 // create result iterator and set iterator to the result of emplace
17782 auto it = begin();
17783 it.m_it.object_iterator = res.first;
17784
17785 // return pair of iterator and boolean
17786 return {it, res.second};
17787 }
17788
17789 /// Helper for insertion of an iterator
17790 /// @note: This uses std::distance to support GCC 4.8,
17791 /// see https://github.com/nlohmann/json/pull/1257
17792 template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)17793 iterator insert_iterator(const_iterator pos, Args&& ... args)
17794 {
17795 iterator result(this);
17796 assert(m_value.array != nullptr);
17797
17798 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17799 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17800 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17801
17802 // This could have been written as:
17803 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
17804 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
17805
17806 return result;
17807 }
17808
17809 /*!
17810 @brief inserts element
17811
17812 Inserts element @a val before iterator @a pos.
17813
17814 @param[in] pos iterator before which the content will be inserted; may be
17815 the end() iterator
17816 @param[in] val element to insert
17817 @return iterator pointing to the inserted @a val.
17818
17819 @throw type_error.309 if called on JSON values other than arrays;
17820 example: `"cannot use insert() with string"`
17821 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17822 example: `"iterator does not fit current value"`
17823
17824 @complexity Constant plus linear in the distance between @a pos and end of
17825 the container.
17826
17827 @liveexample{The example shows how `insert()` is used.,insert}
17828
17829 @since version 1.0.0
17830 */
insert(const_iterator pos,const basic_json & val)17831 iterator insert(const_iterator pos, const basic_json& val)
17832 {
17833 // insert only works for arrays
17834 if (JSON_LIKELY(is_array()))
17835 {
17836 // check if iterator pos fits to this JSON value
17837 if (JSON_UNLIKELY(pos.m_object != this))
17838 {
17839 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17840 }
17841
17842 // insert to array and return iterator
17843 return insert_iterator(pos, val);
17844 }
17845
17846 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17847 }
17848
17849 /*!
17850 @brief inserts element
17851 @copydoc insert(const_iterator, const basic_json&)
17852 */
insert(const_iterator pos,basic_json && val)17853 iterator insert(const_iterator pos, basic_json&& val)
17854 {
17855 return insert(pos, val);
17856 }
17857
17858 /*!
17859 @brief inserts elements
17860
17861 Inserts @a cnt copies of @a val before iterator @a pos.
17862
17863 @param[in] pos iterator before which the content will be inserted; may be
17864 the end() iterator
17865 @param[in] cnt number of copies of @a val to insert
17866 @param[in] val element to insert
17867 @return iterator pointing to the first element inserted, or @a pos if
17868 `cnt==0`
17869
17870 @throw type_error.309 if called on JSON values other than arrays; example:
17871 `"cannot use insert() with string"`
17872 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17873 example: `"iterator does not fit current value"`
17874
17875 @complexity Linear in @a cnt plus linear in the distance between @a pos
17876 and end of the container.
17877
17878 @liveexample{The example shows how `insert()` is used.,insert__count}
17879
17880 @since version 1.0.0
17881 */
insert(const_iterator pos,size_type cnt,const basic_json & val)17882 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
17883 {
17884 // insert only works for arrays
17885 if (JSON_LIKELY(is_array()))
17886 {
17887 // check if iterator pos fits to this JSON value
17888 if (JSON_UNLIKELY(pos.m_object != this))
17889 {
17890 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17891 }
17892
17893 // insert to array and return iterator
17894 return insert_iterator(pos, cnt, val);
17895 }
17896
17897 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17898 }
17899
17900 /*!
17901 @brief inserts elements
17902
17903 Inserts elements from range `[first, last)` before iterator @a pos.
17904
17905 @param[in] pos iterator before which the content will be inserted; may be
17906 the end() iterator
17907 @param[in] first begin of the range of elements to insert
17908 @param[in] last end of the range of elements to insert
17909
17910 @throw type_error.309 if called on JSON values other than arrays; example:
17911 `"cannot use insert() with string"`
17912 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17913 example: `"iterator does not fit current value"`
17914 @throw invalid_iterator.210 if @a first and @a last do not belong to the
17915 same JSON value; example: `"iterators do not fit"`
17916 @throw invalid_iterator.211 if @a first or @a last are iterators into
17917 container for which insert is called; example: `"passed iterators may not
17918 belong to container"`
17919
17920 @return iterator pointing to the first element inserted, or @a pos if
17921 `first==last`
17922
17923 @complexity Linear in `std::distance(first, last)` plus linear in the
17924 distance between @a pos and end of the container.
17925
17926 @liveexample{The example shows how `insert()` is used.,insert__range}
17927
17928 @since version 1.0.0
17929 */
insert(const_iterator pos,const_iterator first,const_iterator last)17930 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
17931 {
17932 // insert only works for arrays
17933 if (JSON_UNLIKELY(not is_array()))
17934 {
17935 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17936 }
17937
17938 // check if iterator pos fits to this JSON value
17939 if (JSON_UNLIKELY(pos.m_object != this))
17940 {
17941 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17942 }
17943
17944 // check if range iterators belong to the same JSON object
17945 if (JSON_UNLIKELY(first.m_object != last.m_object))
17946 {
17947 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
17948 }
17949
17950 if (JSON_UNLIKELY(first.m_object == this))
17951 {
17952 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
17953 }
17954
17955 // insert to array and return iterator
17956 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
17957 }
17958
17959 /*!
17960 @brief inserts elements
17961
17962 Inserts elements from initializer list @a ilist before iterator @a pos.
17963
17964 @param[in] pos iterator before which the content will be inserted; may be
17965 the end() iterator
17966 @param[in] ilist initializer list to insert the values from
17967
17968 @throw type_error.309 if called on JSON values other than arrays; example:
17969 `"cannot use insert() with string"`
17970 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17971 example: `"iterator does not fit current value"`
17972
17973 @return iterator pointing to the first element inserted, or @a pos if
17974 `ilist` is empty
17975
17976 @complexity Linear in `ilist.size()` plus linear in the distance between
17977 @a pos and end of the container.
17978
17979 @liveexample{The example shows how `insert()` is used.,insert__ilist}
17980
17981 @since version 1.0.0
17982 */
insert(const_iterator pos,initializer_list_t ilist)17983 iterator insert(const_iterator pos, initializer_list_t ilist)
17984 {
17985 // insert only works for arrays
17986 if (JSON_UNLIKELY(not is_array()))
17987 {
17988 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17989 }
17990
17991 // check if iterator pos fits to this JSON value
17992 if (JSON_UNLIKELY(pos.m_object != this))
17993 {
17994 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17995 }
17996
17997 // insert to array and return iterator
17998 return insert_iterator(pos, ilist.begin(), ilist.end());
17999 }
18000
18001 /*!
18002 @brief inserts elements
18003
18004 Inserts elements from range `[first, last)`.
18005
18006 @param[in] first begin of the range of elements to insert
18007 @param[in] last end of the range of elements to insert
18008
18009 @throw type_error.309 if called on JSON values other than objects; example:
18010 `"cannot use insert() with string"`
18011 @throw invalid_iterator.202 if iterator @a first or @a last does does not
18012 point to an object; example: `"iterators first and last must point to
18013 objects"`
18014 @throw invalid_iterator.210 if @a first and @a last do not belong to the
18015 same JSON value; example: `"iterators do not fit"`
18016
18017 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
18018 of elements to insert.
18019
18020 @liveexample{The example shows how `insert()` is used.,insert__range_object}
18021
18022 @since version 3.0.0
18023 */
insert(const_iterator first,const_iterator last)18024 void insert(const_iterator first, const_iterator last)
18025 {
18026 // insert only works for objects
18027 if (JSON_UNLIKELY(not is_object()))
18028 {
18029 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
18030 }
18031
18032 // check if range iterators belong to the same JSON object
18033 if (JSON_UNLIKELY(first.m_object != last.m_object))
18034 {
18035 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
18036 }
18037
18038 // passed iterators must belong to objects
18039 if (JSON_UNLIKELY(not first.m_object->is_object()))
18040 {
18041 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
18042 }
18043
18044 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
18045 }
18046
18047 /*!
18048 @brief updates a JSON object from another object, overwriting existing keys
18049
18050 Inserts all values from JSON object @a j and overwrites existing keys.
18051
18052 @param[in] j JSON object to read values from
18053
18054 @throw type_error.312 if called on JSON values other than objects; example:
18055 `"cannot use update() with string"`
18056
18057 @complexity O(N*log(size() + N)), where N is the number of elements to
18058 insert.
18059
18060 @liveexample{The example shows how `update()` is used.,update}
18061
18062 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
18063
18064 @since version 3.0.0
18065 */
update(const_reference j)18066 void update(const_reference j)
18067 {
18068 // implicitly convert null value to an empty object
18069 if (is_null())
18070 {
18071 m_type = value_t::object;
18072 m_value.object = create<object_t>();
18073 assert_invariant();
18074 }
18075
18076 if (JSON_UNLIKELY(not is_object()))
18077 {
18078 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
18079 }
18080 if (JSON_UNLIKELY(not j.is_object()))
18081 {
18082 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
18083 }
18084
18085 for (auto it = j.cbegin(); it != j.cend(); ++it)
18086 {
18087 m_value.object->operator[](it.key()) = it.value();
18088 }
18089 }
18090
18091 /*!
18092 @brief updates a JSON object from another object, overwriting existing keys
18093
18094 Inserts all values from from range `[first, last)` and overwrites existing
18095 keys.
18096
18097 @param[in] first begin of the range of elements to insert
18098 @param[in] last end of the range of elements to insert
18099
18100 @throw type_error.312 if called on JSON values other than objects; example:
18101 `"cannot use update() with string"`
18102 @throw invalid_iterator.202 if iterator @a first or @a last does does not
18103 point to an object; example: `"iterators first and last must point to
18104 objects"`
18105 @throw invalid_iterator.210 if @a first and @a last do not belong to the
18106 same JSON value; example: `"iterators do not fit"`
18107
18108 @complexity O(N*log(size() + N)), where N is the number of elements to
18109 insert.
18110
18111 @liveexample{The example shows how `update()` is used__range.,update}
18112
18113 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
18114
18115 @since version 3.0.0
18116 */
update(const_iterator first,const_iterator last)18117 void update(const_iterator first, const_iterator last)
18118 {
18119 // implicitly convert null value to an empty object
18120 if (is_null())
18121 {
18122 m_type = value_t::object;
18123 m_value.object = create<object_t>();
18124 assert_invariant();
18125 }
18126
18127 if (JSON_UNLIKELY(not is_object()))
18128 {
18129 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
18130 }
18131
18132 // check if range iterators belong to the same JSON object
18133 if (JSON_UNLIKELY(first.m_object != last.m_object))
18134 {
18135 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
18136 }
18137
18138 // passed iterators must belong to objects
18139 if (JSON_UNLIKELY(not first.m_object->is_object()
18140 or not last.m_object->is_object()))
18141 {
18142 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
18143 }
18144
18145 for (auto it = first; it != last; ++it)
18146 {
18147 m_value.object->operator[](it.key()) = it.value();
18148 }
18149 }
18150
18151 /*!
18152 @brief exchanges the values
18153
18154 Exchanges the contents of the JSON value with those of @a other. Does not
18155 invoke any move, copy, or swap operations on individual elements. All
18156 iterators and references remain valid. The past-the-end iterator is
18157 invalidated.
18158
18159 @param[in,out] other JSON value to exchange the contents with
18160
18161 @complexity Constant.
18162
18163 @liveexample{The example below shows how JSON values can be swapped with
18164 `swap()`.,swap__reference}
18165
18166 @since version 1.0.0
18167 */
swap(reference other)18168 void swap(reference other) noexcept (
18169 std::is_nothrow_move_constructible<value_t>::value and
18170 std::is_nothrow_move_assignable<value_t>::value and
18171 std::is_nothrow_move_constructible<json_value>::value and
18172 std::is_nothrow_move_assignable<json_value>::value
18173 )
18174 {
18175 std::swap(m_type, other.m_type);
18176 std::swap(m_value, other.m_value);
18177 assert_invariant();
18178 }
18179
18180 /*!
18181 @brief exchanges the values
18182
18183 Exchanges the contents of a JSON array with those of @a other. Does not
18184 invoke any move, copy, or swap operations on individual elements. All
18185 iterators and references remain valid. The past-the-end iterator is
18186 invalidated.
18187
18188 @param[in,out] other array to exchange the contents with
18189
18190 @throw type_error.310 when JSON value is not an array; example: `"cannot
18191 use swap() with string"`
18192
18193 @complexity Constant.
18194
18195 @liveexample{The example below shows how arrays can be swapped with
18196 `swap()`.,swap__array_t}
18197
18198 @since version 1.0.0
18199 */
swap(array_t & other)18200 void swap(array_t& other)
18201 {
18202 // swap only works for arrays
18203 if (JSON_LIKELY(is_array()))
18204 {
18205 std::swap(*(m_value.array), other);
18206 }
18207 else
18208 {
18209 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18210 }
18211 }
18212
18213 /*!
18214 @brief exchanges the values
18215
18216 Exchanges the contents of a JSON object with those of @a other. Does not
18217 invoke any move, copy, or swap operations on individual elements. All
18218 iterators and references remain valid. The past-the-end iterator is
18219 invalidated.
18220
18221 @param[in,out] other object to exchange the contents with
18222
18223 @throw type_error.310 when JSON value is not an object; example:
18224 `"cannot use swap() with string"`
18225
18226 @complexity Constant.
18227
18228 @liveexample{The example below shows how objects can be swapped with
18229 `swap()`.,swap__object_t}
18230
18231 @since version 1.0.0
18232 */
swap(object_t & other)18233 void swap(object_t& other)
18234 {
18235 // swap only works for objects
18236 if (JSON_LIKELY(is_object()))
18237 {
18238 std::swap(*(m_value.object), other);
18239 }
18240 else
18241 {
18242 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18243 }
18244 }
18245
18246 /*!
18247 @brief exchanges the values
18248
18249 Exchanges the contents of a JSON string with those of @a other. Does not
18250 invoke any move, copy, or swap operations on individual elements. All
18251 iterators and references remain valid. The past-the-end iterator is
18252 invalidated.
18253
18254 @param[in,out] other string to exchange the contents with
18255
18256 @throw type_error.310 when JSON value is not a string; example: `"cannot
18257 use swap() with boolean"`
18258
18259 @complexity Constant.
18260
18261 @liveexample{The example below shows how strings can be swapped with
18262 `swap()`.,swap__string_t}
18263
18264 @since version 1.0.0
18265 */
swap(string_t & other)18266 void swap(string_t& other)
18267 {
18268 // swap only works for strings
18269 if (JSON_LIKELY(is_string()))
18270 {
18271 std::swap(*(m_value.string), other);
18272 }
18273 else
18274 {
18275 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18276 }
18277 }
18278
18279 /// @}
18280
18281 public:
18282 //////////////////////////////////////////
18283 // lexicographical comparison operators //
18284 //////////////////////////////////////////
18285
18286 /// @name lexicographical comparison operators
18287 /// @{
18288
18289 /*!
18290 @brief comparison: equal
18291
18292 Compares two JSON values for equality according to the following rules:
18293 - Two JSON values are equal if (1) they are from the same type and (2)
18294 their stored values are the same according to their respective
18295 `operator==`.
18296 - Integer and floating-point numbers are automatically converted before
18297 comparison. Note than two NaN values are always treated as unequal.
18298 - Two JSON null values are equal.
18299
18300 @note Floating-point inside JSON values numbers are compared with
18301 `json::number_float_t::operator==` which is `double::operator==` by
18302 default. To compare floating-point while respecting an epsilon, an alternative
18303 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
18304 could be used, for instance
18305 @code {.cpp}
18306 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
18307 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
18308 {
18309 return std::abs(a - b) <= epsilon;
18310 }
18311 @endcode
18312
18313 @note NaN values never compare equal to themselves or to other NaN values.
18314
18315 @param[in] lhs first JSON value to consider
18316 @param[in] rhs second JSON value to consider
18317 @return whether the values @a lhs and @a rhs are equal
18318
18319 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18320
18321 @complexity Linear.
18322
18323 @liveexample{The example demonstrates comparing several JSON
18324 types.,operator__equal}
18325
18326 @since version 1.0.0
18327 */
operator ==(const_reference lhs,const_reference rhs)18328 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
18329 {
18330 const auto lhs_type = lhs.type();
18331 const auto rhs_type = rhs.type();
18332
18333 if (lhs_type == rhs_type)
18334 {
18335 switch (lhs_type)
18336 {
18337 case value_t::array:
18338 return *lhs.m_value.array == *rhs.m_value.array;
18339
18340 case value_t::object:
18341 return *lhs.m_value.object == *rhs.m_value.object;
18342
18343 case value_t::null:
18344 return true;
18345
18346 case value_t::string:
18347 return *lhs.m_value.string == *rhs.m_value.string;
18348
18349 case value_t::boolean:
18350 return lhs.m_value.boolean == rhs.m_value.boolean;
18351
18352 case value_t::number_integer:
18353 return lhs.m_value.number_integer == rhs.m_value.number_integer;
18354
18355 case value_t::number_unsigned:
18356 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
18357
18358 case value_t::number_float:
18359 return lhs.m_value.number_float == rhs.m_value.number_float;
18360
18361 default:
18362 return false;
18363 }
18364 }
18365 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18366 {
18367 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
18368 }
18369 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18370 {
18371 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
18372 }
18373 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18374 {
18375 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
18376 }
18377 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18378 {
18379 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
18380 }
18381 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18382 {
18383 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
18384 }
18385 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18386 {
18387 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18388 }
18389
18390 return false;
18391 }
18392
18393 /*!
18394 @brief comparison: equal
18395 @copydoc operator==(const_reference, const_reference)
18396 */
18397 template<typename ScalarType, typename std::enable_if<
18398 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)18399 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
18400 {
18401 return lhs == basic_json(rhs);
18402 }
18403
18404 /*!
18405 @brief comparison: equal
18406 @copydoc operator==(const_reference, const_reference)
18407 */
18408 template<typename ScalarType, typename std::enable_if<
18409 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)18410 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
18411 {
18412 return basic_json(lhs) == rhs;
18413 }
18414
18415 /*!
18416 @brief comparison: not equal
18417
18418 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
18419
18420 @param[in] lhs first JSON value to consider
18421 @param[in] rhs second JSON value to consider
18422 @return whether the values @a lhs and @a rhs are not equal
18423
18424 @complexity Linear.
18425
18426 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18427
18428 @liveexample{The example demonstrates comparing several JSON
18429 types.,operator__notequal}
18430
18431 @since version 1.0.0
18432 */
operator !=(const_reference lhs,const_reference rhs)18433 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
18434 {
18435 return not (lhs == rhs);
18436 }
18437
18438 /*!
18439 @brief comparison: not equal
18440 @copydoc operator!=(const_reference, const_reference)
18441 */
18442 template<typename ScalarType, typename std::enable_if<
18443 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)18444 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
18445 {
18446 return lhs != basic_json(rhs);
18447 }
18448
18449 /*!
18450 @brief comparison: not equal
18451 @copydoc operator!=(const_reference, const_reference)
18452 */
18453 template<typename ScalarType, typename std::enable_if<
18454 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)18455 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
18456 {
18457 return basic_json(lhs) != rhs;
18458 }
18459
18460 /*!
18461 @brief comparison: less than
18462
18463 Compares whether one JSON value @a lhs is less than another JSON value @a
18464 rhs according to the following rules:
18465 - If @a lhs and @a rhs have the same type, the values are compared using
18466 the default `<` operator.
18467 - Integer and floating-point numbers are automatically converted before
18468 comparison
18469 - In case @a lhs and @a rhs have different types, the values are ignored
18470 and the order of the types is considered, see
18471 @ref operator<(const value_t, const value_t).
18472
18473 @param[in] lhs first JSON value to consider
18474 @param[in] rhs second JSON value to consider
18475 @return whether @a lhs is less than @a rhs
18476
18477 @complexity Linear.
18478
18479 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18480
18481 @liveexample{The example demonstrates comparing several JSON
18482 types.,operator__less}
18483
18484 @since version 1.0.0
18485 */
operator <(const_reference lhs,const_reference rhs)18486 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
18487 {
18488 const auto lhs_type = lhs.type();
18489 const auto rhs_type = rhs.type();
18490
18491 if (lhs_type == rhs_type)
18492 {
18493 switch (lhs_type)
18494 {
18495 case value_t::array:
18496 // note parentheses are necessary, see
18497 // https://github.com/nlohmann/json/issues/1530
18498 return (*lhs.m_value.array) < (*rhs.m_value.array);
18499
18500 case value_t::object:
18501 return *lhs.m_value.object < *rhs.m_value.object;
18502
18503 case value_t::null:
18504 return false;
18505
18506 case value_t::string:
18507 return *lhs.m_value.string < *rhs.m_value.string;
18508
18509 case value_t::boolean:
18510 return lhs.m_value.boolean < rhs.m_value.boolean;
18511
18512 case value_t::number_integer:
18513 return lhs.m_value.number_integer < rhs.m_value.number_integer;
18514
18515 case value_t::number_unsigned:
18516 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18517
18518 case value_t::number_float:
18519 return lhs.m_value.number_float < rhs.m_value.number_float;
18520
18521 default:
18522 return false;
18523 }
18524 }
18525 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18526 {
18527 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18528 }
18529 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18530 {
18531 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
18532 }
18533 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18534 {
18535 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18536 }
18537 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18538 {
18539 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
18540 }
18541 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18542 {
18543 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18544 }
18545 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18546 {
18547 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18548 }
18549
18550 // We only reach this line if we cannot compare values. In that case,
18551 // we compare types. Note we have to call the operator explicitly,
18552 // because MSVC has problems otherwise.
18553 return operator<(lhs_type, rhs_type);
18554 }
18555
18556 /*!
18557 @brief comparison: less than
18558 @copydoc operator<(const_reference, const_reference)
18559 */
18560 template<typename ScalarType, typename std::enable_if<
18561 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)18562 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
18563 {
18564 return lhs < basic_json(rhs);
18565 }
18566
18567 /*!
18568 @brief comparison: less than
18569 @copydoc operator<(const_reference, const_reference)
18570 */
18571 template<typename ScalarType, typename std::enable_if<
18572 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)18573 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
18574 {
18575 return basic_json(lhs) < rhs;
18576 }
18577
18578 /*!
18579 @brief comparison: less than or equal
18580
18581 Compares whether one JSON value @a lhs is less than or equal to another
18582 JSON value by calculating `not (rhs < lhs)`.
18583
18584 @param[in] lhs first JSON value to consider
18585 @param[in] rhs second JSON value to consider
18586 @return whether @a lhs is less than or equal to @a rhs
18587
18588 @complexity Linear.
18589
18590 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18591
18592 @liveexample{The example demonstrates comparing several JSON
18593 types.,operator__greater}
18594
18595 @since version 1.0.0
18596 */
operator <=(const_reference lhs,const_reference rhs)18597 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
18598 {
18599 return not (rhs < lhs);
18600 }
18601
18602 /*!
18603 @brief comparison: less than or equal
18604 @copydoc operator<=(const_reference, const_reference)
18605 */
18606 template<typename ScalarType, typename std::enable_if<
18607 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)18608 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
18609 {
18610 return lhs <= basic_json(rhs);
18611 }
18612
18613 /*!
18614 @brief comparison: less than or equal
18615 @copydoc operator<=(const_reference, const_reference)
18616 */
18617 template<typename ScalarType, typename std::enable_if<
18618 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)18619 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
18620 {
18621 return basic_json(lhs) <= rhs;
18622 }
18623
18624 /*!
18625 @brief comparison: greater than
18626
18627 Compares whether one JSON value @a lhs is greater than another
18628 JSON value by calculating `not (lhs <= rhs)`.
18629
18630 @param[in] lhs first JSON value to consider
18631 @param[in] rhs second JSON value to consider
18632 @return whether @a lhs is greater than to @a rhs
18633
18634 @complexity Linear.
18635
18636 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18637
18638 @liveexample{The example demonstrates comparing several JSON
18639 types.,operator__lessequal}
18640
18641 @since version 1.0.0
18642 */
operator >(const_reference lhs,const_reference rhs)18643 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
18644 {
18645 return not (lhs <= rhs);
18646 }
18647
18648 /*!
18649 @brief comparison: greater than
18650 @copydoc operator>(const_reference, const_reference)
18651 */
18652 template<typename ScalarType, typename std::enable_if<
18653 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)18654 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
18655 {
18656 return lhs > basic_json(rhs);
18657 }
18658
18659 /*!
18660 @brief comparison: greater than
18661 @copydoc operator>(const_reference, const_reference)
18662 */
18663 template<typename ScalarType, typename std::enable_if<
18664 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)18665 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
18666 {
18667 return basic_json(lhs) > rhs;
18668 }
18669
18670 /*!
18671 @brief comparison: greater than or equal
18672
18673 Compares whether one JSON value @a lhs is greater than or equal to another
18674 JSON value by calculating `not (lhs < rhs)`.
18675
18676 @param[in] lhs first JSON value to consider
18677 @param[in] rhs second JSON value to consider
18678 @return whether @a lhs is greater than or equal to @a rhs
18679
18680 @complexity Linear.
18681
18682 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18683
18684 @liveexample{The example demonstrates comparing several JSON
18685 types.,operator__greaterequal}
18686
18687 @since version 1.0.0
18688 */
operator >=(const_reference lhs,const_reference rhs)18689 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
18690 {
18691 return not (lhs < rhs);
18692 }
18693
18694 /*!
18695 @brief comparison: greater than or equal
18696 @copydoc operator>=(const_reference, const_reference)
18697 */
18698 template<typename ScalarType, typename std::enable_if<
18699 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)18700 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
18701 {
18702 return lhs >= basic_json(rhs);
18703 }
18704
18705 /*!
18706 @brief comparison: greater than or equal
18707 @copydoc operator>=(const_reference, const_reference)
18708 */
18709 template<typename ScalarType, typename std::enable_if<
18710 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)18711 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
18712 {
18713 return basic_json(lhs) >= rhs;
18714 }
18715
18716 /// @}
18717
18718 ///////////////////
18719 // serialization //
18720 ///////////////////
18721
18722 /// @name serialization
18723 /// @{
18724
18725 /*!
18726 @brief serialize to stream
18727
18728 Serialize the given JSON value @a j to the output stream @a o. The JSON
18729 value will be serialized using the @ref dump member function.
18730
18731 - The indentation of the output can be controlled with the member variable
18732 `width` of the output stream @a o. For instance, using the manipulator
18733 `std::setw(4)` on @a o sets the indentation level to `4` and the
18734 serialization result is the same as calling `dump(4)`.
18735
18736 - The indentation character can be controlled with the member variable
18737 `fill` of the output stream @a o. For instance, the manipulator
18738 `std::setfill('\\t')` sets indentation to use a tab character rather than
18739 the default space character.
18740
18741 @param[in,out] o stream to serialize to
18742 @param[in] j JSON value to serialize
18743
18744 @return the stream @a o
18745
18746 @throw type_error.316 if a string stored inside the JSON value is not
18747 UTF-8 encoded
18748
18749 @complexity Linear.
18750
18751 @liveexample{The example below shows the serialization with different
18752 parameters to `width` to adjust the indentation level.,operator_serialize}
18753
18754 @since version 1.0.0; indentation character added in version 3.0.0
18755 */
operator <<(std::ostream & o,const basic_json & j)18756 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
18757 {
18758 // read width member and use it as indentation parameter if nonzero
18759 const bool pretty_print = o.width() > 0;
18760 const auto indentation = pretty_print ? o.width() : 0;
18761
18762 // reset width to 0 for subsequent calls to this stream
18763 o.width(0);
18764
18765 // do the actual serialization
18766 serializer s(detail::output_adapter<char>(o), o.fill());
18767 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
18768 return o;
18769 }
18770
18771 /*!
18772 @brief serialize to stream
18773 @deprecated This stream operator is deprecated and will be removed in
18774 future 4.0.0 of the library. Please use
18775 @ref operator<<(std::ostream&, const basic_json&)
18776 instead; that is, replace calls like `j >> o;` with `o << j;`.
18777 @since version 1.0.0; deprecated since version 3.0.0
18778 */
18779 JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)18780 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
18781 {
18782 return o << j;
18783 }
18784
18785 /// @}
18786
18787
18788 /////////////////////
18789 // deserialization //
18790 /////////////////////
18791
18792 /// @name deserialization
18793 /// @{
18794
18795 /*!
18796 @brief deserialize from a compatible input
18797
18798 This function reads from a compatible input. Examples are:
18799 - an array of 1-byte values
18800 - strings with character/literal type with size of 1 byte
18801 - input streams
18802 - container with contiguous storage of 1-byte values. Compatible container
18803 types include `std::vector`, `std::string`, `std::array`,
18804 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
18805 arrays can be used with `std::begin()`/`std::end()`. User-defined
18806 containers can be used as long as they implement random-access iterators
18807 and a contiguous storage.
18808
18809 @pre Each element of the container has a size of 1 byte. Violating this
18810 precondition yields undefined behavior. **This precondition is enforced
18811 with a static assertion.**
18812
18813 @pre The container storage is contiguous. Violating this precondition
18814 yields undefined behavior. **This precondition is enforced with an
18815 assertion.**
18816
18817 @warning There is no way to enforce all preconditions at compile-time. If
18818 the function is called with a noncompliant container and with
18819 assertions switched off, the behavior is undefined and will most
18820 likely yield segmentation violation.
18821
18822 @param[in] i input to read from
18823 @param[in] cb a parser callback function of type @ref parser_callback_t
18824 which is used to control the deserialization by filtering unwanted values
18825 (optional)
18826 @param[in] allow_exceptions whether to throw exceptions in case of a
18827 parse error (optional, true by default)
18828
18829 @return deserialized JSON value; in case of a parse error and
18830 @a allow_exceptions set to `false`, the return value will be
18831 value_t::discarded.
18832
18833 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
18834 of input; expected string literal""`
18835 @throw parse_error.102 if to_unicode fails or surrogate error
18836 @throw parse_error.103 if to_unicode fails
18837
18838 @complexity Linear in the length of the input. The parser is a predictive
18839 LL(1) parser. The complexity can be higher if the parser callback function
18840 @a cb has a super-linear complexity.
18841
18842 @note A UTF-8 byte order mark is silently ignored.
18843
18844 @liveexample{The example below demonstrates the `parse()` function reading
18845 from an array.,parse__array__parser_callback_t}
18846
18847 @liveexample{The example below demonstrates the `parse()` function with
18848 and without callback function.,parse__string__parser_callback_t}
18849
18850 @liveexample{The example below demonstrates the `parse()` function with
18851 and without callback function.,parse__istream__parser_callback_t}
18852
18853 @liveexample{The example below demonstrates the `parse()` function reading
18854 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
18855
18856 @since version 2.0.3 (contiguous containers)
18857 */
18858 JSON_NODISCARD
parse(detail::input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)18859 static basic_json parse(detail::input_adapter&& i,
18860 const parser_callback_t cb = nullptr,
18861 const bool allow_exceptions = true)
18862 {
18863 basic_json result;
18864 parser(i, cb, allow_exceptions).parse(true, result);
18865 return result;
18866 }
18867
accept(detail::input_adapter && i)18868 static bool accept(detail::input_adapter&& i)
18869 {
18870 return parser(i).accept(true);
18871 }
18872
18873 /*!
18874 @brief generate SAX events
18875
18876 The SAX event lister must follow the interface of @ref json_sax.
18877
18878 This function reads from a compatible input. Examples are:
18879 - an array of 1-byte values
18880 - strings with character/literal type with size of 1 byte
18881 - input streams
18882 - container with contiguous storage of 1-byte values. Compatible container
18883 types include `std::vector`, `std::string`, `std::array`,
18884 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
18885 arrays can be used with `std::begin()`/`std::end()`. User-defined
18886 containers can be used as long as they implement random-access iterators
18887 and a contiguous storage.
18888
18889 @pre Each element of the container has a size of 1 byte. Violating this
18890 precondition yields undefined behavior. **This precondition is enforced
18891 with a static assertion.**
18892
18893 @pre The container storage is contiguous. Violating this precondition
18894 yields undefined behavior. **This precondition is enforced with an
18895 assertion.**
18896
18897 @warning There is no way to enforce all preconditions at compile-time. If
18898 the function is called with a noncompliant container and with
18899 assertions switched off, the behavior is undefined and will most
18900 likely yield segmentation violation.
18901
18902 @param[in] i input to read from
18903 @param[in,out] sax SAX event listener
18904 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
18905 @param[in] strict whether the input has to be consumed completely
18906
18907 @return return value of the last processed SAX event
18908
18909 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
18910 of input; expected string literal""`
18911 @throw parse_error.102 if to_unicode fails or surrogate error
18912 @throw parse_error.103 if to_unicode fails
18913
18914 @complexity Linear in the length of the input. The parser is a predictive
18915 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
18916 a super-linear complexity.
18917
18918 @note A UTF-8 byte order mark is silently ignored.
18919
18920 @liveexample{The example below demonstrates the `sax_parse()` function
18921 reading from string and processing the events with a user-defined SAX
18922 event consumer.,sax_parse}
18923
18924 @since version 3.2.0
18925 */
18926 template <typename SAX>
sax_parse(detail::input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true)18927 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18928 input_format_t format = input_format_t::json,
18929 const bool strict = true)
18930 {
18931 assert(sax);
18932 return format == input_format_t::json
18933 ? parser(std::move(i)).sax_parse(sax, strict)
18934 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
18935 }
18936
18937 /*!
18938 @brief deserialize from an iterator range with contiguous storage
18939
18940 This function reads from an iterator range of a container with contiguous
18941 storage of 1-byte values. Compatible container types include
18942 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
18943 `std::initializer_list`. Furthermore, C-style arrays can be used with
18944 `std::begin()`/`std::end()`. User-defined containers can be used as long
18945 as they implement random-access iterators and a contiguous storage.
18946
18947 @pre The iterator range is contiguous. Violating this precondition yields
18948 undefined behavior. **This precondition is enforced with an assertion.**
18949 @pre Each element in the range has a size of 1 byte. Violating this
18950 precondition yields undefined behavior. **This precondition is enforced
18951 with a static assertion.**
18952
18953 @warning There is no way to enforce all preconditions at compile-time. If
18954 the function is called with noncompliant iterators and with
18955 assertions switched off, the behavior is undefined and will most
18956 likely yield segmentation violation.
18957
18958 @tparam IteratorType iterator of container with contiguous storage
18959 @param[in] first begin of the range to parse (included)
18960 @param[in] last end of the range to parse (excluded)
18961 @param[in] cb a parser callback function of type @ref parser_callback_t
18962 which is used to control the deserialization by filtering unwanted values
18963 (optional)
18964 @param[in] allow_exceptions whether to throw exceptions in case of a
18965 parse error (optional, true by default)
18966
18967 @return deserialized JSON value; in case of a parse error and
18968 @a allow_exceptions set to `false`, the return value will be
18969 value_t::discarded.
18970
18971 @throw parse_error.101 in case of an unexpected token
18972 @throw parse_error.102 if to_unicode fails or surrogate error
18973 @throw parse_error.103 if to_unicode fails
18974
18975 @complexity Linear in the length of the input. The parser is a predictive
18976 LL(1) parser. The complexity can be higher if the parser callback function
18977 @a cb has a super-linear complexity.
18978
18979 @note A UTF-8 byte order mark is silently ignored.
18980
18981 @liveexample{The example below demonstrates the `parse()` function reading
18982 from an iterator range.,parse__iteratortype__parser_callback_t}
18983
18984 @since version 2.0.3
18985 */
18986 template<class IteratorType, typename std::enable_if<
18987 std::is_base_of<
18988 std::random_access_iterator_tag,
18989 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)18990 static basic_json parse(IteratorType first, IteratorType last,
18991 const parser_callback_t cb = nullptr,
18992 const bool allow_exceptions = true)
18993 {
18994 basic_json result;
18995 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
18996 return result;
18997 }
18998
18999 template<class IteratorType, typename std::enable_if<
19000 std::is_base_of<
19001 std::random_access_iterator_tag,
19002 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)19003 static bool accept(IteratorType first, IteratorType last)
19004 {
19005 return parser(detail::input_adapter(first, last)).accept(true);
19006 }
19007
19008 template<class IteratorType, class SAX, typename std::enable_if<
19009 std::is_base_of<
19010 std::random_access_iterator_tag,
19011 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
sax_parse(IteratorType first,IteratorType last,SAX * sax)19012 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
19013 {
19014 return parser(detail::input_adapter(first, last)).sax_parse(sax);
19015 }
19016
19017 /*!
19018 @brief deserialize from stream
19019 @deprecated This stream operator is deprecated and will be removed in
19020 version 4.0.0 of the library. Please use
19021 @ref operator>>(std::istream&, basic_json&)
19022 instead; that is, replace calls like `j << i;` with `i >> j;`.
19023 @since version 1.0.0; deprecated since version 3.0.0
19024 */
19025 JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)19026 friend std::istream& operator<<(basic_json& j, std::istream& i)
19027 {
19028 return operator>>(i, j);
19029 }
19030
19031 /*!
19032 @brief deserialize from stream
19033
19034 Deserializes an input stream to a JSON value.
19035
19036 @param[in,out] i input stream to read a serialized JSON value from
19037 @param[in,out] j JSON value to write the deserialized input to
19038
19039 @throw parse_error.101 in case of an unexpected token
19040 @throw parse_error.102 if to_unicode fails or surrogate error
19041 @throw parse_error.103 if to_unicode fails
19042
19043 @complexity Linear in the length of the input. The parser is a predictive
19044 LL(1) parser.
19045
19046 @note A UTF-8 byte order mark is silently ignored.
19047
19048 @liveexample{The example below shows how a JSON value is constructed by
19049 reading a serialization from a stream.,operator_deserialize}
19050
19051 @sa parse(std::istream&, const parser_callback_t) for a variant with a
19052 parser callback function to filter values while parsing
19053
19054 @since version 1.0.0
19055 */
operator >>(std::istream & i,basic_json & j)19056 friend std::istream& operator>>(std::istream& i, basic_json& j)
19057 {
19058 parser(detail::input_adapter(i)).parse(false, j);
19059 return i;
19060 }
19061
19062 /// @}
19063
19064 ///////////////////////////
19065 // convenience functions //
19066 ///////////////////////////
19067
19068 /*!
19069 @brief return the type as string
19070
19071 Returns the type name as string to be used in error messages - usually to
19072 indicate that a function was called on a wrong JSON type.
19073
19074 @return a string representation of a the @a m_type member:
19075 Value type | return value
19076 ----------- | -------------
19077 null | `"null"`
19078 boolean | `"boolean"`
19079 string | `"string"`
19080 number | `"number"` (for all number types)
19081 object | `"object"`
19082 array | `"array"`
19083 discarded | `"discarded"`
19084
19085 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19086
19087 @complexity Constant.
19088
19089 @liveexample{The following code exemplifies `type_name()` for all JSON
19090 types.,type_name}
19091
19092 @sa @ref type() -- return the type of the JSON value
19093 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
19094
19095 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
19096 since 3.0.0
19097 */
type_name() const19098 const char* type_name() const noexcept
19099 {
19100 {
19101 switch (m_type)
19102 {
19103 case value_t::null:
19104 return "null";
19105 case value_t::object:
19106 return "object";
19107 case value_t::array:
19108 return "array";
19109 case value_t::string:
19110 return "string";
19111 case value_t::boolean:
19112 return "boolean";
19113 case value_t::discarded:
19114 return "discarded";
19115 default:
19116 return "number";
19117 }
19118 }
19119 }
19120
19121
19122 private:
19123 //////////////////////
19124 // member variables //
19125 //////////////////////
19126
19127 /// the type of the current element
19128 value_t m_type = value_t::null;
19129
19130 /// the value of the current element
19131 json_value m_value = {};
19132
19133 //////////////////////////////////////////
19134 // binary serialization/deserialization //
19135 //////////////////////////////////////////
19136
19137 /// @name binary serialization/deserialization support
19138 /// @{
19139
19140 public:
19141 /*!
19142 @brief create a CBOR serialization of a given JSON value
19143
19144 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
19145 Binary Object Representation) serialization format. CBOR is a binary
19146 serialization format which aims to be more compact than JSON itself, yet
19147 more efficient to parse.
19148
19149 The library uses the following mapping from JSON values types to
19150 CBOR types according to the CBOR specification (RFC 7049):
19151
19152 JSON value type | value/range | CBOR type | first byte
19153 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
19154 null | `null` | Null | 0xF6
19155 boolean | `true` | True | 0xF5
19156 boolean | `false` | False | 0xF4
19157 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
19158 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
19159 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
19160 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
19161 number_integer | -24..-1 | Negative integer | 0x20..0x37
19162 number_integer | 0..23 | Integer | 0x00..0x17
19163 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
19164 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
19165 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
19166 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
19167 number_unsigned | 0..23 | Integer | 0x00..0x17
19168 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
19169 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
19170 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
19171 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
19172 number_float | *any value* | Double-Precision Float | 0xFB
19173 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
19174 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
19175 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
19176 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
19177 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
19178 array | *size*: 0..23 | array | 0x80..0x97
19179 array | *size*: 23..255 | array (1 byte follow) | 0x98
19180 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
19181 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
19182 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
19183 object | *size*: 0..23 | map | 0xA0..0xB7
19184 object | *size*: 23..255 | map (1 byte follow) | 0xB8
19185 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
19186 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
19187 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
19188
19189 @note The mapping is **complete** in the sense that any JSON value type
19190 can be converted to a CBOR value.
19191
19192 @note If NaN or Infinity are stored inside a JSON number, they are
19193 serialized properly. This behavior differs from the @ref dump()
19194 function which serializes NaN or Infinity to `null`.
19195
19196 @note The following CBOR types are not used in the conversion:
19197 - byte strings (0x40..0x5F)
19198 - UTF-8 strings terminated by "break" (0x7F)
19199 - arrays terminated by "break" (0x9F)
19200 - maps terminated by "break" (0xBF)
19201 - date/time (0xC0..0xC1)
19202 - bignum (0xC2..0xC3)
19203 - decimal fraction (0xC4)
19204 - bigfloat (0xC5)
19205 - tagged items (0xC6..0xD4, 0xD8..0xDB)
19206 - expected conversions (0xD5..0xD7)
19207 - simple values (0xE0..0xF3, 0xF8)
19208 - undefined (0xF7)
19209 - half and single-precision floats (0xF9-0xFA)
19210 - break (0xFF)
19211
19212 @param[in] j JSON value to serialize
19213 @return MessagePack serialization as byte vector
19214
19215 @complexity Linear in the size of the JSON value @a j.
19216
19217 @liveexample{The example shows the serialization of a JSON value to a byte
19218 vector in CBOR format.,to_cbor}
19219
19220 @sa http://cbor.io
19221 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19222 analogous deserialization
19223 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19224 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19225 related UBJSON format
19226
19227 @since version 2.0.9
19228 */
to_cbor(const basic_json & j)19229 static std::vector<uint8_t> to_cbor(const basic_json& j)
19230 {
19231 std::vector<uint8_t> result;
19232 to_cbor(j, result);
19233 return result;
19234 }
19235
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)19236 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
19237 {
19238 binary_writer<uint8_t>(o).write_cbor(j);
19239 }
19240
to_cbor(const basic_json & j,detail::output_adapter<char> o)19241 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
19242 {
19243 binary_writer<char>(o).write_cbor(j);
19244 }
19245
19246 /*!
19247 @brief create a MessagePack serialization of a given JSON value
19248
19249 Serializes a given JSON value @a j to a byte vector using the MessagePack
19250 serialization format. MessagePack is a binary serialization format which
19251 aims to be more compact than JSON itself, yet more efficient to parse.
19252
19253 The library uses the following mapping from JSON values types to
19254 MessagePack types according to the MessagePack specification:
19255
19256 JSON value type | value/range | MessagePack type | first byte
19257 --------------- | --------------------------------- | ---------------- | ----------
19258 null | `null` | nil | 0xC0
19259 boolean | `true` | true | 0xC3
19260 boolean | `false` | false | 0xC2
19261 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
19262 number_integer | -2147483648..-32769 | int32 | 0xD2
19263 number_integer | -32768..-129 | int16 | 0xD1
19264 number_integer | -128..-33 | int8 | 0xD0
19265 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
19266 number_integer | 0..127 | positive fixint | 0x00..0x7F
19267 number_integer | 128..255 | uint 8 | 0xCC
19268 number_integer | 256..65535 | uint 16 | 0xCD
19269 number_integer | 65536..4294967295 | uint 32 | 0xCE
19270 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
19271 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
19272 number_unsigned | 128..255 | uint 8 | 0xCC
19273 number_unsigned | 256..65535 | uint 16 | 0xCD
19274 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
19275 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
19276 number_float | *any value* | float 64 | 0xCB
19277 string | *length*: 0..31 | fixstr | 0xA0..0xBF
19278 string | *length*: 32..255 | str 8 | 0xD9
19279 string | *length*: 256..65535 | str 16 | 0xDA
19280 string | *length*: 65536..4294967295 | str 32 | 0xDB
19281 array | *size*: 0..15 | fixarray | 0x90..0x9F
19282 array | *size*: 16..65535 | array 16 | 0xDC
19283 array | *size*: 65536..4294967295 | array 32 | 0xDD
19284 object | *size*: 0..15 | fix map | 0x80..0x8F
19285 object | *size*: 16..65535 | map 16 | 0xDE
19286 object | *size*: 65536..4294967295 | map 32 | 0xDF
19287
19288 @note The mapping is **complete** in the sense that any JSON value type
19289 can be converted to a MessagePack value.
19290
19291 @note The following values can **not** be converted to a MessagePack value:
19292 - strings with more than 4294967295 bytes
19293 - arrays with more than 4294967295 elements
19294 - objects with more than 4294967295 elements
19295
19296 @note The following MessagePack types are not used in the conversion:
19297 - bin 8 - bin 32 (0xC4..0xC6)
19298 - ext 8 - ext 32 (0xC7..0xC9)
19299 - float 32 (0xCA)
19300 - fixext 1 - fixext 16 (0xD4..0xD8)
19301
19302 @note Any MessagePack output created @ref to_msgpack can be successfully
19303 parsed by @ref from_msgpack.
19304
19305 @note If NaN or Infinity are stored inside a JSON number, they are
19306 serialized properly. This behavior differs from the @ref dump()
19307 function which serializes NaN or Infinity to `null`.
19308
19309 @param[in] j JSON value to serialize
19310 @return MessagePack serialization as byte vector
19311
19312 @complexity Linear in the size of the JSON value @a j.
19313
19314 @liveexample{The example shows the serialization of a JSON value to a byte
19315 vector in MessagePack format.,to_msgpack}
19316
19317 @sa http://msgpack.org
19318 @sa @ref from_msgpack for the analogous deserialization
19319 @sa @ref to_cbor(const basic_json& for the related CBOR format
19320 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19321 related UBJSON format
19322
19323 @since version 2.0.9
19324 */
to_msgpack(const basic_json & j)19325 static std::vector<uint8_t> to_msgpack(const basic_json& j)
19326 {
19327 std::vector<uint8_t> result;
19328 to_msgpack(j, result);
19329 return result;
19330 }
19331
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)19332 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
19333 {
19334 binary_writer<uint8_t>(o).write_msgpack(j);
19335 }
19336
to_msgpack(const basic_json & j,detail::output_adapter<char> o)19337 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
19338 {
19339 binary_writer<char>(o).write_msgpack(j);
19340 }
19341
19342 /*!
19343 @brief create a UBJSON serialization of a given JSON value
19344
19345 Serializes a given JSON value @a j to a byte vector using the UBJSON
19346 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
19347 than JSON itself, yet more efficient to parse.
19348
19349 The library uses the following mapping from JSON values types to
19350 UBJSON types according to the UBJSON specification:
19351
19352 JSON value type | value/range | UBJSON type | marker
19353 --------------- | --------------------------------- | ----------- | ------
19354 null | `null` | null | `Z`
19355 boolean | `true` | true | `T`
19356 boolean | `false` | false | `F`
19357 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
19358 number_integer | -2147483648..-32769 | int32 | `l`
19359 number_integer | -32768..-129 | int16 | `I`
19360 number_integer | -128..127 | int8 | `i`
19361 number_integer | 128..255 | uint8 | `U`
19362 number_integer | 256..32767 | int16 | `I`
19363 number_integer | 32768..2147483647 | int32 | `l`
19364 number_integer | 2147483648..9223372036854775807 | int64 | `L`
19365 number_unsigned | 0..127 | int8 | `i`
19366 number_unsigned | 128..255 | uint8 | `U`
19367 number_unsigned | 256..32767 | int16 | `I`
19368 number_unsigned | 32768..2147483647 | int32 | `l`
19369 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
19370 number_float | *any value* | float64 | `D`
19371 string | *with shortest length indicator* | string | `S`
19372 array | *see notes on optimized format* | array | `[`
19373 object | *see notes on optimized format* | map | `{`
19374
19375 @note The mapping is **complete** in the sense that any JSON value type
19376 can be converted to a UBJSON value.
19377
19378 @note The following values can **not** be converted to a UBJSON value:
19379 - strings with more than 9223372036854775807 bytes (theoretical)
19380 - unsigned integer numbers above 9223372036854775807
19381
19382 @note The following markers are not used in the conversion:
19383 - `Z`: no-op values are not created.
19384 - `C`: single-byte strings are serialized with `S` markers.
19385
19386 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
19387 by @ref from_ubjson.
19388
19389 @note If NaN or Infinity are stored inside a JSON number, they are
19390 serialized properly. This behavior differs from the @ref dump()
19391 function which serializes NaN or Infinity to `null`.
19392
19393 @note The optimized formats for containers are supported: Parameter
19394 @a use_size adds size information to the beginning of a container and
19395 removes the closing marker. Parameter @a use_type further checks
19396 whether all elements of a container have the same type and adds the
19397 type marker to the beginning of the container. The @a use_type
19398 parameter must only be used together with @a use_size = true. Note
19399 that @a use_size = true alone may result in larger representations -
19400 the benefit of this parameter is that the receiving side is
19401 immediately informed on the number of elements of the container.
19402
19403 @param[in] j JSON value to serialize
19404 @param[in] use_size whether to add size annotations to container types
19405 @param[in] use_type whether to add type annotations to container types
19406 (must be combined with @a use_size = true)
19407 @return UBJSON serialization as byte vector
19408
19409 @complexity Linear in the size of the JSON value @a j.
19410
19411 @liveexample{The example shows the serialization of a JSON value to a byte
19412 vector in UBJSON format.,to_ubjson}
19413
19414 @sa http://ubjson.org
19415 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19416 analogous deserialization
19417 @sa @ref to_cbor(const basic_json& for the related CBOR format
19418 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19419
19420 @since version 3.1.0
19421 */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)19422 static std::vector<uint8_t> to_ubjson(const basic_json& j,
19423 const bool use_size = false,
19424 const bool use_type = false)
19425 {
19426 std::vector<uint8_t> result;
19427 to_ubjson(j, result, use_size, use_type);
19428 return result;
19429 }
19430
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)19431 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
19432 const bool use_size = false, const bool use_type = false)
19433 {
19434 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
19435 }
19436
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)19437 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
19438 const bool use_size = false, const bool use_type = false)
19439 {
19440 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
19441 }
19442
19443
19444 /*!
19445 @brief Serializes the given JSON object `j` to BSON and returns a vector
19446 containing the corresponding BSON-representation.
19447
19448 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
19449 stored as a single entity (a so-called document).
19450
19451 The library uses the following mapping from JSON values types to BSON types:
19452
19453 JSON value type | value/range | BSON type | marker
19454 --------------- | --------------------------------- | ----------- | ------
19455 null | `null` | null | 0x0A
19456 boolean | `true`, `false` | boolean | 0x08
19457 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
19458 number_integer | -2147483648..2147483647 | int32 | 0x10
19459 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
19460 number_unsigned | 0..2147483647 | int32 | 0x10
19461 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
19462 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
19463 number_float | *any value* | double | 0x01
19464 string | *any value* | string | 0x02
19465 array | *any value* | document | 0x04
19466 object | *any value* | document | 0x03
19467
19468 @warning The mapping is **incomplete**, since only JSON-objects (and things
19469 contained therein) can be serialized to BSON.
19470 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
19471 and the keys may not contain U+0000, since they are serialized a
19472 zero-terminated c-strings.
19473
19474 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
19475 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
19476 @throw type_error.317 if `!j.is_object()`
19477
19478 @pre The input `j` is required to be an object: `j.is_object() == true`.
19479
19480 @note Any BSON output created via @ref to_bson can be successfully parsed
19481 by @ref from_bson.
19482
19483 @param[in] j JSON value to serialize
19484 @return BSON serialization as byte vector
19485
19486 @complexity Linear in the size of the JSON value @a j.
19487
19488 @liveexample{The example shows the serialization of a JSON value to a byte
19489 vector in BSON format.,to_bson}
19490
19491 @sa http://bsonspec.org/spec.html
19492 @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
19493 analogous deserialization
19494 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19495 related UBJSON format
19496 @sa @ref to_cbor(const basic_json&) for the related CBOR format
19497 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19498 */
to_bson(const basic_json & j)19499 static std::vector<uint8_t> to_bson(const basic_json& j)
19500 {
19501 std::vector<uint8_t> result;
19502 to_bson(j, result);
19503 return result;
19504 }
19505
19506 /*!
19507 @brief Serializes the given JSON object `j` to BSON and forwards the
19508 corresponding BSON-representation to the given output_adapter `o`.
19509 @param j The JSON object to convert to BSON.
19510 @param o The output adapter that receives the binary BSON representation.
19511 @pre The input `j` shall be an object: `j.is_object() == true`
19512 @sa @ref to_bson(const basic_json&)
19513 */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)19514 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
19515 {
19516 binary_writer<uint8_t>(o).write_bson(j);
19517 }
19518
19519 /*!
19520 @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
19521 */
to_bson(const basic_json & j,detail::output_adapter<char> o)19522 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
19523 {
19524 binary_writer<char>(o).write_bson(j);
19525 }
19526
19527
19528 /*!
19529 @brief create a JSON value from an input in CBOR format
19530
19531 Deserializes a given input @a i to a JSON value using the CBOR (Concise
19532 Binary Object Representation) serialization format.
19533
19534 The library maps CBOR types to JSON value types as follows:
19535
19536 CBOR type | JSON value type | first byte
19537 ---------------------- | --------------- | ----------
19538 Integer | number_unsigned | 0x00..0x17
19539 Unsigned integer | number_unsigned | 0x18
19540 Unsigned integer | number_unsigned | 0x19
19541 Unsigned integer | number_unsigned | 0x1A
19542 Unsigned integer | number_unsigned | 0x1B
19543 Negative integer | number_integer | 0x20..0x37
19544 Negative integer | number_integer | 0x38
19545 Negative integer | number_integer | 0x39
19546 Negative integer | number_integer | 0x3A
19547 Negative integer | number_integer | 0x3B
19548 Negative integer | number_integer | 0x40..0x57
19549 UTF-8 string | string | 0x60..0x77
19550 UTF-8 string | string | 0x78
19551 UTF-8 string | string | 0x79
19552 UTF-8 string | string | 0x7A
19553 UTF-8 string | string | 0x7B
19554 UTF-8 string | string | 0x7F
19555 array | array | 0x80..0x97
19556 array | array | 0x98
19557 array | array | 0x99
19558 array | array | 0x9A
19559 array | array | 0x9B
19560 array | array | 0x9F
19561 map | object | 0xA0..0xB7
19562 map | object | 0xB8
19563 map | object | 0xB9
19564 map | object | 0xBA
19565 map | object | 0xBB
19566 map | object | 0xBF
19567 False | `false` | 0xF4
19568 True | `true` | 0xF5
19569 Null | `null` | 0xF6
19570 Half-Precision Float | number_float | 0xF9
19571 Single-Precision Float | number_float | 0xFA
19572 Double-Precision Float | number_float | 0xFB
19573
19574 @warning The mapping is **incomplete** in the sense that not all CBOR
19575 types can be converted to a JSON value. The following CBOR types
19576 are not supported and will yield parse errors (parse_error.112):
19577 - byte strings (0x40..0x5F)
19578 - date/time (0xC0..0xC1)
19579 - bignum (0xC2..0xC3)
19580 - decimal fraction (0xC4)
19581 - bigfloat (0xC5)
19582 - tagged items (0xC6..0xD4, 0xD8..0xDB)
19583 - expected conversions (0xD5..0xD7)
19584 - simple values (0xE0..0xF3, 0xF8)
19585 - undefined (0xF7)
19586
19587 @warning CBOR allows map keys of any type, whereas JSON only allows
19588 strings as keys in object values. Therefore, CBOR maps with keys
19589 other than UTF-8 strings are rejected (parse_error.113).
19590
19591 @note Any CBOR output created @ref to_cbor can be successfully parsed by
19592 @ref from_cbor.
19593
19594 @param[in] i an input in CBOR format convertible to an input adapter
19595 @param[in] strict whether to expect the input to be consumed until EOF
19596 (true by default)
19597 @param[in] allow_exceptions whether to throw exceptions in case of a
19598 parse error (optional, true by default)
19599
19600 @return deserialized JSON value; in case of a parse error and
19601 @a allow_exceptions set to `false`, the return value will be
19602 value_t::discarded.
19603
19604 @throw parse_error.110 if the given input ends prematurely or the end of
19605 file was not reached when @a strict was set to true
19606 @throw parse_error.112 if unsupported features from CBOR were
19607 used in the given input @a v or if the input is not valid CBOR
19608 @throw parse_error.113 if a string was expected as map key, but not found
19609
19610 @complexity Linear in the size of the input @a i.
19611
19612 @liveexample{The example shows the deserialization of a byte vector in CBOR
19613 format to a JSON value.,from_cbor}
19614
19615 @sa http://cbor.io
19616 @sa @ref to_cbor(const basic_json&) for the analogous serialization
19617 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
19618 related MessagePack format
19619 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19620 related UBJSON format
19621
19622 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
19623 consume input adapters, removed start_index parameter, and added
19624 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
19625 since 3.2.0
19626 */
19627 JSON_NODISCARD
from_cbor(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19628 static basic_json from_cbor(detail::input_adapter&& i,
19629 const bool strict = true,
19630 const bool allow_exceptions = true)
19631 {
19632 basic_json result;
19633 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19634 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
19635 return res ? result : basic_json(value_t::discarded);
19636 }
19637
19638 /*!
19639 @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
19640 */
19641 template<typename A1, typename A2,
19642 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19643 JSON_NODISCARD
from_cbor(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19644 static basic_json from_cbor(A1 && a1, A2 && a2,
19645 const bool strict = true,
19646 const bool allow_exceptions = true)
19647 {
19648 basic_json result;
19649 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19650 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19651 return res ? result : basic_json(value_t::discarded);
19652 }
19653
19654 /*!
19655 @brief create a JSON value from an input in MessagePack format
19656
19657 Deserializes a given input @a i to a JSON value using the MessagePack
19658 serialization format.
19659
19660 The library maps MessagePack types to JSON value types as follows:
19661
19662 MessagePack type | JSON value type | first byte
19663 ---------------- | --------------- | ----------
19664 positive fixint | number_unsigned | 0x00..0x7F
19665 fixmap | object | 0x80..0x8F
19666 fixarray | array | 0x90..0x9F
19667 fixstr | string | 0xA0..0xBF
19668 nil | `null` | 0xC0
19669 false | `false` | 0xC2
19670 true | `true` | 0xC3
19671 float 32 | number_float | 0xCA
19672 float 64 | number_float | 0xCB
19673 uint 8 | number_unsigned | 0xCC
19674 uint 16 | number_unsigned | 0xCD
19675 uint 32 | number_unsigned | 0xCE
19676 uint 64 | number_unsigned | 0xCF
19677 int 8 | number_integer | 0xD0
19678 int 16 | number_integer | 0xD1
19679 int 32 | number_integer | 0xD2
19680 int 64 | number_integer | 0xD3
19681 str 8 | string | 0xD9
19682 str 16 | string | 0xDA
19683 str 32 | string | 0xDB
19684 array 16 | array | 0xDC
19685 array 32 | array | 0xDD
19686 map 16 | object | 0xDE
19687 map 32 | object | 0xDF
19688 negative fixint | number_integer | 0xE0-0xFF
19689
19690 @warning The mapping is **incomplete** in the sense that not all
19691 MessagePack types can be converted to a JSON value. The following
19692 MessagePack types are not supported and will yield parse errors:
19693 - bin 8 - bin 32 (0xC4..0xC6)
19694 - ext 8 - ext 32 (0xC7..0xC9)
19695 - fixext 1 - fixext 16 (0xD4..0xD8)
19696
19697 @note Any MessagePack output created @ref to_msgpack can be successfully
19698 parsed by @ref from_msgpack.
19699
19700 @param[in] i an input in MessagePack format convertible to an input
19701 adapter
19702 @param[in] strict whether to expect the input to be consumed until EOF
19703 (true by default)
19704 @param[in] allow_exceptions whether to throw exceptions in case of a
19705 parse error (optional, true by default)
19706
19707 @return deserialized JSON value; in case of a parse error and
19708 @a allow_exceptions set to `false`, the return value will be
19709 value_t::discarded.
19710
19711 @throw parse_error.110 if the given input ends prematurely or the end of
19712 file was not reached when @a strict was set to true
19713 @throw parse_error.112 if unsupported features from MessagePack were
19714 used in the given input @a i or if the input is not valid MessagePack
19715 @throw parse_error.113 if a string was expected as map key, but not found
19716
19717 @complexity Linear in the size of the input @a i.
19718
19719 @liveexample{The example shows the deserialization of a byte vector in
19720 MessagePack format to a JSON value.,from_msgpack}
19721
19722 @sa http://msgpack.org
19723 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
19724 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19725 related CBOR format
19726 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
19727 the related UBJSON format
19728 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
19729 the related BSON format
19730
19731 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
19732 consume input adapters, removed start_index parameter, and added
19733 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
19734 since 3.2.0
19735 */
19736 JSON_NODISCARD
from_msgpack(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19737 static basic_json from_msgpack(detail::input_adapter&& i,
19738 const bool strict = true,
19739 const bool allow_exceptions = true)
19740 {
19741 basic_json result;
19742 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19743 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
19744 return res ? result : basic_json(value_t::discarded);
19745 }
19746
19747 /*!
19748 @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
19749 */
19750 template<typename A1, typename A2,
19751 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19752 JSON_NODISCARD
from_msgpack(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19753 static basic_json from_msgpack(A1 && a1, A2 && a2,
19754 const bool strict = true,
19755 const bool allow_exceptions = true)
19756 {
19757 basic_json result;
19758 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19759 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19760 return res ? result : basic_json(value_t::discarded);
19761 }
19762
19763 /*!
19764 @brief create a JSON value from an input in UBJSON format
19765
19766 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
19767 Binary JSON) serialization format.
19768
19769 The library maps UBJSON types to JSON value types as follows:
19770
19771 UBJSON type | JSON value type | marker
19772 ----------- | --------------------------------------- | ------
19773 no-op | *no value, next value is read* | `N`
19774 null | `null` | `Z`
19775 false | `false` | `F`
19776 true | `true` | `T`
19777 float32 | number_float | `d`
19778 float64 | number_float | `D`
19779 uint8 | number_unsigned | `U`
19780 int8 | number_integer | `i`
19781 int16 | number_integer | `I`
19782 int32 | number_integer | `l`
19783 int64 | number_integer | `L`
19784 string | string | `S`
19785 char | string | `C`
19786 array | array (optimized values are supported) | `[`
19787 object | object (optimized values are supported) | `{`
19788
19789 @note The mapping is **complete** in the sense that any UBJSON value can
19790 be converted to a JSON value.
19791
19792 @param[in] i an input in UBJSON format convertible to an input adapter
19793 @param[in] strict whether to expect the input to be consumed until EOF
19794 (true by default)
19795 @param[in] allow_exceptions whether to throw exceptions in case of a
19796 parse error (optional, true by default)
19797
19798 @return deserialized JSON value; in case of a parse error and
19799 @a allow_exceptions set to `false`, the return value will be
19800 value_t::discarded.
19801
19802 @throw parse_error.110 if the given input ends prematurely or the end of
19803 file was not reached when @a strict was set to true
19804 @throw parse_error.112 if a parse error occurs
19805 @throw parse_error.113 if a string could not be parsed successfully
19806
19807 @complexity Linear in the size of the input @a i.
19808
19809 @liveexample{The example shows the deserialization of a byte vector in
19810 UBJSON format to a JSON value.,from_ubjson}
19811
19812 @sa http://ubjson.org
19813 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19814 analogous serialization
19815 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19816 related CBOR format
19817 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
19818 the related MessagePack format
19819 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
19820 the related BSON format
19821
19822 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
19823 */
19824 JSON_NODISCARD
from_ubjson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19825 static basic_json from_ubjson(detail::input_adapter&& i,
19826 const bool strict = true,
19827 const bool allow_exceptions = true)
19828 {
19829 basic_json result;
19830 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19831 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
19832 return res ? result : basic_json(value_t::discarded);
19833 }
19834
19835 /*!
19836 @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
19837 */
19838 template<typename A1, typename A2,
19839 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19840 JSON_NODISCARD
from_ubjson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19841 static basic_json from_ubjson(A1 && a1, A2 && a2,
19842 const bool strict = true,
19843 const bool allow_exceptions = true)
19844 {
19845 basic_json result;
19846 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19847 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19848 return res ? result : basic_json(value_t::discarded);
19849 }
19850
19851 /*!
19852 @brief Create a JSON value from an input in BSON format
19853
19854 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
19855 serialization format.
19856
19857 The library maps BSON record types to JSON value types as follows:
19858
19859 BSON type | BSON marker byte | JSON value type
19860 --------------- | ---------------- | ---------------------------
19861 double | 0x01 | number_float
19862 string | 0x02 | string
19863 document | 0x03 | object
19864 array | 0x04 | array
19865 binary | 0x05 | still unsupported
19866 undefined | 0x06 | still unsupported
19867 ObjectId | 0x07 | still unsupported
19868 boolean | 0x08 | boolean
19869 UTC Date-Time | 0x09 | still unsupported
19870 null | 0x0A | null
19871 Regular Expr. | 0x0B | still unsupported
19872 DB Pointer | 0x0C | still unsupported
19873 JavaScript Code | 0x0D | still unsupported
19874 Symbol | 0x0E | still unsupported
19875 JavaScript Code | 0x0F | still unsupported
19876 int32 | 0x10 | number_integer
19877 Timestamp | 0x11 | still unsupported
19878 128-bit decimal float | 0x13 | still unsupported
19879 Max Key | 0x7F | still unsupported
19880 Min Key | 0xFF | still unsupported
19881
19882 @warning The mapping is **incomplete**. The unsupported mappings
19883 are indicated in the table above.
19884
19885 @param[in] i an input in BSON format convertible to an input adapter
19886 @param[in] strict whether to expect the input to be consumed until EOF
19887 (true by default)
19888 @param[in] allow_exceptions whether to throw exceptions in case of a
19889 parse error (optional, true by default)
19890
19891 @return deserialized JSON value; in case of a parse error and
19892 @a allow_exceptions set to `false`, the return value will be
19893 value_t::discarded.
19894
19895 @throw parse_error.114 if an unsupported BSON record type is encountered
19896
19897 @complexity Linear in the size of the input @a i.
19898
19899 @liveexample{The example shows the deserialization of a byte vector in
19900 BSON format to a JSON value.,from_bson}
19901
19902 @sa http://bsonspec.org/spec.html
19903 @sa @ref to_bson(const basic_json&) for the analogous serialization
19904 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19905 related CBOR format
19906 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
19907 the related MessagePack format
19908 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19909 related UBJSON format
19910 */
19911 JSON_NODISCARD
from_bson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19912 static basic_json from_bson(detail::input_adapter&& i,
19913 const bool strict = true,
19914 const bool allow_exceptions = true)
19915 {
19916 basic_json result;
19917 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19918 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
19919 return res ? result : basic_json(value_t::discarded);
19920 }
19921
19922 /*!
19923 @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
19924 */
19925 template<typename A1, typename A2,
19926 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19927 JSON_NODISCARD
from_bson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19928 static basic_json from_bson(A1 && a1, A2 && a2,
19929 const bool strict = true,
19930 const bool allow_exceptions = true)
19931 {
19932 basic_json result;
19933 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19934 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19935 return res ? result : basic_json(value_t::discarded);
19936 }
19937
19938
19939
19940 /// @}
19941
19942 //////////////////////////
19943 // JSON Pointer support //
19944 //////////////////////////
19945
19946 /// @name JSON Pointer functions
19947 /// @{
19948
19949 /*!
19950 @brief access specified element via JSON Pointer
19951
19952 Uses a JSON pointer to retrieve a reference to the respective JSON value.
19953 No bound checking is performed. Similar to @ref operator[](const typename
19954 object_t::key_type&), `null` values are created in arrays and objects if
19955 necessary.
19956
19957 In particular:
19958 - If the JSON pointer points to an object key that does not exist, it
19959 is created an filled with a `null` value before a reference to it
19960 is returned.
19961 - If the JSON pointer points to an array index that does not exist, it
19962 is created an filled with a `null` value before a reference to it
19963 is returned. All indices between the current maximum and the given
19964 index are also filled with `null`.
19965 - The special value `-` is treated as a synonym for the index past the
19966 end.
19967
19968 @param[in] ptr a JSON pointer
19969
19970 @return reference to the element pointed to by @a ptr
19971
19972 @complexity Constant.
19973
19974 @throw parse_error.106 if an array index begins with '0'
19975 @throw parse_error.109 if an array index was not a number
19976 @throw out_of_range.404 if the JSON pointer can not be resolved
19977
19978 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
19979
19980 @since version 2.0.0
19981 */
operator [](const json_pointer & ptr)19982 reference operator[](const json_pointer& ptr)
19983 {
19984 return ptr.get_unchecked(this);
19985 }
19986
19987 /*!
19988 @brief access specified element via JSON Pointer
19989
19990 Uses a JSON pointer to retrieve a reference to the respective JSON value.
19991 No bound checking is performed. The function does not change the JSON
19992 value; no `null` values are created. In particular, the the special value
19993 `-` yields an exception.
19994
19995 @param[in] ptr JSON pointer to the desired element
19996
19997 @return const reference to the element pointed to by @a ptr
19998
19999 @complexity Constant.
20000
20001 @throw parse_error.106 if an array index begins with '0'
20002 @throw parse_error.109 if an array index was not a number
20003 @throw out_of_range.402 if the array index '-' is used
20004 @throw out_of_range.404 if the JSON pointer can not be resolved
20005
20006 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
20007
20008 @since version 2.0.0
20009 */
operator [](const json_pointer & ptr) const20010 const_reference operator[](const json_pointer& ptr) const
20011 {
20012 return ptr.get_unchecked(this);
20013 }
20014
20015 /*!
20016 @brief access specified element via JSON Pointer
20017
20018 Returns a reference to the element at with specified JSON pointer @a ptr,
20019 with bounds checking.
20020
20021 @param[in] ptr JSON pointer to the desired element
20022
20023 @return reference to the element pointed to by @a ptr
20024
20025 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
20026 begins with '0'. See example below.
20027
20028 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
20029 is not a number. See example below.
20030
20031 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
20032 is out of range. See example below.
20033
20034 @throw out_of_range.402 if the array index '-' is used in the passed JSON
20035 pointer @a ptr. As `at` provides checked access (and no elements are
20036 implicitly inserted), the index '-' is always invalid. See example below.
20037
20038 @throw out_of_range.403 if the JSON pointer describes a key of an object
20039 which cannot be found. See example below.
20040
20041 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
20042 See example below.
20043
20044 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20045 changes in the JSON value.
20046
20047 @complexity Constant.
20048
20049 @since version 2.0.0
20050
20051 @liveexample{The behavior is shown in the example.,at_json_pointer}
20052 */
at(const json_pointer & ptr)20053 reference at(const json_pointer& ptr)
20054 {
20055 return ptr.get_checked(this);
20056 }
20057
20058 /*!
20059 @brief access specified element via JSON Pointer
20060
20061 Returns a const reference to the element at with specified JSON pointer @a
20062 ptr, with bounds checking.
20063
20064 @param[in] ptr JSON pointer to the desired element
20065
20066 @return reference to the element pointed to by @a ptr
20067
20068 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
20069 begins with '0'. See example below.
20070
20071 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
20072 is not a number. See example below.
20073
20074 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
20075 is out of range. See example below.
20076
20077 @throw out_of_range.402 if the array index '-' is used in the passed JSON
20078 pointer @a ptr. As `at` provides checked access (and no elements are
20079 implicitly inserted), the index '-' is always invalid. See example below.
20080
20081 @throw out_of_range.403 if the JSON pointer describes a key of an object
20082 which cannot be found. See example below.
20083
20084 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
20085 See example below.
20086
20087 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20088 changes in the JSON value.
20089
20090 @complexity Constant.
20091
20092 @since version 2.0.0
20093
20094 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
20095 */
at(const json_pointer & ptr) const20096 const_reference at(const json_pointer& ptr) const
20097 {
20098 return ptr.get_checked(this);
20099 }
20100
20101 /*!
20102 @brief return flattened JSON value
20103
20104 The function creates a JSON object whose keys are JSON pointers (see [RFC
20105 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
20106 primitive. The original JSON value can be restored using the @ref
20107 unflatten() function.
20108
20109 @return an object that maps JSON pointers to primitive values
20110
20111 @note Empty objects and arrays are flattened to `null` and will not be
20112 reconstructed correctly by the @ref unflatten() function.
20113
20114 @complexity Linear in the size the JSON value.
20115
20116 @liveexample{The following code shows how a JSON object is flattened to an
20117 object whose keys consist of JSON pointers.,flatten}
20118
20119 @sa @ref unflatten() for the reverse function
20120
20121 @since version 2.0.0
20122 */
flatten() const20123 basic_json flatten() const
20124 {
20125 basic_json result(value_t::object);
20126 json_pointer::flatten("", *this, result);
20127 return result;
20128 }
20129
20130 /*!
20131 @brief unflatten a previously flattened JSON value
20132
20133 The function restores the arbitrary nesting of a JSON value that has been
20134 flattened before using the @ref flatten() function. The JSON value must
20135 meet certain constraints:
20136 1. The value must be an object.
20137 2. The keys must be JSON pointers (see
20138 [RFC 6901](https://tools.ietf.org/html/rfc6901))
20139 3. The mapped values must be primitive JSON types.
20140
20141 @return the original JSON from a flattened version
20142
20143 @note Empty objects and arrays are flattened by @ref flatten() to `null`
20144 values and can not unflattened to their original type. Apart from
20145 this example, for a JSON value `j`, the following is always true:
20146 `j == j.flatten().unflatten()`.
20147
20148 @complexity Linear in the size the JSON value.
20149
20150 @throw type_error.314 if value is not an object
20151 @throw type_error.315 if object values are not primitive
20152
20153 @liveexample{The following code shows how a flattened JSON object is
20154 unflattened into the original nested JSON object.,unflatten}
20155
20156 @sa @ref flatten() for the reverse function
20157
20158 @since version 2.0.0
20159 */
unflatten() const20160 basic_json unflatten() const
20161 {
20162 return json_pointer::unflatten(*this);
20163 }
20164
20165 /// @}
20166
20167 //////////////////////////
20168 // JSON Patch functions //
20169 //////////////////////////
20170
20171 /// @name JSON Patch functions
20172 /// @{
20173
20174 /*!
20175 @brief applies a JSON patch
20176
20177 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
20178 expressing a sequence of operations to apply to a JSON) document. With
20179 this function, a JSON Patch is applied to the current JSON value by
20180 executing all operations from the patch.
20181
20182 @param[in] json_patch JSON patch document
20183 @return patched document
20184
20185 @note The application of a patch is atomic: Either all operations succeed
20186 and the patched document is returned or an exception is thrown. In
20187 any case, the original value is not changed: the patch is applied
20188 to a copy of the value.
20189
20190 @throw parse_error.104 if the JSON patch does not consist of an array of
20191 objects
20192
20193 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
20194 attributes are missing); example: `"operation add must have member path"`
20195
20196 @throw out_of_range.401 if an array index is out of range.
20197
20198 @throw out_of_range.403 if a JSON pointer inside the patch could not be
20199 resolved successfully in the current JSON value; example: `"key baz not
20200 found"`
20201
20202 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
20203 "move")
20204
20205 @throw other_error.501 if "test" operation was unsuccessful
20206
20207 @complexity Linear in the size of the JSON value and the length of the
20208 JSON patch. As usually only a fraction of the JSON value is affected by
20209 the patch, the complexity can usually be neglected.
20210
20211 @liveexample{The following code shows how a JSON patch is applied to a
20212 value.,patch}
20213
20214 @sa @ref diff -- create a JSON patch by comparing two JSON values
20215
20216 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
20217 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
20218
20219 @since version 2.0.0
20220 */
patch(const basic_json & json_patch) const20221 basic_json patch(const basic_json& json_patch) const
20222 {
20223 // make a working copy to apply the patch to
20224 basic_json result = *this;
20225
20226 // the valid JSON Patch operations
20227 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
20228
20229 const auto get_op = [](const std::string & op)
20230 {
20231 if (op == "add")
20232 {
20233 return patch_operations::add;
20234 }
20235 if (op == "remove")
20236 {
20237 return patch_operations::remove;
20238 }
20239 if (op == "replace")
20240 {
20241 return patch_operations::replace;
20242 }
20243 if (op == "move")
20244 {
20245 return patch_operations::move;
20246 }
20247 if (op == "copy")
20248 {
20249 return patch_operations::copy;
20250 }
20251 if (op == "test")
20252 {
20253 return patch_operations::test;
20254 }
20255
20256 return patch_operations::invalid;
20257 };
20258
20259 // wrapper for "add" operation; add value at ptr
20260 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
20261 {
20262 // adding to the root of the target document means replacing it
20263 if (ptr.empty())
20264 {
20265 result = val;
20266 return;
20267 }
20268
20269 // make sure the top element of the pointer exists
20270 json_pointer top_pointer = ptr.top();
20271 if (top_pointer != ptr)
20272 {
20273 result.at(top_pointer);
20274 }
20275
20276 // get reference to parent of JSON pointer ptr
20277 const auto last_path = ptr.back();
20278 ptr.pop_back();
20279 basic_json& parent = result[ptr];
20280
20281 switch (parent.m_type)
20282 {
20283 case value_t::null:
20284 case value_t::object:
20285 {
20286 // use operator[] to add value
20287 parent[last_path] = val;
20288 break;
20289 }
20290
20291 case value_t::array:
20292 {
20293 if (last_path == "-")
20294 {
20295 // special case: append to back
20296 parent.push_back(val);
20297 }
20298 else
20299 {
20300 const auto idx = json_pointer::array_index(last_path);
20301 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
20302 {
20303 // avoid undefined behavior
20304 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20305 }
20306
20307 // default case: insert add offset
20308 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
20309 }
20310 break;
20311 }
20312
20313 // if there exists a parent it cannot be primitive
20314 default: // LCOV_EXCL_LINE
20315 assert(false); // LCOV_EXCL_LINE
20316 }
20317 };
20318
20319 // wrapper for "remove" operation; remove value at ptr
20320 const auto operation_remove = [&result](json_pointer & ptr)
20321 {
20322 // get reference to parent of JSON pointer ptr
20323 const auto last_path = ptr.back();
20324 ptr.pop_back();
20325 basic_json& parent = result.at(ptr);
20326
20327 // remove child
20328 if (parent.is_object())
20329 {
20330 // perform range check
20331 auto it = parent.find(last_path);
20332 if (JSON_LIKELY(it != parent.end()))
20333 {
20334 parent.erase(it);
20335 }
20336 else
20337 {
20338 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
20339 }
20340 }
20341 else if (parent.is_array())
20342 {
20343 // note erase performs range check
20344 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
20345 }
20346 };
20347
20348 // type check: top level value must be an array
20349 if (JSON_UNLIKELY(not json_patch.is_array()))
20350 {
20351 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
20352 }
20353
20354 // iterate and apply the operations
20355 for (const auto& val : json_patch)
20356 {
20357 // wrapper to get a value for an operation
20358 const auto get_value = [&val](const std::string & op,
20359 const std::string & member,
20360 bool string_type) -> basic_json &
20361 {
20362 // find value
20363 auto it = val.m_value.object->find(member);
20364
20365 // context-sensitive error message
20366 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
20367
20368 // check if desired value is present
20369 if (JSON_UNLIKELY(it == val.m_value.object->end()))
20370 {
20371 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
20372 }
20373
20374 // check if result is of type string
20375 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
20376 {
20377 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
20378 }
20379
20380 // no error: return value
20381 return it->second;
20382 };
20383
20384 // type check: every element of the array must be an object
20385 if (JSON_UNLIKELY(not val.is_object()))
20386 {
20387 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
20388 }
20389
20390 // collect mandatory members
20391 const std::string op = get_value("op", "op", true);
20392 const std::string path = get_value(op, "path", true);
20393 json_pointer ptr(path);
20394
20395 switch (get_op(op))
20396 {
20397 case patch_operations::add:
20398 {
20399 operation_add(ptr, get_value("add", "value", false));
20400 break;
20401 }
20402
20403 case patch_operations::remove:
20404 {
20405 operation_remove(ptr);
20406 break;
20407 }
20408
20409 case patch_operations::replace:
20410 {
20411 // the "path" location must exist - use at()
20412 result.at(ptr) = get_value("replace", "value", false);
20413 break;
20414 }
20415
20416 case patch_operations::move:
20417 {
20418 const std::string from_path = get_value("move", "from", true);
20419 json_pointer from_ptr(from_path);
20420
20421 // the "from" location must exist - use at()
20422 basic_json v = result.at(from_ptr);
20423
20424 // The move operation is functionally identical to a
20425 // "remove" operation on the "from" location, followed
20426 // immediately by an "add" operation at the target
20427 // location with the value that was just removed.
20428 operation_remove(from_ptr);
20429 operation_add(ptr, v);
20430 break;
20431 }
20432
20433 case patch_operations::copy:
20434 {
20435 const std::string from_path = get_value("copy", "from", true);
20436 const json_pointer from_ptr(from_path);
20437
20438 // the "from" location must exist - use at()
20439 basic_json v = result.at(from_ptr);
20440
20441 // The copy is functionally identical to an "add"
20442 // operation at the target location using the value
20443 // specified in the "from" member.
20444 operation_add(ptr, v);
20445 break;
20446 }
20447
20448 case patch_operations::test:
20449 {
20450 bool success = false;
20451 JSON_TRY
20452 {
20453 // check if "value" matches the one at "path"
20454 // the "path" location must exist - use at()
20455 success = (result.at(ptr) == get_value("test", "value", false));
20456 }
20457 JSON_INTERNAL_CATCH (out_of_range&)
20458 {
20459 // ignore out of range errors: success remains false
20460 }
20461
20462 // throw an exception if test fails
20463 if (JSON_UNLIKELY(not success))
20464 {
20465 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
20466 }
20467
20468 break;
20469 }
20470
20471 default:
20472 {
20473 // op must be "add", "remove", "replace", "move", "copy", or
20474 // "test"
20475 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
20476 }
20477 }
20478 }
20479
20480 return result;
20481 }
20482
20483 /*!
20484 @brief creates a diff as a JSON patch
20485
20486 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
20487 be changed into the value @a target by calling @ref patch function.
20488
20489 @invariant For two JSON values @a source and @a target, the following code
20490 yields always `true`:
20491 @code {.cpp}
20492 source.patch(diff(source, target)) == target;
20493 @endcode
20494
20495 @note Currently, only `remove`, `add`, and `replace` operations are
20496 generated.
20497
20498 @param[in] source JSON value to compare from
20499 @param[in] target JSON value to compare against
20500 @param[in] path helper value to create JSON pointers
20501
20502 @return a JSON patch to convert the @a source to @a target
20503
20504 @complexity Linear in the lengths of @a source and @a target.
20505
20506 @liveexample{The following code shows how a JSON patch is created as a
20507 diff for two JSON values.,diff}
20508
20509 @sa @ref patch -- apply a JSON patch
20510 @sa @ref merge_patch -- apply a JSON Merge Patch
20511
20512 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
20513
20514 @since version 2.0.0
20515 */
20516 JSON_NODISCARD
diff(const basic_json & source,const basic_json & target,const std::string & path="")20517 static basic_json diff(const basic_json& source, const basic_json& target,
20518 const std::string& path = "")
20519 {
20520 // the patch
20521 basic_json result(value_t::array);
20522
20523 // if the values are the same, return empty patch
20524 if (source == target)
20525 {
20526 return result;
20527 }
20528
20529 if (source.type() != target.type())
20530 {
20531 // different types: replace value
20532 result.push_back(
20533 {
20534 {"op", "replace"}, {"path", path}, {"value", target}
20535 });
20536 return result;
20537 }
20538
20539 switch (source.type())
20540 {
20541 case value_t::array:
20542 {
20543 // first pass: traverse common elements
20544 std::size_t i = 0;
20545 while (i < source.size() and i < target.size())
20546 {
20547 // recursive call to compare array values at index i
20548 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
20549 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20550 ++i;
20551 }
20552
20553 // i now reached the end of at least one array
20554 // in a second pass, traverse the remaining elements
20555
20556 // remove my remaining elements
20557 const auto end_index = static_cast<difference_type>(result.size());
20558 while (i < source.size())
20559 {
20560 // add operations in reverse order to avoid invalid
20561 // indices
20562 result.insert(result.begin() + end_index, object(
20563 {
20564 {"op", "remove"},
20565 {"path", path + "/" + std::to_string(i)}
20566 }));
20567 ++i;
20568 }
20569
20570 // add other remaining elements
20571 while (i < target.size())
20572 {
20573 result.push_back(
20574 {
20575 {"op", "add"},
20576 {"path", path + "/" + std::to_string(i)},
20577 {"value", target[i]}
20578 });
20579 ++i;
20580 }
20581
20582 break;
20583 }
20584
20585 case value_t::object:
20586 {
20587 // first pass: traverse this object's elements
20588 for (auto it = source.cbegin(); it != source.cend(); ++it)
20589 {
20590 // escape the key name to be used in a JSON patch
20591 const auto key = json_pointer::escape(it.key());
20592
20593 if (target.find(it.key()) != target.end())
20594 {
20595 // recursive call to compare object values at key it
20596 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
20597 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20598 }
20599 else
20600 {
20601 // found a key that is not in o -> remove it
20602 result.push_back(object(
20603 {
20604 {"op", "remove"}, {"path", path + "/" + key}
20605 }));
20606 }
20607 }
20608
20609 // second pass: traverse other object's elements
20610 for (auto it = target.cbegin(); it != target.cend(); ++it)
20611 {
20612 if (source.find(it.key()) == source.end())
20613 {
20614 // found a key that is not in this -> add it
20615 const auto key = json_pointer::escape(it.key());
20616 result.push_back(
20617 {
20618 {"op", "add"}, {"path", path + "/" + key},
20619 {"value", it.value()}
20620 });
20621 }
20622 }
20623
20624 break;
20625 }
20626
20627 default:
20628 {
20629 // both primitive type: replace value
20630 result.push_back(
20631 {
20632 {"op", "replace"}, {"path", path}, {"value", target}
20633 });
20634 break;
20635 }
20636 }
20637
20638 return result;
20639 }
20640
20641 /// @}
20642
20643 ////////////////////////////////
20644 // JSON Merge Patch functions //
20645 ////////////////////////////////
20646
20647 /// @name JSON Merge Patch functions
20648 /// @{
20649
20650 /*!
20651 @brief applies a JSON Merge Patch
20652
20653 The merge patch format is primarily intended for use with the HTTP PATCH
20654 method as a means of describing a set of modifications to a target
20655 resource's content. This function applies a merge patch to the current
20656 JSON value.
20657
20658 The function implements the following algorithm from Section 2 of
20659 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
20660
20661 ```
20662 define MergePatch(Target, Patch):
20663 if Patch is an Object:
20664 if Target is not an Object:
20665 Target = {} // Ignore the contents and set it to an empty Object
20666 for each Name/Value pair in Patch:
20667 if Value is null:
20668 if Name exists in Target:
20669 remove the Name/Value pair from Target
20670 else:
20671 Target[Name] = MergePatch(Target[Name], Value)
20672 return Target
20673 else:
20674 return Patch
20675 ```
20676
20677 Thereby, `Target` is the current object; that is, the patch is applied to
20678 the current value.
20679
20680 @param[in] apply_patch the patch to apply
20681
20682 @complexity Linear in the lengths of @a patch.
20683
20684 @liveexample{The following code shows how a JSON Merge Patch is applied to
20685 a JSON document.,merge_patch}
20686
20687 @sa @ref patch -- apply a JSON patch
20688 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
20689
20690 @since version 3.0.0
20691 */
merge_patch(const basic_json & apply_patch)20692 void merge_patch(const basic_json& apply_patch)
20693 {
20694 if (apply_patch.is_object())
20695 {
20696 if (not is_object())
20697 {
20698 *this = object();
20699 }
20700 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
20701 {
20702 if (it.value().is_null())
20703 {
20704 erase(it.key());
20705 }
20706 else
20707 {
20708 operator[](it.key()).merge_patch(it.value());
20709 }
20710 }
20711 }
20712 else
20713 {
20714 *this = apply_patch;
20715 }
20716 }
20717
20718 /// @}
20719 };
20720 } // namespace nlohmann
20721
20722 ///////////////////////
20723 // nonmember support //
20724 ///////////////////////
20725
20726 // specialization of std::swap, and std::hash
20727 namespace std
20728 {
20729
20730 /// hash value for JSON objects
20731 template<>
20732 struct hash<nlohmann::json>
20733 {
20734 /*!
20735 @brief return a hash value for a JSON object
20736
20737 @since version 1.0.0
20738 */
operator ()std::hash20739 std::size_t operator()(const nlohmann::json& j) const
20740 {
20741 // a naive hashing via the string representation
20742 const auto& h = hash<nlohmann::json::string_t>();
20743 return h(j.dump());
20744 }
20745 };
20746
20747 /// specialization for std::less<value_t>
20748 /// @note: do not remove the space after '<',
20749 /// see https://github.com/nlohmann/json/pull/679
20750 template<>
20751 struct less< ::nlohmann::detail::value_t>
20752 {
20753 /*!
20754 @brief compare two value_t enum values
20755 @since version 3.0.0
20756 */
operator ()std::less20757 bool operator()(nlohmann::detail::value_t lhs,
20758 nlohmann::detail::value_t rhs) const noexcept
20759 {
20760 return nlohmann::detail::operator<(lhs, rhs);
20761 }
20762 };
20763
20764 /*!
20765 @brief exchanges the values of two JSON objects
20766
20767 @since version 1.0.0
20768 */
20769 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)20770 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
20771 is_nothrow_move_constructible<nlohmann::json>::value and
20772 is_nothrow_move_assignable<nlohmann::json>::value
20773 )
20774 {
20775 j1.swap(j2);
20776 }
20777
20778 } // namespace std
20779
20780 /*!
20781 @brief user-defined string literal for JSON values
20782
20783 This operator implements a user-defined string literal for JSON objects. It
20784 can be used by adding `"_json"` to a string literal and returns a JSON object
20785 if no parse error occurred.
20786
20787 @param[in] s a string representation of a JSON object
20788 @param[in] n the length of string @a s
20789 @return a JSON object
20790
20791 @since version 1.0.0
20792 */
operator ""_json(const char * s,std::size_t n)20793 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
20794 {
20795 return nlohmann::json::parse(s, s + n);
20796 }
20797
20798 /*!
20799 @brief user-defined string literal for JSON pointer
20800
20801 This operator implements a user-defined string literal for JSON Pointers. It
20802 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
20803 object if no parse error occurred.
20804
20805 @param[in] s a string representation of a JSON Pointer
20806 @param[in] n the length of string @a s
20807 @return a JSON pointer object
20808
20809 @since version 2.0.0
20810 */
operator ""_json_pointer(const char * s,std::size_t n)20811 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
20812 {
20813 return nlohmann::json::json_pointer(std::string(s, n));
20814 }
20815
20816 // #include <nlohmann/detail/macro_unscope.hpp>
20817
20818
20819 // restore GCC/clang diagnostic settings
20820 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
20821 #pragma GCC diagnostic pop
20822 #endif
20823 #if defined(__clang__)
20824 #pragma GCC diagnostic pop
20825 #endif
20826
20827 // clean up
20828 #undef JSON_INTERNAL_CATCH
20829 #undef JSON_CATCH
20830 #undef JSON_THROW
20831 #undef JSON_TRY
20832 #undef JSON_LIKELY
20833 #undef JSON_UNLIKELY
20834 #undef JSON_DEPRECATED
20835 #undef JSON_NODISCARD
20836 #undef JSON_HAS_CPP_14
20837 #undef JSON_HAS_CPP_17
20838 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
20839 #undef NLOHMANN_BASIC_JSON_TPL
20840
20841
20842 #endif // INCLUDE_NLOHMANN_JSON_HPP_
20843