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 // C++ language standard detection
473 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
474 #define JSON_HAS_CPP_17
475 #define JSON_HAS_CPP_14
476 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
477 #define JSON_HAS_CPP_14
478 #endif
479
480 // disable float-equal warnings on GCC/clang
481 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
482 #pragma GCC diagnostic push
483 #pragma GCC diagnostic ignored "-Wfloat-equal"
484 #endif
485
486 // disable documentation warnings on clang
487 #if defined(__clang__)
488 #pragma GCC diagnostic push
489 #pragma GCC diagnostic ignored "-Wdocumentation"
490 #endif
491
492 // allow for portable deprecation warnings
493 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
494 #define JSON_DEPRECATED __attribute__((deprecated))
495 #elif defined(_MSC_VER)
496 #define JSON_DEPRECATED __declspec(deprecated)
497 #else
498 #define JSON_DEPRECATED
499 #endif
500
501 // allow for portable nodiscard warnings
502 #if defined(__has_cpp_attribute)
503 #if __has_cpp_attribute(nodiscard)
504 #if defined(__clang__) && !defined(JSON_HAS_CPP_17) // issue #1535
505 #define JSON_NODISCARD
506 #else
507 #define JSON_NODISCARD [[nodiscard]]
508 #endif
509 #elif __has_cpp_attribute(gnu::warn_unused_result)
510 #define JSON_NODISCARD [[gnu::warn_unused_result]]
511 #else
512 #define JSON_NODISCARD
513 #endif
514 #else
515 #define JSON_NODISCARD
516 #endif
517
518 // allow to disable exceptions
519 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
520 #define JSON_THROW(exception) throw exception
521 #define JSON_TRY try
522 #define JSON_CATCH(exception) catch(exception)
523 #define JSON_INTERNAL_CATCH(exception) catch(exception)
524 #else
525 #include <cstdlib>
526 #define JSON_THROW(exception) std::abort()
527 #define JSON_TRY if(true)
528 #define JSON_CATCH(exception) if(false)
529 #define JSON_INTERNAL_CATCH(exception) if(false)
530 #endif
531
532 // override exception macros
533 #if defined(JSON_THROW_USER)
534 #undef JSON_THROW
535 #define JSON_THROW JSON_THROW_USER
536 #endif
537 #if defined(JSON_TRY_USER)
538 #undef JSON_TRY
539 #define JSON_TRY JSON_TRY_USER
540 #endif
541 #if defined(JSON_CATCH_USER)
542 #undef JSON_CATCH
543 #define JSON_CATCH JSON_CATCH_USER
544 #undef JSON_INTERNAL_CATCH
545 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
546 #endif
547 #if defined(JSON_INTERNAL_CATCH_USER)
548 #undef JSON_INTERNAL_CATCH
549 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
550 #endif
551
552 // manual branch prediction
553 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
554 #define JSON_LIKELY(x) __builtin_expect(x, 1)
555 #define JSON_UNLIKELY(x) __builtin_expect(x, 0)
556 #else
557 #define JSON_LIKELY(x) x
558 #define JSON_UNLIKELY(x) x
559 #endif
560
561 /*!
562 @brief macro to briefly define a mapping between an enum and JSON
563 @def NLOHMANN_JSON_SERIALIZE_ENUM
564 @since version 3.4.0
565 */
566 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
567 template<typename BasicJsonType> \
568 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
569 { \
570 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
571 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
572 auto it = std::find_if(std::begin(m), std::end(m), \
573 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
574 { \
575 return ej_pair.first == e; \
576 }); \
577 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
578 } \
579 template<typename BasicJsonType> \
580 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
581 { \
582 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
583 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
584 auto it = std::find_if(std::begin(m), std::end(m), \
585 [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
586 { \
587 return ej_pair.second == j; \
588 }); \
589 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
590 }
591
592 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
593 // may be removed in the future once the class is split.
594
595 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
596 template<template<typename, typename, typename...> class ObjectType, \
597 template<typename, typename...> class ArrayType, \
598 class StringType, class BooleanType, class NumberIntegerType, \
599 class NumberUnsignedType, class NumberFloatType, \
600 template<typename> class AllocatorType, \
601 template<typename, typename = void> class JSONSerializer>
602
603 #define NLOHMANN_BASIC_JSON_TPL \
604 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
605 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
606 AllocatorType, JSONSerializer>
607
608 // #include <nlohmann/detail/meta/cpp_future.hpp>
609
610
611 #include <ciso646> // not
612 #include <cstddef> // size_t
613 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
614
615 namespace nlohmann
616 {
617 namespace detail
618 {
619 // alias templates to reduce boilerplate
620 template<bool B, typename T = void>
621 using enable_if_t = typename std::enable_if<B, T>::type;
622
623 template<typename T>
624 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
625
626 // implementation of C++14 index_sequence and affiliates
627 // source: https://stackoverflow.com/a/32223343
628 template<std::size_t... Ints>
629 struct index_sequence
630 {
631 using type = index_sequence;
632 using value_type = std::size_t;
sizenlohmann::detail::index_sequence633 static constexpr std::size_t size() noexcept
634 {
635 return sizeof...(Ints);
636 }
637 };
638
639 template<class Sequence1, class Sequence2>
640 struct merge_and_renumber;
641
642 template<std::size_t... I1, std::size_t... I2>
643 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
644 : index_sequence < I1..., (sizeof...(I1) + I2)... > {};
645
646 template<std::size_t N>
647 struct make_index_sequence
648 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
649 typename make_index_sequence < N - N / 2 >::type > {};
650
651 template<> struct make_index_sequence<0> : index_sequence<> {};
652 template<> struct make_index_sequence<1> : index_sequence<0> {};
653
654 template<typename... Ts>
655 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
656
657 // dispatch utility (taken from ranges-v3)
658 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
659 template<> struct priority_tag<0> {};
660
661 // taken from ranges-v3
662 template<typename T>
663 struct static_const
664 {
665 static constexpr T value{};
666 };
667
668 template<typename T>
669 constexpr T static_const<T>::value;
670 } // namespace detail
671 } // namespace nlohmann
672
673 // #include <nlohmann/detail/meta/type_traits.hpp>
674
675
676 #include <ciso646> // not
677 #include <limits> // numeric_limits
678 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
679 #include <utility> // declval
680
681 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
682
683
684 #include <iterator> // random_access_iterator_tag
685
686 // #include <nlohmann/detail/meta/void_t.hpp>
687
688
689 namespace nlohmann
690 {
691 namespace detail
692 {
693 template <typename ...Ts> struct make_void
694 {
695 using type = void;
696 };
697 template <typename ...Ts> using void_t = typename make_void<Ts...>::type;
698 } // namespace detail
699 } // namespace nlohmann
700
701 // #include <nlohmann/detail/meta/cpp_future.hpp>
702
703
704 namespace nlohmann
705 {
706 namespace detail
707 {
708 template <typename It, typename = void>
709 struct iterator_types {};
710
711 template <typename It>
712 struct iterator_types <
713 It,
714 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
715 typename It::reference, typename It::iterator_category >>
716 {
717 using difference_type = typename It::difference_type;
718 using value_type = typename It::value_type;
719 using pointer = typename It::pointer;
720 using reference = typename It::reference;
721 using iterator_category = typename It::iterator_category;
722 };
723
724 // This is required as some compilers implement std::iterator_traits in a way that
725 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
726 template <typename T, typename = void>
727 struct iterator_traits
728 {
729 };
730
731 template <typename T>
732 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
733 : iterator_types<T>
734 {
735 };
736
737 template <typename T>
738 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
739 {
740 using iterator_category = std::random_access_iterator_tag;
741 using value_type = T;
742 using difference_type = ptrdiff_t;
743 using pointer = T*;
744 using reference = T&;
745 };
746 } // namespace detail
747 } // namespace nlohmann
748
749 // #include <nlohmann/detail/macro_scope.hpp>
750
751 // #include <nlohmann/detail/meta/cpp_future.hpp>
752
753 // #include <nlohmann/detail/meta/detected.hpp>
754
755
756 #include <type_traits>
757
758 // #include <nlohmann/detail/meta/void_t.hpp>
759
760
761 // http://en.cppreference.com/w/cpp/experimental/is_detected
762 namespace nlohmann
763 {
764 namespace detail
765 {
766 struct nonesuch
767 {
768 nonesuch() = delete;
769 ~nonesuch() = delete;
770 nonesuch(nonesuch const&) = delete;
771 nonesuch(nonesuch const&&) = delete;
772 void operator=(nonesuch const&) = delete;
773 void operator=(nonesuch&&) = delete;
774 };
775
776 template <class Default,
777 class AlwaysVoid,
778 template <class...> class Op,
779 class... Args>
780 struct detector
781 {
782 using value_t = std::false_type;
783 using type = Default;
784 };
785
786 template <class Default, template <class...> class Op, class... Args>
787 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
788 {
789 using value_t = std::true_type;
790 using type = Op<Args...>;
791 };
792
793 template <template <class...> class Op, class... Args>
794 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
795
796 template <template <class...> class Op, class... Args>
797 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
798
799 template <class Default, template <class...> class Op, class... Args>
800 using detected_or = detector<Default, void, Op, Args...>;
801
802 template <class Default, template <class...> class Op, class... Args>
803 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
804
805 template <class Expected, template <class...> class Op, class... Args>
806 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
807
808 template <class To, template <class...> class Op, class... Args>
809 using is_detected_convertible =
810 std::is_convertible<detected_t<Op, Args...>, To>;
811 } // namespace detail
812 } // namespace nlohmann
813
814 // #include <nlohmann/json_fwd.hpp>
815 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
816 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
817
818 #include <cstdint> // int64_t, uint64_t
819 #include <map> // map
820 #include <memory> // allocator
821 #include <string> // string
822 #include <vector> // vector
823
824 /*!
825 @brief namespace for Niels Lohmann
826 @see https://github.com/nlohmann
827 @since version 1.0.0
828 */
829 namespace nlohmann
830 {
831 /*!
832 @brief default JSONSerializer template argument
833
834 This serializer ignores the template arguments and uses ADL
835 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
836 for serialization.
837 */
838 template<typename T = void, typename SFINAE = void>
839 struct adl_serializer;
840
841 template<template<typename U, typename V, typename... Args> class ObjectType =
842 std::map,
843 template<typename U, typename... Args> class ArrayType = std::vector,
844 class StringType = std::string, class BooleanType = bool,
845 class NumberIntegerType = std::int64_t,
846 class NumberUnsignedType = std::uint64_t,
847 class NumberFloatType = double,
848 template<typename U> class AllocatorType = std::allocator,
849 template<typename T, typename SFINAE = void> class JSONSerializer =
850 adl_serializer>
851 class basic_json;
852
853 /*!
854 @brief JSON Pointer
855
856 A JSON pointer defines a string syntax for identifying a specific value
857 within a JSON document. It can be used with functions `at` and
858 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
859
860 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
861
862 @since version 2.0.0
863 */
864 template<typename BasicJsonType>
865 class json_pointer;
866
867 /*!
868 @brief default JSON class
869
870 This type is the default specialization of the @ref basic_json class which
871 uses the standard template types.
872
873 @since version 1.0.0
874 */
875 using json = basic_json<>;
876 } // namespace nlohmann
877
878 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
879
880
881 namespace nlohmann
882 {
883 /*!
884 @brief detail namespace with internal helper functions
885
886 This namespace collects functions that should not be exposed,
887 implementations of some @ref basic_json methods, and meta-programming helpers.
888
889 @since version 2.1.0
890 */
891 namespace detail
892 {
893 /////////////
894 // helpers //
895 /////////////
896
897 // Note to maintainers:
898 //
899 // Every trait in this file expects a non CV-qualified type.
900 // The only exceptions are in the 'aliases for detected' section
901 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
902 //
903 // In this case, T has to be properly CV-qualified to constraint the function arguments
904 // (e.g. to_json(BasicJsonType&, const T&))
905
906 template<typename> struct is_basic_json : std::false_type {};
907
908 NLOHMANN_BASIC_JSON_TPL_DECLARATION
909 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
910
911 //////////////////////////
912 // aliases for detected //
913 //////////////////////////
914
915 template <typename T>
916 using mapped_type_t = typename T::mapped_type;
917
918 template <typename T>
919 using key_type_t = typename T::key_type;
920
921 template <typename T>
922 using value_type_t = typename T::value_type;
923
924 template <typename T>
925 using difference_type_t = typename T::difference_type;
926
927 template <typename T>
928 using pointer_t = typename T::pointer;
929
930 template <typename T>
931 using reference_t = typename T::reference;
932
933 template <typename T>
934 using iterator_category_t = typename T::iterator_category;
935
936 template <typename T>
937 using iterator_t = typename T::iterator;
938
939 template <typename T, typename... Args>
940 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
941
942 template <typename T, typename... Args>
943 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
944
945 template <typename T, typename U>
946 using get_template_function = decltype(std::declval<T>().template get<U>());
947
948 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
949 template <typename BasicJsonType, typename T, typename = void>
950 struct has_from_json : std::false_type {};
951
952 template <typename BasicJsonType, typename T>
953 struct has_from_json<BasicJsonType, T,
954 enable_if_t<not is_basic_json<T>::value>>
955 {
956 using serializer = typename BasicJsonType::template json_serializer<T, void>;
957
958 static constexpr bool value =
959 is_detected_exact<void, from_json_function, serializer,
960 const BasicJsonType&, T&>::value;
961 };
962
963 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
964 // this overload is used for non-default-constructible user-defined-types
965 template <typename BasicJsonType, typename T, typename = void>
966 struct has_non_default_from_json : std::false_type {};
967
968 template<typename BasicJsonType, typename T>
969 struct has_non_default_from_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
970 {
971 using serializer = typename BasicJsonType::template json_serializer<T, void>;
972
973 static constexpr bool value =
974 is_detected_exact<T, from_json_function, serializer,
975 const BasicJsonType&>::value;
976 };
977
978 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
979 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
980 template <typename BasicJsonType, typename T, typename = void>
981 struct has_to_json : std::false_type {};
982
983 template <typename BasicJsonType, typename T>
984 struct has_to_json<BasicJsonType, T, enable_if_t<not is_basic_json<T>::value>>
985 {
986 using serializer = typename BasicJsonType::template json_serializer<T, void>;
987
988 static constexpr bool value =
989 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
990 T>::value;
991 };
992
993
994 ///////////////////
995 // is_ functions //
996 ///////////////////
997
998 template <typename T, typename = void>
999 struct is_iterator_traits : std::false_type {};
1000
1001 template <typename T>
1002 struct is_iterator_traits<iterator_traits<T>>
1003 {
1004 private:
1005 using traits = iterator_traits<T>;
1006
1007 public:
1008 static constexpr auto value =
1009 is_detected<value_type_t, traits>::value &&
1010 is_detected<difference_type_t, traits>::value &&
1011 is_detected<pointer_t, traits>::value &&
1012 is_detected<iterator_category_t, traits>::value &&
1013 is_detected<reference_t, traits>::value;
1014 };
1015
1016 // source: https://stackoverflow.com/a/37193089/4116453
1017
1018 template <typename T, typename = void>
1019 struct is_complete_type : std::false_type {};
1020
1021 template <typename T>
1022 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
1023
1024 template <typename BasicJsonType, typename CompatibleObjectType,
1025 typename = void>
1026 struct is_compatible_object_type_impl : std::false_type {};
1027
1028 template <typename BasicJsonType, typename CompatibleObjectType>
1029 struct is_compatible_object_type_impl <
1030 BasicJsonType, CompatibleObjectType,
1031 enable_if_t<is_detected<mapped_type_t, CompatibleObjectType>::value and
1032 is_detected<key_type_t, CompatibleObjectType>::value >>
1033 {
1034
1035 using object_t = typename BasicJsonType::object_t;
1036
1037 // macOS's is_constructible does not play well with nonesuch...
1038 static constexpr bool value =
1039 std::is_constructible<typename object_t::key_type,
1040 typename CompatibleObjectType::key_type>::value and
1041 std::is_constructible<typename object_t::mapped_type,
1042 typename CompatibleObjectType::mapped_type>::value;
1043 };
1044
1045 template <typename BasicJsonType, typename CompatibleObjectType>
1046 struct is_compatible_object_type
1047 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
1048
1049 template <typename BasicJsonType, typename ConstructibleObjectType,
1050 typename = void>
1051 struct is_constructible_object_type_impl : std::false_type {};
1052
1053 template <typename BasicJsonType, typename ConstructibleObjectType>
1054 struct is_constructible_object_type_impl <
1055 BasicJsonType, ConstructibleObjectType,
1056 enable_if_t<is_detected<mapped_type_t, ConstructibleObjectType>::value and
1057 is_detected<key_type_t, ConstructibleObjectType>::value >>
1058 {
1059 using object_t = typename BasicJsonType::object_t;
1060
1061 static constexpr bool value =
1062 (std::is_default_constructible<ConstructibleObjectType>::value and
1063 (std::is_move_assignable<ConstructibleObjectType>::value or
1064 std::is_copy_assignable<ConstructibleObjectType>::value) and
1065 (std::is_constructible<typename ConstructibleObjectType::key_type,
1066 typename object_t::key_type>::value and
1067 std::is_same <
1068 typename object_t::mapped_type,
1069 typename ConstructibleObjectType::mapped_type >::value)) or
1070 (has_from_json<BasicJsonType,
1071 typename ConstructibleObjectType::mapped_type>::value or
1072 has_non_default_from_json <
1073 BasicJsonType,
1074 typename ConstructibleObjectType::mapped_type >::value);
1075 };
1076
1077 template <typename BasicJsonType, typename ConstructibleObjectType>
1078 struct is_constructible_object_type
1079 : is_constructible_object_type_impl<BasicJsonType,
1080 ConstructibleObjectType> {};
1081
1082 template <typename BasicJsonType, typename CompatibleStringType,
1083 typename = void>
1084 struct is_compatible_string_type_impl : std::false_type {};
1085
1086 template <typename BasicJsonType, typename CompatibleStringType>
1087 struct is_compatible_string_type_impl <
1088 BasicJsonType, CompatibleStringType,
1089 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
1090 value_type_t, CompatibleStringType>::value >>
1091 {
1092 static constexpr auto value =
1093 std::is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
1094 };
1095
1096 template <typename BasicJsonType, typename ConstructibleStringType>
1097 struct is_compatible_string_type
1098 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1099
1100 template <typename BasicJsonType, typename ConstructibleStringType,
1101 typename = void>
1102 struct is_constructible_string_type_impl : std::false_type {};
1103
1104 template <typename BasicJsonType, typename ConstructibleStringType>
1105 struct is_constructible_string_type_impl <
1106 BasicJsonType, ConstructibleStringType,
1107 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
1108 value_type_t, ConstructibleStringType>::value >>
1109 {
1110 static constexpr auto value =
1111 std::is_constructible<ConstructibleStringType,
1112 typename BasicJsonType::string_t>::value;
1113 };
1114
1115 template <typename BasicJsonType, typename ConstructibleStringType>
1116 struct is_constructible_string_type
1117 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
1118
1119 template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
1120 struct is_compatible_array_type_impl : std::false_type {};
1121
1122 template <typename BasicJsonType, typename CompatibleArrayType>
1123 struct is_compatible_array_type_impl <
1124 BasicJsonType, CompatibleArrayType,
1125 enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
1126 is_detected<iterator_t, CompatibleArrayType>::value and
1127 // This is needed because json_reverse_iterator has a ::iterator type...
1128 // Therefore it is detected as a CompatibleArrayType.
1129 // The real fix would be to have an Iterable concept.
1130 not is_iterator_traits<
1131 iterator_traits<CompatibleArrayType>>::value >>
1132 {
1133 static constexpr bool value =
1134 std::is_constructible<BasicJsonType,
1135 typename CompatibleArrayType::value_type>::value;
1136 };
1137
1138 template <typename BasicJsonType, typename CompatibleArrayType>
1139 struct is_compatible_array_type
1140 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
1141
1142 template <typename BasicJsonType, typename ConstructibleArrayType, typename = void>
1143 struct is_constructible_array_type_impl : std::false_type {};
1144
1145 template <typename BasicJsonType, typename ConstructibleArrayType>
1146 struct is_constructible_array_type_impl <
1147 BasicJsonType, ConstructibleArrayType,
1148 enable_if_t<std::is_same<ConstructibleArrayType,
1149 typename BasicJsonType::value_type>::value >>
1150 : std::true_type {};
1151
1152 template <typename BasicJsonType, typename ConstructibleArrayType>
1153 struct is_constructible_array_type_impl <
1154 BasicJsonType, ConstructibleArrayType,
1155 enable_if_t<not std::is_same<ConstructibleArrayType,
1156 typename BasicJsonType::value_type>::value and
1157 std::is_default_constructible<ConstructibleArrayType>::value and
1158 (std::is_move_assignable<ConstructibleArrayType>::value or
1159 std::is_copy_assignable<ConstructibleArrayType>::value) and
1160 is_detected<value_type_t, ConstructibleArrayType>::value and
1161 is_detected<iterator_t, ConstructibleArrayType>::value and
1162 is_complete_type<
1163 detected_t<value_type_t, ConstructibleArrayType>>::value >>
1164 {
1165 static constexpr bool value =
1166 // This is needed because json_reverse_iterator has a ::iterator type,
1167 // furthermore, std::back_insert_iterator (and other iterators) have a
1168 // base class `iterator`... Therefore it is detected as a
1169 // ConstructibleArrayType. The real fix would be to have an Iterable
1170 // concept.
1171 not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
1172
1173 (std::is_same<typename ConstructibleArrayType::value_type,
1174 typename BasicJsonType::array_t::value_type>::value or
1175 has_from_json<BasicJsonType,
1176 typename ConstructibleArrayType::value_type>::value or
1177 has_non_default_from_json <
1178 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
1179 };
1180
1181 template <typename BasicJsonType, typename ConstructibleArrayType>
1182 struct is_constructible_array_type
1183 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
1184
1185 template <typename RealIntegerType, typename CompatibleNumberIntegerType,
1186 typename = void>
1187 struct is_compatible_integer_type_impl : std::false_type {};
1188
1189 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
1190 struct is_compatible_integer_type_impl <
1191 RealIntegerType, CompatibleNumberIntegerType,
1192 enable_if_t<std::is_integral<RealIntegerType>::value and
1193 std::is_integral<CompatibleNumberIntegerType>::value and
1194 not std::is_same<bool, CompatibleNumberIntegerType>::value >>
1195 {
1196 // is there an assert somewhere on overflows?
1197 using RealLimits = std::numeric_limits<RealIntegerType>;
1198 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
1199
1200 static constexpr auto value =
1201 std::is_constructible<RealIntegerType,
1202 CompatibleNumberIntegerType>::value and
1203 CompatibleLimits::is_integer and
1204 RealLimits::is_signed == CompatibleLimits::is_signed;
1205 };
1206
1207 template <typename RealIntegerType, typename CompatibleNumberIntegerType>
1208 struct is_compatible_integer_type
1209 : is_compatible_integer_type_impl<RealIntegerType,
1210 CompatibleNumberIntegerType> {};
1211
1212 template <typename BasicJsonType, typename CompatibleType, typename = void>
1213 struct is_compatible_type_impl: std::false_type {};
1214
1215 template <typename BasicJsonType, typename CompatibleType>
1216 struct is_compatible_type_impl <
1217 BasicJsonType, CompatibleType,
1218 enable_if_t<is_complete_type<CompatibleType>::value >>
1219 {
1220 static constexpr bool value =
1221 has_to_json<BasicJsonType, CompatibleType>::value;
1222 };
1223
1224 template <typename BasicJsonType, typename CompatibleType>
1225 struct is_compatible_type
1226 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
1227 } // namespace detail
1228 } // namespace nlohmann
1229
1230 // #include <nlohmann/detail/value_t.hpp>
1231
1232
1233 #include <array> // array
1234 #include <ciso646> // and
1235 #include <cstddef> // size_t
1236 #include <cstdint> // uint8_t
1237 #include <string> // string
1238
1239 namespace nlohmann
1240 {
1241 namespace detail
1242 {
1243 ///////////////////////////
1244 // JSON type enumeration //
1245 ///////////////////////////
1246
1247 /*!
1248 @brief the JSON type enumeration
1249
1250 This enumeration collects the different JSON types. It is internally used to
1251 distinguish the stored values, and the functions @ref basic_json::is_null(),
1252 @ref basic_json::is_object(), @ref basic_json::is_array(),
1253 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
1254 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
1255 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
1256 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
1257 @ref basic_json::is_structured() rely on it.
1258
1259 @note There are three enumeration entries (number_integer, number_unsigned, and
1260 number_float), because the library distinguishes these three types for numbers:
1261 @ref basic_json::number_unsigned_t is used for unsigned integers,
1262 @ref basic_json::number_integer_t is used for signed integers, and
1263 @ref basic_json::number_float_t is used for floating-point numbers or to
1264 approximate integers which do not fit in the limits of their respective type.
1265
1266 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
1267 value with the default value for a given type
1268
1269 @since version 1.0.0
1270 */
1271 enum class value_t : std::uint8_t
1272 {
1273 null, ///< null value
1274 object, ///< object (unordered set of name/value pairs)
1275 array, ///< array (ordered collection of values)
1276 string, ///< string value
1277 boolean, ///< boolean value
1278 number_integer, ///< number value (signed integer)
1279 number_unsigned, ///< number value (unsigned integer)
1280 number_float, ///< number value (floating-point)
1281 discarded ///< discarded by the the parser callback function
1282 };
1283
1284 /*!
1285 @brief comparison operator for JSON types
1286
1287 Returns an ordering that is similar to Python:
1288 - order: null < boolean < number < object < array < string
1289 - furthermore, each type is not smaller than itself
1290 - discarded values are not comparable
1291
1292 @since version 1.0.0
1293 */
operator <(const value_t lhs,const value_t rhs)1294 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
1295 {
1296 static constexpr std::array<std::uint8_t, 8> order = {{
1297 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
1298 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */
1299 }
1300 };
1301
1302 const auto l_index = static_cast<std::size_t>(lhs);
1303 const auto r_index = static_cast<std::size_t>(rhs);
1304 return l_index < order.size() and r_index < order.size() and order[l_index] < order[r_index];
1305 }
1306 } // namespace detail
1307 } // namespace nlohmann
1308
1309
1310 namespace nlohmann
1311 {
1312 namespace detail
1313 {
1314 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)1315 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
1316 {
1317 if (JSON_UNLIKELY(not j.is_null()))
1318 {
1319 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name())));
1320 }
1321 n = nullptr;
1322 }
1323
1324 // overloads for basic_json template parameters
1325 template<typename BasicJsonType, typename ArithmeticType,
1326 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1327 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1328 int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1329 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1330 {
1331 switch (static_cast<value_t>(j))
1332 {
1333 case value_t::number_unsigned:
1334 {
1335 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1336 break;
1337 }
1338 case value_t::number_integer:
1339 {
1340 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1341 break;
1342 }
1343 case value_t::number_float:
1344 {
1345 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1346 break;
1347 }
1348
1349 default:
1350 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1351 }
1352 }
1353
1354 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1355 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1356 {
1357 if (JSON_UNLIKELY(not j.is_boolean()))
1358 {
1359 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1360 }
1361 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1362 }
1363
1364 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1365 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1366 {
1367 if (JSON_UNLIKELY(not j.is_string()))
1368 {
1369 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1370 }
1371 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1372 }
1373
1374 template <
1375 typename BasicJsonType, typename ConstructibleStringType,
1376 enable_if_t <
1377 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
1378 not std::is_same<typename BasicJsonType::string_t,
1379 ConstructibleStringType>::value,
1380 int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)1381 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
1382 {
1383 if (JSON_UNLIKELY(not j.is_string()))
1384 {
1385 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1386 }
1387
1388 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1389 }
1390
1391 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1392 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1393 {
1394 get_arithmetic_value(j, val);
1395 }
1396
1397 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1398 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1399 {
1400 get_arithmetic_value(j, val);
1401 }
1402
1403 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1404 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1405 {
1406 get_arithmetic_value(j, val);
1407 }
1408
1409 template<typename BasicJsonType, typename EnumType,
1410 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1411 void from_json(const BasicJsonType& j, EnumType& e)
1412 {
1413 typename std::underlying_type<EnumType>::type val;
1414 get_arithmetic_value(j, val);
1415 e = static_cast<EnumType>(val);
1416 }
1417
1418 // forward_list doesn't have an insert method
1419 template<typename BasicJsonType, typename T, typename Allocator,
1420 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1421 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1422 {
1423 if (JSON_UNLIKELY(not j.is_array()))
1424 {
1425 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1426 }
1427 l.clear();
1428 std::transform(j.rbegin(), j.rend(),
1429 std::front_inserter(l), [](const BasicJsonType & i)
1430 {
1431 return i.template get<T>();
1432 });
1433 }
1434
1435 // valarray doesn't have an insert method
1436 template<typename BasicJsonType, typename T,
1437 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1438 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1439 {
1440 if (JSON_UNLIKELY(not j.is_array()))
1441 {
1442 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1443 }
1444 l.resize(j.size());
1445 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1446 }
1447
1448 template <typename BasicJsonType, typename T, std::size_t N>
from_json(const BasicJsonType & j,T (& arr)[N])1449 auto from_json(const BasicJsonType& j, T (&arr)[N])
1450 -> decltype(j.template get<T>(), void())
1451 {
1452 for (std::size_t i = 0; i < N; ++i)
1453 {
1454 arr[i] = j.at(i).template get<T>();
1455 }
1456 }
1457
1458 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)1459 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
1460 {
1461 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1462 }
1463
1464 template <typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1465 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
1466 priority_tag<2> /*unused*/)
1467 -> decltype(j.template get<T>(), void())
1468 {
1469 for (std::size_t i = 0; i < N; ++i)
1470 {
1471 arr[i] = j.at(i).template get<T>();
1472 }
1473 }
1474
1475 template<typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)1476 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
1477 -> decltype(
1478 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
1479 j.template get<typename ConstructibleArrayType::value_type>(),
1480 void())
1481 {
1482 using std::end;
1483
1484 ConstructibleArrayType ret;
1485 ret.reserve(j.size());
1486 std::transform(j.begin(), j.end(),
1487 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
1488 {
1489 // get<BasicJsonType>() returns *this, this won't call a from_json
1490 // method when value_type is BasicJsonType
1491 return i.template get<typename ConstructibleArrayType::value_type>();
1492 });
1493 arr = std::move(ret);
1494 }
1495
1496 template <typename BasicJsonType, typename ConstructibleArrayType>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)1497 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
1498 priority_tag<0> /*unused*/)
1499 {
1500 using std::end;
1501
1502 ConstructibleArrayType ret;
1503 std::transform(
1504 j.begin(), j.end(), std::inserter(ret, end(ret)),
1505 [](const BasicJsonType & i)
1506 {
1507 // get<BasicJsonType>() returns *this, this won't call a from_json
1508 // method when value_type is BasicJsonType
1509 return i.template get<typename ConstructibleArrayType::value_type>();
1510 });
1511 arr = std::move(ret);
1512 }
1513
1514 template <typename BasicJsonType, typename ConstructibleArrayType,
1515 enable_if_t <
1516 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
1517 not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
1518 not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
1519 not is_basic_json<ConstructibleArrayType>::value,
1520 int > = 0 >
1521
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)1522 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
1523 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
1524 j.template get<typename ConstructibleArrayType::value_type>(),
1525 void())
1526 {
1527 if (JSON_UNLIKELY(not j.is_array()))
1528 {
1529 JSON_THROW(type_error::create(302, "type must be array, but is " +
1530 std::string(j.type_name())));
1531 }
1532
1533 from_json_array_impl(j, arr, priority_tag<3> {});
1534 }
1535
1536 template<typename BasicJsonType, typename ConstructibleObjectType,
1537 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)1538 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
1539 {
1540 if (JSON_UNLIKELY(not j.is_object()))
1541 {
1542 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1543 }
1544
1545 ConstructibleObjectType ret;
1546 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1547 using value_type = typename ConstructibleObjectType::value_type;
1548 std::transform(
1549 inner_object->begin(), inner_object->end(),
1550 std::inserter(ret, ret.begin()),
1551 [](typename BasicJsonType::object_t::value_type const & p)
1552 {
1553 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
1554 });
1555 obj = std::move(ret);
1556 }
1557
1558 // overload for arithmetic types, not chosen for basic_json template arguments
1559 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1560 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1561 // an arithmetic type?
1562 template<typename BasicJsonType, typename ArithmeticType,
1563 enable_if_t <
1564 std::is_arithmetic<ArithmeticType>::value and
1565 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1566 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1567 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1568 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1569 int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1570 void from_json(const BasicJsonType& j, ArithmeticType& val)
1571 {
1572 switch (static_cast<value_t>(j))
1573 {
1574 case value_t::number_unsigned:
1575 {
1576 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1577 break;
1578 }
1579 case value_t::number_integer:
1580 {
1581 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1582 break;
1583 }
1584 case value_t::number_float:
1585 {
1586 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1587 break;
1588 }
1589 case value_t::boolean:
1590 {
1591 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1592 break;
1593 }
1594
1595 default:
1596 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1597 }
1598 }
1599
1600 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1601 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1602 {
1603 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1604 }
1605
1606 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1607 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...> /*unused*/)
1608 {
1609 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1610 }
1611
1612 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1613 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1614 {
1615 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1616 }
1617
1618 template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
1619 typename = enable_if_t<not std::is_constructible<
1620 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)1621 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
1622 {
1623 if (JSON_UNLIKELY(not j.is_array()))
1624 {
1625 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1626 }
1627 m.clear();
1628 for (const auto& p : j)
1629 {
1630 if (JSON_UNLIKELY(not p.is_array()))
1631 {
1632 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1633 }
1634 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1635 }
1636 }
1637
1638 template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
1639 typename = enable_if_t<not std::is_constructible<
1640 typename BasicJsonType::string_t, Key>::value>>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)1641 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
1642 {
1643 if (JSON_UNLIKELY(not j.is_array()))
1644 {
1645 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1646 }
1647 m.clear();
1648 for (const auto& p : j)
1649 {
1650 if (JSON_UNLIKELY(not p.is_array()))
1651 {
1652 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name())));
1653 }
1654 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
1655 }
1656 }
1657
1658 struct from_json_fn
1659 {
1660 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1661 auto operator()(const BasicJsonType& j, T& val) const
1662 noexcept(noexcept(from_json(j, val)))
1663 -> decltype(from_json(j, val), void())
1664 {
1665 return from_json(j, val);
1666 }
1667 };
1668 } // namespace detail
1669
1670 /// namespace to hold default `from_json` function
1671 /// to see why this is required:
1672 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
1673 namespace
1674 {
1675 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
1676 } // namespace
1677 } // namespace nlohmann
1678
1679 // #include <nlohmann/detail/conversions/to_json.hpp>
1680
1681
1682 #include <algorithm> // copy
1683 #include <ciso646> // or, and, not
1684 #include <iterator> // begin, end
1685 #include <string> // string
1686 #include <tuple> // tuple, get
1687 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
1688 #include <utility> // move, forward, declval, pair
1689 #include <valarray> // valarray
1690 #include <vector> // vector
1691
1692 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
1693
1694
1695 #include <cstddef> // size_t
1696 #include <iterator> // input_iterator_tag
1697 #include <string> // string, to_string
1698 #include <tuple> // tuple_size, get, tuple_element
1699
1700 // #include <nlohmann/detail/meta/type_traits.hpp>
1701
1702 // #include <nlohmann/detail/value_t.hpp>
1703
1704
1705 namespace nlohmann
1706 {
1707 namespace detail
1708 {
1709 template <typename IteratorType> class iteration_proxy_value
1710 {
1711 public:
1712 using difference_type = std::ptrdiff_t;
1713 using value_type = iteration_proxy_value;
1714 using pointer = value_type * ;
1715 using reference = value_type & ;
1716 using iterator_category = std::input_iterator_tag;
1717
1718 private:
1719 /// the iterator
1720 IteratorType anchor;
1721 /// an index for arrays (used to create key names)
1722 std::size_t array_index = 0;
1723 /// last stringified array index
1724 mutable std::size_t array_index_last = 0;
1725 /// a string representation of the array index
1726 mutable std::string array_index_str = "0";
1727 /// an empty string (to return a reference for primitive values)
1728 const std::string empty_str = "";
1729
1730 public:
iteration_proxy_value(IteratorType it)1731 explicit iteration_proxy_value(IteratorType it) noexcept : anchor(it) {}
1732
1733 /// dereference operator (needed for range-based for)
operator *()1734 iteration_proxy_value& operator*()
1735 {
1736 return *this;
1737 }
1738
1739 /// increment operator (needed for range-based for)
operator ++()1740 iteration_proxy_value& operator++()
1741 {
1742 ++anchor;
1743 ++array_index;
1744
1745 return *this;
1746 }
1747
1748 /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const1749 bool operator==(const iteration_proxy_value& o) const
1750 {
1751 return anchor == o.anchor;
1752 }
1753
1754 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const1755 bool operator!=(const iteration_proxy_value& o) const
1756 {
1757 return anchor != o.anchor;
1758 }
1759
1760 /// return key of the iterator
key() const1761 const std::string& key() const
1762 {
1763 assert(anchor.m_object != nullptr);
1764
1765 switch (anchor.m_object->type())
1766 {
1767 // use integer array index as key
1768 case value_t::array:
1769 {
1770 if (array_index != array_index_last)
1771 {
1772 array_index_str = std::to_string(array_index);
1773 array_index_last = array_index;
1774 }
1775 return array_index_str;
1776 }
1777
1778 // use key from the object
1779 case value_t::object:
1780 return anchor.key();
1781
1782 // use an empty key for all primitive types
1783 default:
1784 return empty_str;
1785 }
1786 }
1787
1788 /// return value of the iterator
value() const1789 typename IteratorType::reference value() const
1790 {
1791 return anchor.value();
1792 }
1793 };
1794
1795 /// proxy class for the items() function
1796 template<typename IteratorType> class iteration_proxy
1797 {
1798 private:
1799 /// the container to iterate
1800 typename IteratorType::reference container;
1801
1802 public:
1803 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)1804 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
1805 : container(cont) {}
1806
1807 /// return iterator begin (needed for range-based for)
begin()1808 iteration_proxy_value<IteratorType> begin() noexcept
1809 {
1810 return iteration_proxy_value<IteratorType>(container.begin());
1811 }
1812
1813 /// return iterator end (needed for range-based for)
end()1814 iteration_proxy_value<IteratorType> end() noexcept
1815 {
1816 return iteration_proxy_value<IteratorType>(container.end());
1817 }
1818 };
1819 // Structured Bindings Support
1820 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1821 // And see https://github.com/nlohmann/json/pull/1391
1822 template <std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)1823 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
1824 {
1825 return i.key();
1826 }
1827 // Structured Bindings Support
1828 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1829 // And see https://github.com/nlohmann/json/pull/1391
1830 template <std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)1831 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
1832 {
1833 return i.value();
1834 }
1835 } // namespace detail
1836 } // namespace nlohmann
1837
1838 // The Addition to the STD Namespace is required to add
1839 // Structured Bindings Support to the iteration_proxy_value class
1840 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
1841 // And see https://github.com/nlohmann/json/pull/1391
1842 namespace std
1843 {
1844 #if defined(__clang__)
1845 // Fix: https://github.com/nlohmann/json/issues/1401
1846 #pragma clang diagnostic push
1847 #pragma clang diagnostic ignored "-Wmismatched-tags"
1848 #endif
1849 template <typename IteratorType>
1850 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
1851 : public std::integral_constant<std::size_t, 2> {};
1852
1853 template <std::size_t N, typename IteratorType>
1854 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
1855 {
1856 public:
1857 using type = decltype(
1858 get<N>(std::declval <
1859 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
1860 };
1861 #if defined(__clang__)
1862 #pragma clang diagnostic pop
1863 #endif
1864 } // namespace std
1865
1866 // #include <nlohmann/detail/meta/cpp_future.hpp>
1867
1868 // #include <nlohmann/detail/meta/type_traits.hpp>
1869
1870 // #include <nlohmann/detail/value_t.hpp>
1871
1872
1873 namespace nlohmann
1874 {
1875 namespace detail
1876 {
1877 //////////////////
1878 // constructors //
1879 //////////////////
1880
1881 template<value_t> struct external_constructor;
1882
1883 template<>
1884 struct external_constructor<value_t::boolean>
1885 {
1886 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1887 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
1888 {
1889 j.m_type = value_t::boolean;
1890 j.m_value = b;
1891 j.assert_invariant();
1892 }
1893 };
1894
1895 template<>
1896 struct external_constructor<value_t::string>
1897 {
1898 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1899 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
1900 {
1901 j.m_type = value_t::string;
1902 j.m_value = s;
1903 j.assert_invariant();
1904 }
1905
1906 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1907 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
1908 {
1909 j.m_type = value_t::string;
1910 j.m_value = std::move(s);
1911 j.assert_invariant();
1912 }
1913
1914 template<typename BasicJsonType, typename CompatibleStringType,
1915 enable_if_t<not std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
1916 int> = 0>
constructnlohmann::detail::external_constructor1917 static void construct(BasicJsonType& j, const CompatibleStringType& str)
1918 {
1919 j.m_type = value_t::string;
1920 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
1921 j.assert_invariant();
1922 }
1923 };
1924
1925 template<>
1926 struct external_constructor<value_t::number_float>
1927 {
1928 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1929 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
1930 {
1931 j.m_type = value_t::number_float;
1932 j.m_value = val;
1933 j.assert_invariant();
1934 }
1935 };
1936
1937 template<>
1938 struct external_constructor<value_t::number_unsigned>
1939 {
1940 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1941 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
1942 {
1943 j.m_type = value_t::number_unsigned;
1944 j.m_value = val;
1945 j.assert_invariant();
1946 }
1947 };
1948
1949 template<>
1950 struct external_constructor<value_t::number_integer>
1951 {
1952 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1953 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
1954 {
1955 j.m_type = value_t::number_integer;
1956 j.m_value = val;
1957 j.assert_invariant();
1958 }
1959 };
1960
1961 template<>
1962 struct external_constructor<value_t::array>
1963 {
1964 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1965 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
1966 {
1967 j.m_type = value_t::array;
1968 j.m_value = arr;
1969 j.assert_invariant();
1970 }
1971
1972 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1973 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1974 {
1975 j.m_type = value_t::array;
1976 j.m_value = std::move(arr);
1977 j.assert_invariant();
1978 }
1979
1980 template<typename BasicJsonType, typename CompatibleArrayType,
1981 enable_if_t<not std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
1982 int> = 0>
constructnlohmann::detail::external_constructor1983 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
1984 {
1985 using std::begin;
1986 using std::end;
1987 j.m_type = value_t::array;
1988 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
1989 j.assert_invariant();
1990 }
1991
1992 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor1993 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
1994 {
1995 j.m_type = value_t::array;
1996 j.m_value = value_t::array;
1997 j.m_value.array->reserve(arr.size());
1998 for (const bool x : arr)
1999 {
2000 j.m_value.array->push_back(x);
2001 }
2002 j.assert_invariant();
2003 }
2004
2005 template<typename BasicJsonType, typename T,
2006 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor2007 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
2008 {
2009 j.m_type = value_t::array;
2010 j.m_value = value_t::array;
2011 j.m_value.array->resize(arr.size());
2012 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
2013 j.assert_invariant();
2014 }
2015 };
2016
2017 template<>
2018 struct external_constructor<value_t::object>
2019 {
2020 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor2021 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
2022 {
2023 j.m_type = value_t::object;
2024 j.m_value = obj;
2025 j.assert_invariant();
2026 }
2027
2028 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor2029 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
2030 {
2031 j.m_type = value_t::object;
2032 j.m_value = std::move(obj);
2033 j.assert_invariant();
2034 }
2035
2036 template<typename BasicJsonType, typename CompatibleObjectType,
2037 enable_if_t<not std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor2038 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
2039 {
2040 using std::begin;
2041 using std::end;
2042
2043 j.m_type = value_t::object;
2044 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
2045 j.assert_invariant();
2046 }
2047 };
2048
2049 /////////////
2050 // to_json //
2051 /////////////
2052
2053 template<typename BasicJsonType, typename T,
2054 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)2055 void to_json(BasicJsonType& j, T b) noexcept
2056 {
2057 external_constructor<value_t::boolean>::construct(j, b);
2058 }
2059
2060 template<typename BasicJsonType, typename CompatibleString,
2061 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)2062 void to_json(BasicJsonType& j, const CompatibleString& s)
2063 {
2064 external_constructor<value_t::string>::construct(j, s);
2065 }
2066
2067 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)2068 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
2069 {
2070 external_constructor<value_t::string>::construct(j, std::move(s));
2071 }
2072
2073 template<typename BasicJsonType, typename FloatType,
2074 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)2075 void to_json(BasicJsonType& j, FloatType val) noexcept
2076 {
2077 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
2078 }
2079
2080 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
2081 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)2082 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
2083 {
2084 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
2085 }
2086
2087 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
2088 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)2089 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
2090 {
2091 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
2092 }
2093
2094 template<typename BasicJsonType, typename EnumType,
2095 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)2096 void to_json(BasicJsonType& j, EnumType e) noexcept
2097 {
2098 using underlying_type = typename std::underlying_type<EnumType>::type;
2099 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
2100 }
2101
2102 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)2103 void to_json(BasicJsonType& j, const std::vector<bool>& e)
2104 {
2105 external_constructor<value_t::array>::construct(j, e);
2106 }
2107
2108 template <typename BasicJsonType, typename CompatibleArrayType,
2109 enable_if_t<is_compatible_array_type<BasicJsonType,
2110 CompatibleArrayType>::value and
2111 not is_compatible_object_type<
2112 BasicJsonType, CompatibleArrayType>::value and
2113 not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
2114 not is_basic_json<CompatibleArrayType>::value,
2115 int> = 0>
to_json(BasicJsonType & j,const CompatibleArrayType & arr)2116 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
2117 {
2118 external_constructor<value_t::array>::construct(j, arr);
2119 }
2120
2121 template<typename BasicJsonType, typename T,
2122 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)2123 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
2124 {
2125 external_constructor<value_t::array>::construct(j, std::move(arr));
2126 }
2127
2128 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)2129 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
2130 {
2131 external_constructor<value_t::array>::construct(j, std::move(arr));
2132 }
2133
2134 template<typename BasicJsonType, typename CompatibleObjectType,
2135 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)2136 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
2137 {
2138 external_constructor<value_t::object>::construct(j, obj);
2139 }
2140
2141 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)2142 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
2143 {
2144 external_constructor<value_t::object>::construct(j, std::move(obj));
2145 }
2146
2147 template <
2148 typename BasicJsonType, typename T, std::size_t N,
2149 enable_if_t<not std::is_constructible<typename BasicJsonType::string_t,
2150 const T(&)[N]>::value,
2151 int> = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])2152 void to_json(BasicJsonType& j, const T(&arr)[N])
2153 {
2154 external_constructor<value_t::array>::construct(j, arr);
2155 }
2156
2157 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)2158 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
2159 {
2160 j = { p.first, p.second };
2161 }
2162
2163 // for https://github.com/nlohmann/json/pull/1134
2164 template < typename BasicJsonType, typename T,
2165 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)2166 void to_json(BasicJsonType& j, const T& b)
2167 {
2168 j = { {b.key(), b.value()} };
2169 }
2170
2171 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)2172 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
2173 {
2174 j = { std::get<Idx>(t)... };
2175 }
2176
2177 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)2178 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
2179 {
2180 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
2181 }
2182
2183 struct to_json_fn
2184 {
2185 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn2186 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
2187 -> decltype(to_json(j, std::forward<T>(val)), void())
2188 {
2189 return to_json(j, std::forward<T>(val));
2190 }
2191 };
2192 } // namespace detail
2193
2194 /// namespace to hold default `to_json` function
2195 namespace
2196 {
2197 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
2198 } // namespace
2199 } // namespace nlohmann
2200
2201
2202 namespace nlohmann
2203 {
2204
2205 template<typename, typename>
2206 struct adl_serializer
2207 {
2208 /*!
2209 @brief convert a JSON value to any value type
2210
2211 This function is usually called by the `get()` function of the
2212 @ref basic_json class (either explicit or via conversion operators).
2213
2214 @param[in] j JSON value to read from
2215 @param[in,out] val value to write to
2216 */
2217 template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer2218 static auto from_json(BasicJsonType&& j, ValueType& val) noexcept(
2219 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
2220 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
2221 {
2222 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
2223 }
2224
2225 /*!
2226 @brief convert any value type to a JSON value
2227
2228 This function is usually called by the constructors of the @ref basic_json
2229 class.
2230
2231 @param[in,out] j JSON value to write to
2232 @param[in] val value to read from
2233 */
2234 template <typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer2235 static auto to_json(BasicJsonType& j, ValueType&& val) noexcept(
2236 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
2237 -> decltype(::nlohmann::to_json(j, std::forward<ValueType>(val)), void())
2238 {
2239 ::nlohmann::to_json(j, std::forward<ValueType>(val));
2240 }
2241 };
2242
2243 } // namespace nlohmann
2244
2245 // #include <nlohmann/detail/conversions/from_json.hpp>
2246
2247 // #include <nlohmann/detail/conversions/to_json.hpp>
2248
2249 // #include <nlohmann/detail/exceptions.hpp>
2250
2251 // #include <nlohmann/detail/input/binary_reader.hpp>
2252
2253
2254 #include <algorithm> // generate_n
2255 #include <array> // array
2256 #include <cassert> // assert
2257 #include <cmath> // ldexp
2258 #include <cstddef> // size_t
2259 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
2260 #include <cstdio> // snprintf
2261 #include <cstring> // memcpy
2262 #include <iterator> // back_inserter
2263 #include <limits> // numeric_limits
2264 #include <string> // char_traits, string
2265 #include <utility> // make_pair, move
2266
2267 // #include <nlohmann/detail/exceptions.hpp>
2268
2269 // #include <nlohmann/detail/input/input_adapters.hpp>
2270
2271
2272 #include <array> // array
2273 #include <cassert> // assert
2274 #include <cstddef> // size_t
2275 #include <cstdio> //FILE *
2276 #include <cstring> // strlen
2277 #include <istream> // istream
2278 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
2279 #include <memory> // shared_ptr, make_shared, addressof
2280 #include <numeric> // accumulate
2281 #include <string> // string, char_traits
2282 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
2283 #include <utility> // pair, declval
2284
2285 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
2286
2287 // #include <nlohmann/detail/macro_scope.hpp>
2288
2289 //ABELL
2290 #undef snprintf
2291
2292 namespace nlohmann
2293 {
2294 namespace detail
2295 {
2296 /// the supported input formats
2297 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
2298
2299 ////////////////////
2300 // input adapters //
2301 ////////////////////
2302
2303 /*!
2304 @brief abstract input adapter interface
2305
2306 Produces a stream of std::char_traits<char>::int_type characters from a
2307 std::istream, a buffer, or some other input type. Accepts the return of
2308 exactly one non-EOF character for future input. The int_type characters
2309 returned consist of all valid char values as positive values (typically
2310 unsigned char), plus an EOF value outside that range, specified by the value
2311 of the function std::char_traits<char>::eof(). This value is typically -1, but
2312 could be any arbitrary value which is not a valid char value.
2313 */
2314 struct input_adapter_protocol
2315 {
2316 /// get a character [0,255] or std::char_traits<char>::eof().
2317 virtual std::char_traits<char>::int_type get_character() = 0;
2318 virtual ~input_adapter_protocol() = default;
2319 };
2320
2321 /// a type to simplify interfaces
2322 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
2323
2324 /*!
2325 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
2326 buffer. This adapter is a very low level adapter.
2327 */
2328 class file_input_adapter : public input_adapter_protocol
2329 {
2330 public:
file_input_adapter(std::FILE * f)2331 explicit file_input_adapter(std::FILE* f) noexcept
2332 : m_file(f)
2333 {}
2334
2335 // make class move-only
2336 file_input_adapter(const file_input_adapter&) = delete;
2337 file_input_adapter(file_input_adapter&&) = default;
2338 file_input_adapter& operator=(const file_input_adapter&) = delete;
2339 file_input_adapter& operator=(file_input_adapter&&) = default;
2340 ~file_input_adapter() override = default;
2341
get_character()2342 std::char_traits<char>::int_type get_character() noexcept override
2343 {
2344 return std::fgetc(m_file);
2345 }
2346
2347 private:
2348 /// the file pointer to read from
2349 std::FILE* m_file;
2350 };
2351
2352
2353 /*!
2354 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
2355 beginning of input. Does not support changing the underlying std::streambuf
2356 in mid-input. Maintains underlying std::istream and std::streambuf to support
2357 subsequent use of standard std::istream operations to process any input
2358 characters following those used in parsing the JSON input. Clears the
2359 std::istream flags; any input errors (e.g., EOF) will be detected by the first
2360 subsequent call for input from the std::istream.
2361 */
2362 class input_stream_adapter : public input_adapter_protocol
2363 {
2364 public:
~input_stream_adapter()2365 ~input_stream_adapter() override
2366 {
2367 // clear stream flags; we use underlying streambuf I/O, do not
2368 // maintain ifstream flags, except eof
2369 is.clear(is.rdstate() & std::ios::eofbit);
2370 }
2371
input_stream_adapter(std::istream & i)2372 explicit input_stream_adapter(std::istream& i)
2373 : is(i), sb(*i.rdbuf())
2374 {}
2375
2376 // delete because of pointer members
2377 input_stream_adapter(const input_stream_adapter&) = delete;
2378 input_stream_adapter& operator=(input_stream_adapter&) = delete;
2379 input_stream_adapter(input_stream_adapter&&) = delete;
2380 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
2381
2382 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
2383 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
2384 // end up as the same value, eg. 0xFFFFFFFF.
get_character()2385 std::char_traits<char>::int_type get_character() override
2386 {
2387 auto res = sb.sbumpc();
2388 // set eof manually, as we don't use the istream interface.
2389 if (res == EOF)
2390 {
2391 is.clear(is.rdstate() | std::ios::eofbit);
2392 }
2393 return res;
2394 }
2395
2396 private:
2397 /// the associated input stream
2398 std::istream& is;
2399 std::streambuf& sb;
2400 };
2401
2402 /// input adapter for buffer input
2403 class input_buffer_adapter : public input_adapter_protocol
2404 {
2405 public:
input_buffer_adapter(const char * b,const std::size_t l)2406 input_buffer_adapter(const char* b, const std::size_t l) noexcept
2407 : cursor(b), limit(b + l)
2408 {}
2409
2410 // delete because of pointer members
2411 input_buffer_adapter(const input_buffer_adapter&) = delete;
2412 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
2413 input_buffer_adapter(input_buffer_adapter&&) = delete;
2414 input_buffer_adapter& operator=(input_buffer_adapter&&) = delete;
2415 ~input_buffer_adapter() override = default;
2416
get_character()2417 std::char_traits<char>::int_type get_character() noexcept override
2418 {
2419 if (JSON_LIKELY(cursor < limit))
2420 {
2421 return std::char_traits<char>::to_int_type(*(cursor++));
2422 }
2423
2424 return std::char_traits<char>::eof();
2425 }
2426
2427 private:
2428 /// pointer to the current character
2429 const char* cursor;
2430 /// pointer past the last character
2431 const char* const limit;
2432 };
2433
2434 template<typename WideStringType, size_t T>
2435 struct wide_string_input_helper
2436 {
2437 // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper2438 static void fill_buffer(const WideStringType& str,
2439 size_t& current_wchar,
2440 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2441 size_t& utf8_bytes_index,
2442 size_t& utf8_bytes_filled)
2443 {
2444 utf8_bytes_index = 0;
2445
2446 if (current_wchar == str.size())
2447 {
2448 utf8_bytes[0] = std::char_traits<char>::eof();
2449 utf8_bytes_filled = 1;
2450 }
2451 else
2452 {
2453 // get the current character
2454 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2455
2456 // UTF-32 to UTF-8 encoding
2457 if (wc < 0x80)
2458 {
2459 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2460 utf8_bytes_filled = 1;
2461 }
2462 else if (wc <= 0x7FF)
2463 {
2464 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u) & 0x1Fu));
2465 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2466 utf8_bytes_filled = 2;
2467 }
2468 else if (wc <= 0xFFFF)
2469 {
2470 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u) & 0x0Fu));
2471 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2472 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2473 utf8_bytes_filled = 3;
2474 }
2475 else if (wc <= 0x10FFFF)
2476 {
2477 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((wc >> 18u) & 0x07u));
2478 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 12u) & 0x3Fu));
2479 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2480 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2481 utf8_bytes_filled = 4;
2482 }
2483 else
2484 {
2485 // unknown character
2486 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2487 utf8_bytes_filled = 1;
2488 }
2489 }
2490 }
2491 };
2492
2493 template<typename WideStringType>
2494 struct wide_string_input_helper<WideStringType, 2>
2495 {
2496 // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper2497 static void fill_buffer(const WideStringType& str,
2498 size_t& current_wchar,
2499 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
2500 size_t& utf8_bytes_index,
2501 size_t& utf8_bytes_filled)
2502 {
2503 utf8_bytes_index = 0;
2504
2505 if (current_wchar == str.size())
2506 {
2507 utf8_bytes[0] = std::char_traits<char>::eof();
2508 utf8_bytes_filled = 1;
2509 }
2510 else
2511 {
2512 // get the current character
2513 const auto wc = static_cast<unsigned int>(str[current_wchar++]);
2514
2515 // UTF-16 to UTF-8 encoding
2516 if (wc < 0x80)
2517 {
2518 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2519 utf8_bytes_filled = 1;
2520 }
2521 else if (wc <= 0x7FF)
2522 {
2523 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((wc >> 6u)));
2524 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2525 utf8_bytes_filled = 2;
2526 }
2527 else if (0xD800 > wc or wc >= 0xE000)
2528 {
2529 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((wc >> 12u)));
2530 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((wc >> 6u) & 0x3Fu));
2531 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (wc & 0x3Fu));
2532 utf8_bytes_filled = 3;
2533 }
2534 else
2535 {
2536 if (current_wchar < str.size())
2537 {
2538 const auto wc2 = static_cast<unsigned int>(str[current_wchar++]);
2539 const auto charcode = 0x10000u + (((wc & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
2540 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
2541 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
2542 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
2543 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
2544 utf8_bytes_filled = 4;
2545 }
2546 else
2547 {
2548 // unknown character
2549 ++current_wchar;
2550 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
2551 utf8_bytes_filled = 1;
2552 }
2553 }
2554 }
2555 }
2556 };
2557
2558 template<typename WideStringType>
2559 class wide_string_input_adapter : public input_adapter_protocol
2560 {
2561 public:
wide_string_input_adapter(const WideStringType & w)2562 explicit wide_string_input_adapter(const WideStringType& w) noexcept
2563 : str(w)
2564 {}
2565
get_character()2566 std::char_traits<char>::int_type get_character() noexcept override
2567 {
2568 // check if buffer needs to be filled
2569 if (utf8_bytes_index == utf8_bytes_filled)
2570 {
2571 fill_buffer<sizeof(typename WideStringType::value_type)>();
2572
2573 assert(utf8_bytes_filled > 0);
2574 assert(utf8_bytes_index == 0);
2575 }
2576
2577 // use buffer
2578 assert(utf8_bytes_filled > 0);
2579 assert(utf8_bytes_index < utf8_bytes_filled);
2580 return utf8_bytes[utf8_bytes_index++];
2581 }
2582
2583 private:
2584 template<size_t T>
fill_buffer()2585 void fill_buffer()
2586 {
2587 wide_string_input_helper<WideStringType, T>::fill_buffer(str, current_wchar, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
2588 }
2589
2590 /// the wstring to process
2591 const WideStringType& str;
2592
2593 /// index of the current wchar in str
2594 std::size_t current_wchar = 0;
2595
2596 /// a buffer for UTF-8 bytes
2597 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
2598
2599 /// index to the utf8_codes array for the next valid byte
2600 std::size_t utf8_bytes_index = 0;
2601 /// number of valid bytes in the utf8_codes array
2602 std::size_t utf8_bytes_filled = 0;
2603 };
2604
2605 class input_adapter
2606 {
2607 public:
2608 // native support
input_adapter(std::FILE * file)2609 input_adapter(std::FILE* file)
2610 : ia(std::make_shared<file_input_adapter>(file)) {}
2611 /// input adapter for input stream
input_adapter(std::istream & i)2612 input_adapter(std::istream& i)
2613 : ia(std::make_shared<input_stream_adapter>(i)) {}
2614
2615 /// input adapter for input stream
input_adapter(std::istream && i)2616 input_adapter(std::istream&& i)
2617 : ia(std::make_shared<input_stream_adapter>(i)) {}
2618
input_adapter(const std::wstring & ws)2619 input_adapter(const std::wstring& ws)
2620 : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {}
2621
input_adapter(const std::u16string & ws)2622 input_adapter(const std::u16string& ws)
2623 : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {}
2624
input_adapter(const std::u32string & ws)2625 input_adapter(const std::u32string& ws)
2626 : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {}
2627
2628 /// input adapter for buffer
2629 template<typename CharT,
2630 typename std::enable_if<
2631 std::is_pointer<CharT>::value and
2632 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2633 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2634 int>::type = 0>
input_adapter(CharT b,std::size_t l)2635 input_adapter(CharT b, std::size_t l)
2636 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
2637
2638 // derived support
2639
2640 /// input adapter for string literal
2641 template<typename CharT,
2642 typename std::enable_if<
2643 std::is_pointer<CharT>::value and
2644 std::is_integral<typename std::remove_pointer<CharT>::type>::value and
2645 sizeof(typename std::remove_pointer<CharT>::type) == 1,
2646 int>::type = 0>
input_adapter(CharT b)2647 input_adapter(CharT b)
2648 : input_adapter(reinterpret_cast<const char*>(b),
2649 std::strlen(reinterpret_cast<const char*>(b))) {}
2650
2651 /// input adapter for iterator range with contiguous storage
2652 template<class IteratorType,
2653 typename std::enable_if<
2654 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
2655 int>::type = 0>
input_adapter(IteratorType first,IteratorType last)2656 input_adapter(IteratorType first, IteratorType last)
2657 {
2658 #ifndef NDEBUG
2659 // assertion to check that the iterator range is indeed contiguous,
2660 // see http://stackoverflow.com/a/35008842/266378 for more discussion
2661 const auto is_contiguous = std::accumulate(
2662 first, last, std::pair<bool, int>(true, 0),
2663 [&first](std::pair<bool, int> res, decltype(*first) val)
2664 {
2665 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
2666 return res;
2667 }).first;
2668 assert(is_contiguous);
2669 #endif
2670
2671 // assertion to check that each element is 1 byte long
2672 static_assert(
2673 sizeof(typename iterator_traits<IteratorType>::value_type) == 1,
2674 "each element in the iterator range must have the size of 1 byte");
2675
2676 const auto len = static_cast<size_t>(std::distance(first, last));
2677 if (JSON_LIKELY(len > 0))
2678 {
2679 // there is at least one element: use the address of first
2680 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
2681 }
2682 else
2683 {
2684 // the address of first cannot be used: use nullptr
2685 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
2686 }
2687 }
2688
2689 /// input adapter for array
2690 template<class T, std::size_t N>
input_adapter(T (& array)[N])2691 input_adapter(T (&array)[N])
2692 : input_adapter(std::begin(array), std::end(array)) {}
2693
2694 /// input adapter for contiguous container
2695 template<class ContiguousContainer, typename
2696 std::enable_if<not std::is_pointer<ContiguousContainer>::value and
2697 std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
2698 int>::type = 0>
input_adapter(const ContiguousContainer & c)2699 input_adapter(const ContiguousContainer& c)
2700 : input_adapter(std::begin(c), std::end(c)) {}
2701
operator input_adapter_t()2702 operator input_adapter_t()
2703 {
2704 return ia;
2705 }
2706
2707 private:
2708 /// the actual adapter
2709 input_adapter_t ia = nullptr;
2710 };
2711 } // namespace detail
2712 } // namespace nlohmann
2713
2714 // #include <nlohmann/detail/input/json_sax.hpp>
2715
2716
2717 #include <cassert> // assert
2718 #include <cstddef>
2719 #include <string> // string
2720 #include <utility> // move
2721 #include <vector> // vector
2722
2723 // #include <nlohmann/detail/exceptions.hpp>
2724
2725 // #include <nlohmann/detail/macro_scope.hpp>
2726
2727
2728 namespace nlohmann
2729 {
2730
2731 /*!
2732 @brief SAX interface
2733
2734 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
2735 Each function is called in different situations while the input is parsed. The
2736 boolean return value informs the parser whether to continue processing the
2737 input.
2738 */
2739 template<typename BasicJsonType>
2740 struct json_sax
2741 {
2742 /// type for (signed) integers
2743 using number_integer_t = typename BasicJsonType::number_integer_t;
2744 /// type for unsigned integers
2745 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2746 /// type for floating-point numbers
2747 using number_float_t = typename BasicJsonType::number_float_t;
2748 /// type for strings
2749 using string_t = typename BasicJsonType::string_t;
2750
2751 /*!
2752 @brief a null value was read
2753 @return whether parsing should proceed
2754 */
2755 virtual bool null() = 0;
2756
2757 /*!
2758 @brief a boolean value was read
2759 @param[in] val boolean value
2760 @return whether parsing should proceed
2761 */
2762 virtual bool boolean(bool val) = 0;
2763
2764 /*!
2765 @brief an integer number was read
2766 @param[in] val integer value
2767 @return whether parsing should proceed
2768 */
2769 virtual bool number_integer(number_integer_t val) = 0;
2770
2771 /*!
2772 @brief an unsigned integer number was read
2773 @param[in] val unsigned integer value
2774 @return whether parsing should proceed
2775 */
2776 virtual bool number_unsigned(number_unsigned_t val) = 0;
2777
2778 /*!
2779 @brief an floating-point number was read
2780 @param[in] val floating-point value
2781 @param[in] s raw token value
2782 @return whether parsing should proceed
2783 */
2784 virtual bool number_float(number_float_t val, const string_t& s) = 0;
2785
2786 /*!
2787 @brief a string was read
2788 @param[in] val string value
2789 @return whether parsing should proceed
2790 @note It is safe to move the passed string.
2791 */
2792 virtual bool string(string_t& val) = 0;
2793
2794 /*!
2795 @brief the beginning of an object was read
2796 @param[in] elements number of object elements or -1 if unknown
2797 @return whether parsing should proceed
2798 @note binary formats may report the number of elements
2799 */
2800 virtual bool start_object(std::size_t elements) = 0;
2801
2802 /*!
2803 @brief an object key was read
2804 @param[in] val object key
2805 @return whether parsing should proceed
2806 @note It is safe to move the passed string.
2807 */
2808 virtual bool key(string_t& val) = 0;
2809
2810 /*!
2811 @brief the end of an object was read
2812 @return whether parsing should proceed
2813 */
2814 virtual bool end_object() = 0;
2815
2816 /*!
2817 @brief the beginning of an array was read
2818 @param[in] elements number of array elements or -1 if unknown
2819 @return whether parsing should proceed
2820 @note binary formats may report the number of elements
2821 */
2822 virtual bool start_array(std::size_t elements) = 0;
2823
2824 /*!
2825 @brief the end of an array was read
2826 @return whether parsing should proceed
2827 */
2828 virtual bool end_array() = 0;
2829
2830 /*!
2831 @brief a parse error occurred
2832 @param[in] position the position in the input where the error occurs
2833 @param[in] last_token the last read token
2834 @param[in] ex an exception object describing the error
2835 @return whether parsing should proceed (must return false)
2836 */
2837 virtual bool parse_error(std::size_t position,
2838 const std::string& last_token,
2839 const detail::exception& ex) = 0;
2840
2841 virtual ~json_sax() = default;
2842 };
2843
2844
2845 namespace detail
2846 {
2847 /*!
2848 @brief SAX implementation to create a JSON value from SAX events
2849
2850 This class implements the @ref json_sax interface and processes the SAX events
2851 to create a JSON value which makes it basically a DOM parser. The structure or
2852 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
2853 a pointer to the respective array or object for each recursion depth.
2854
2855 After successful parsing, the value that is passed by reference to the
2856 constructor contains the parsed value.
2857
2858 @tparam BasicJsonType the JSON type
2859 */
2860 template<typename BasicJsonType>
2861 class json_sax_dom_parser
2862 {
2863 public:
2864 using number_integer_t = typename BasicJsonType::number_integer_t;
2865 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2866 using number_float_t = typename BasicJsonType::number_float_t;
2867 using string_t = typename BasicJsonType::string_t;
2868
2869 /*!
2870 @param[in, out] r reference to a JSON value that is manipulated while
2871 parsing
2872 @param[in] allow_exceptions_ whether parse errors yield exceptions
2873 */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)2874 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
2875 : root(r), allow_exceptions(allow_exceptions_)
2876 {}
2877
2878 // make class move-only
2879 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
2880 json_sax_dom_parser(json_sax_dom_parser&&) = default;
2881 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
2882 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default;
2883 ~json_sax_dom_parser() = default;
2884
null()2885 bool null()
2886 {
2887 handle_value(nullptr);
2888 return true;
2889 }
2890
boolean(bool val)2891 bool boolean(bool val)
2892 {
2893 handle_value(val);
2894 return true;
2895 }
2896
number_integer(number_integer_t val)2897 bool number_integer(number_integer_t val)
2898 {
2899 handle_value(val);
2900 return true;
2901 }
2902
number_unsigned(number_unsigned_t val)2903 bool number_unsigned(number_unsigned_t val)
2904 {
2905 handle_value(val);
2906 return true;
2907 }
2908
number_float(number_float_t val,const string_t &)2909 bool number_float(number_float_t val, const string_t& /*unused*/)
2910 {
2911 handle_value(val);
2912 return true;
2913 }
2914
string(string_t & val)2915 bool string(string_t& val)
2916 {
2917 handle_value(val);
2918 return true;
2919 }
2920
start_object(std::size_t len)2921 bool start_object(std::size_t len)
2922 {
2923 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
2924
2925 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2926 {
2927 JSON_THROW(out_of_range::create(408,
2928 "excessive object size: " + std::to_string(len)));
2929 }
2930
2931 return true;
2932 }
2933
key(string_t & val)2934 bool key(string_t& val)
2935 {
2936 // add null at given key and store the reference for later
2937 object_element = &(ref_stack.back()->m_value.object->operator[](val));
2938 return true;
2939 }
2940
end_object()2941 bool end_object()
2942 {
2943 ref_stack.pop_back();
2944 return true;
2945 }
2946
start_array(std::size_t len)2947 bool start_array(std::size_t len)
2948 {
2949 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
2950
2951 if (JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
2952 {
2953 JSON_THROW(out_of_range::create(408,
2954 "excessive array size: " + std::to_string(len)));
2955 }
2956
2957 return true;
2958 }
2959
end_array()2960 bool end_array()
2961 {
2962 ref_stack.pop_back();
2963 return true;
2964 }
2965
parse_error(std::size_t,const std::string &,const detail::exception & ex)2966 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
2967 const detail::exception& ex)
2968 {
2969 errored = true;
2970 if (allow_exceptions)
2971 {
2972 // determine the proper exception type from the id
2973 switch ((ex.id / 100) % 100)
2974 {
2975 case 1:
2976 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
2977 case 4:
2978 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
2979 // LCOV_EXCL_START
2980 case 2:
2981 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
2982 case 3:
2983 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
2984 case 5:
2985 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
2986 default:
2987 assert(false);
2988 // LCOV_EXCL_STOP
2989 }
2990 }
2991 return false;
2992 }
2993
is_errored() const2994 constexpr bool is_errored() const
2995 {
2996 return errored;
2997 }
2998
2999 private:
3000 /*!
3001 @invariant If the ref stack is empty, then the passed value will be the new
3002 root.
3003 @invariant If the ref stack contains a value, then it is an array or an
3004 object to which we can add elements
3005 */
3006 template<typename Value>
handle_value(Value && v)3007 BasicJsonType* handle_value(Value&& v)
3008 {
3009 if (ref_stack.empty())
3010 {
3011 root = BasicJsonType(std::forward<Value>(v));
3012 return &root;
3013 }
3014
3015 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
3016
3017 if (ref_stack.back()->is_array())
3018 {
3019 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
3020 return &(ref_stack.back()->m_value.array->back());
3021 }
3022
3023 assert(ref_stack.back()->is_object());
3024 assert(object_element);
3025 *object_element = BasicJsonType(std::forward<Value>(v));
3026 return object_element;
3027 }
3028
3029 /// the parsed JSON value
3030 BasicJsonType& root;
3031 /// stack to model hierarchy of values
3032 std::vector<BasicJsonType*> ref_stack {};
3033 /// helper to hold the reference for the next object element
3034 BasicJsonType* object_element = nullptr;
3035 /// whether a syntax error occurred
3036 bool errored = false;
3037 /// whether to throw exceptions in case of errors
3038 const bool allow_exceptions = true;
3039 };
3040
3041 template<typename BasicJsonType>
3042 class json_sax_dom_callback_parser
3043 {
3044 public:
3045 using number_integer_t = typename BasicJsonType::number_integer_t;
3046 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3047 using number_float_t = typename BasicJsonType::number_float_t;
3048 using string_t = typename BasicJsonType::string_t;
3049 using parser_callback_t = typename BasicJsonType::parser_callback_t;
3050 using parse_event_t = typename BasicJsonType::parse_event_t;
3051
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)3052 json_sax_dom_callback_parser(BasicJsonType& r,
3053 const parser_callback_t cb,
3054 const bool allow_exceptions_ = true)
3055 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
3056 {
3057 keep_stack.push_back(true);
3058 }
3059
3060 // make class move-only
3061 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
3062 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
3063 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
3064 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default;
3065 ~json_sax_dom_callback_parser() = default;
3066
null()3067 bool null()
3068 {
3069 handle_value(nullptr);
3070 return true;
3071 }
3072
boolean(bool val)3073 bool boolean(bool val)
3074 {
3075 handle_value(val);
3076 return true;
3077 }
3078
number_integer(number_integer_t val)3079 bool number_integer(number_integer_t val)
3080 {
3081 handle_value(val);
3082 return true;
3083 }
3084
number_unsigned(number_unsigned_t val)3085 bool number_unsigned(number_unsigned_t val)
3086 {
3087 handle_value(val);
3088 return true;
3089 }
3090
number_float(number_float_t val,const string_t &)3091 bool number_float(number_float_t val, const string_t& /*unused*/)
3092 {
3093 handle_value(val);
3094 return true;
3095 }
3096
string(string_t & val)3097 bool string(string_t& val)
3098 {
3099 handle_value(val);
3100 return true;
3101 }
3102
start_object(std::size_t len)3103 bool start_object(std::size_t len)
3104 {
3105 // check callback for object start
3106 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
3107 keep_stack.push_back(keep);
3108
3109 auto val = handle_value(BasicJsonType::value_t::object, true);
3110 ref_stack.push_back(val.second);
3111
3112 // check object limit
3113 if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3114 {
3115 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len)));
3116 }
3117
3118 return true;
3119 }
3120
key(string_t & val)3121 bool key(string_t& val)
3122 {
3123 BasicJsonType k = BasicJsonType(val);
3124
3125 // check callback for key
3126 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
3127 key_keep_stack.push_back(keep);
3128
3129 // add discarded value at given key and store the reference for later
3130 if (keep and ref_stack.back())
3131 {
3132 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
3133 }
3134
3135 return true;
3136 }
3137
end_object()3138 bool end_object()
3139 {
3140 if (ref_stack.back() and not callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
3141 {
3142 // discard object
3143 *ref_stack.back() = discarded;
3144 }
3145
3146 assert(not ref_stack.empty());
3147 assert(not keep_stack.empty());
3148 ref_stack.pop_back();
3149 keep_stack.pop_back();
3150
3151 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
3152 {
3153 // remove discarded value
3154 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
3155 {
3156 if (it->is_discarded())
3157 {
3158 ref_stack.back()->erase(it);
3159 break;
3160 }
3161 }
3162 }
3163
3164 return true;
3165 }
3166
start_array(std::size_t len)3167 bool start_array(std::size_t len)
3168 {
3169 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
3170 keep_stack.push_back(keep);
3171
3172 auto val = handle_value(BasicJsonType::value_t::array, true);
3173 ref_stack.push_back(val.second);
3174
3175 // check array limit
3176 if (ref_stack.back() and JSON_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
3177 {
3178 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len)));
3179 }
3180
3181 return true;
3182 }
3183
end_array()3184 bool end_array()
3185 {
3186 bool keep = true;
3187
3188 if (ref_stack.back())
3189 {
3190 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
3191 if (not keep)
3192 {
3193 // discard array
3194 *ref_stack.back() = discarded;
3195 }
3196 }
3197
3198 assert(not ref_stack.empty());
3199 assert(not keep_stack.empty());
3200 ref_stack.pop_back();
3201 keep_stack.pop_back();
3202
3203 // remove discarded value
3204 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
3205 {
3206 ref_stack.back()->m_value.array->pop_back();
3207 }
3208
3209 return true;
3210 }
3211
parse_error(std::size_t,const std::string &,const detail::exception & ex)3212 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
3213 const detail::exception& ex)
3214 {
3215 errored = true;
3216 if (allow_exceptions)
3217 {
3218 // determine the proper exception type from the id
3219 switch ((ex.id / 100) % 100)
3220 {
3221 case 1:
3222 JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
3223 case 4:
3224 JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
3225 // LCOV_EXCL_START
3226 case 2:
3227 JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
3228 case 3:
3229 JSON_THROW(*static_cast<const detail::type_error*>(&ex));
3230 case 5:
3231 JSON_THROW(*static_cast<const detail::other_error*>(&ex));
3232 default:
3233 assert(false);
3234 // LCOV_EXCL_STOP
3235 }
3236 }
3237 return false;
3238 }
3239
is_errored() const3240 constexpr bool is_errored() const
3241 {
3242 return errored;
3243 }
3244
3245 private:
3246 /*!
3247 @param[in] v value to add to the JSON value we build during parsing
3248 @param[in] skip_callback whether we should skip calling the callback
3249 function; this is required after start_array() and
3250 start_object() SAX events, because otherwise we would call the
3251 callback function with an empty array or object, respectively.
3252
3253 @invariant If the ref stack is empty, then the passed value will be the new
3254 root.
3255 @invariant If the ref stack contains a value, then it is an array or an
3256 object to which we can add elements
3257
3258 @return pair of boolean (whether value should be kept) and pointer (to the
3259 passed value in the ref_stack hierarchy; nullptr if not kept)
3260 */
3261 template<typename Value>
handle_value(Value && v,const bool skip_callback=false)3262 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
3263 {
3264 assert(not keep_stack.empty());
3265
3266 // do not handle this value if we know it would be added to a discarded
3267 // container
3268 if (not keep_stack.back())
3269 {
3270 return {false, nullptr};
3271 }
3272
3273 // create value
3274 auto value = BasicJsonType(std::forward<Value>(v));
3275
3276 // check callback
3277 const bool keep = skip_callback or callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
3278
3279 // do not handle this value if we just learnt it shall be discarded
3280 if (not keep)
3281 {
3282 return {false, nullptr};
3283 }
3284
3285 if (ref_stack.empty())
3286 {
3287 root = std::move(value);
3288 return {true, &root};
3289 }
3290
3291 // skip this value if we already decided to skip the parent
3292 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
3293 if (not ref_stack.back())
3294 {
3295 return {false, nullptr};
3296 }
3297
3298 // we now only expect arrays and objects
3299 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
3300
3301 // array
3302 if (ref_stack.back()->is_array())
3303 {
3304 ref_stack.back()->m_value.array->push_back(std::move(value));
3305 return {true, &(ref_stack.back()->m_value.array->back())};
3306 }
3307
3308 // object
3309 assert(ref_stack.back()->is_object());
3310 // check if we should store an element for the current key
3311 assert(not key_keep_stack.empty());
3312 const bool store_element = key_keep_stack.back();
3313 key_keep_stack.pop_back();
3314
3315 if (not store_element)
3316 {
3317 return {false, nullptr};
3318 }
3319
3320 assert(object_element);
3321 *object_element = std::move(value);
3322 return {true, object_element};
3323 }
3324
3325 /// the parsed JSON value
3326 BasicJsonType& root;
3327 /// stack to model hierarchy of values
3328 std::vector<BasicJsonType*> ref_stack {};
3329 /// stack to manage which values to keep
3330 std::vector<bool> keep_stack {};
3331 /// stack to manage which object keys to keep
3332 std::vector<bool> key_keep_stack {};
3333 /// helper to hold the reference for the next object element
3334 BasicJsonType* object_element = nullptr;
3335 /// whether a syntax error occurred
3336 bool errored = false;
3337 /// callback function
3338 const parser_callback_t callback = nullptr;
3339 /// whether to throw exceptions in case of errors
3340 const bool allow_exceptions = true;
3341 /// a discarded value for the callback
3342 BasicJsonType discarded = BasicJsonType::value_t::discarded;
3343 };
3344
3345 template<typename BasicJsonType>
3346 class json_sax_acceptor
3347 {
3348 public:
3349 using number_integer_t = typename BasicJsonType::number_integer_t;
3350 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3351 using number_float_t = typename BasicJsonType::number_float_t;
3352 using string_t = typename BasicJsonType::string_t;
3353
null()3354 bool null()
3355 {
3356 return true;
3357 }
3358
boolean(bool)3359 bool boolean(bool /*unused*/)
3360 {
3361 return true;
3362 }
3363
number_integer(number_integer_t)3364 bool number_integer(number_integer_t /*unused*/)
3365 {
3366 return true;
3367 }
3368
number_unsigned(number_unsigned_t)3369 bool number_unsigned(number_unsigned_t /*unused*/)
3370 {
3371 return true;
3372 }
3373
number_float(number_float_t,const string_t &)3374 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
3375 {
3376 return true;
3377 }
3378
string(string_t &)3379 bool string(string_t& /*unused*/)
3380 {
3381 return true;
3382 }
3383
start_object(std::size_t=std::size_t (-1))3384 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
3385 {
3386 return true;
3387 }
3388
key(string_t &)3389 bool key(string_t& /*unused*/)
3390 {
3391 return true;
3392 }
3393
end_object()3394 bool end_object()
3395 {
3396 return true;
3397 }
3398
start_array(std::size_t=std::size_t (-1))3399 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
3400 {
3401 return true;
3402 }
3403
end_array()3404 bool end_array()
3405 {
3406 return true;
3407 }
3408
parse_error(std::size_t,const std::string &,const detail::exception &)3409 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
3410 {
3411 return false;
3412 }
3413 };
3414 } // namespace detail
3415
3416 } // namespace nlohmann
3417
3418 // #include <nlohmann/detail/macro_scope.hpp>
3419
3420 // #include <nlohmann/detail/meta/is_sax.hpp>
3421
3422
3423 #include <cstdint> // size_t
3424 #include <utility> // declval
3425 #include <string> // string
3426
3427 // #include <nlohmann/detail/meta/detected.hpp>
3428
3429 // #include <nlohmann/detail/meta/type_traits.hpp>
3430
3431
3432 namespace nlohmann
3433 {
3434 namespace detail
3435 {
3436 template <typename T>
3437 using null_function_t = decltype(std::declval<T&>().null());
3438
3439 template <typename T>
3440 using boolean_function_t =
3441 decltype(std::declval<T&>().boolean(std::declval<bool>()));
3442
3443 template <typename T, typename Integer>
3444 using number_integer_function_t =
3445 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
3446
3447 template <typename T, typename Unsigned>
3448 using number_unsigned_function_t =
3449 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
3450
3451 template <typename T, typename Float, typename String>
3452 using number_float_function_t = decltype(std::declval<T&>().number_float(
3453 std::declval<Float>(), std::declval<const String&>()));
3454
3455 template <typename T, typename String>
3456 using string_function_t =
3457 decltype(std::declval<T&>().string(std::declval<String&>()));
3458
3459 template <typename T>
3460 using start_object_function_t =
3461 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
3462
3463 template <typename T, typename String>
3464 using key_function_t =
3465 decltype(std::declval<T&>().key(std::declval<String&>()));
3466
3467 template <typename T>
3468 using end_object_function_t = decltype(std::declval<T&>().end_object());
3469
3470 template <typename T>
3471 using start_array_function_t =
3472 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
3473
3474 template <typename T>
3475 using end_array_function_t = decltype(std::declval<T&>().end_array());
3476
3477 template <typename T, typename Exception>
3478 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
3479 std::declval<std::size_t>(), std::declval<const std::string&>(),
3480 std::declval<const Exception&>()));
3481
3482 template <typename SAX, typename BasicJsonType>
3483 struct is_sax
3484 {
3485 private:
3486 static_assert(is_basic_json<BasicJsonType>::value,
3487 "BasicJsonType must be of type basic_json<...>");
3488
3489 using number_integer_t = typename BasicJsonType::number_integer_t;
3490 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3491 using number_float_t = typename BasicJsonType::number_float_t;
3492 using string_t = typename BasicJsonType::string_t;
3493 using exception_t = typename BasicJsonType::exception;
3494
3495 public:
3496 static constexpr bool value =
3497 is_detected_exact<bool, null_function_t, SAX>::value &&
3498 is_detected_exact<bool, boolean_function_t, SAX>::value &&
3499 is_detected_exact<bool, number_integer_function_t, SAX,
3500 number_integer_t>::value &&
3501 is_detected_exact<bool, number_unsigned_function_t, SAX,
3502 number_unsigned_t>::value &&
3503 is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
3504 string_t>::value &&
3505 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
3506 is_detected_exact<bool, start_object_function_t, SAX>::value &&
3507 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
3508 is_detected_exact<bool, end_object_function_t, SAX>::value &&
3509 is_detected_exact<bool, start_array_function_t, SAX>::value &&
3510 is_detected_exact<bool, end_array_function_t, SAX>::value &&
3511 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
3512 };
3513
3514 template <typename SAX, typename BasicJsonType>
3515 struct is_sax_static_asserts
3516 {
3517 private:
3518 static_assert(is_basic_json<BasicJsonType>::value,
3519 "BasicJsonType must be of type basic_json<...>");
3520
3521 using number_integer_t = typename BasicJsonType::number_integer_t;
3522 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3523 using number_float_t = typename BasicJsonType::number_float_t;
3524 using string_t = typename BasicJsonType::string_t;
3525 using exception_t = typename BasicJsonType::exception;
3526
3527 public:
3528 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
3529 "Missing/invalid function: bool null()");
3530 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3531 "Missing/invalid function: bool boolean(bool)");
3532 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
3533 "Missing/invalid function: bool boolean(bool)");
3534 static_assert(
3535 is_detected_exact<bool, number_integer_function_t, SAX,
3536 number_integer_t>::value,
3537 "Missing/invalid function: bool number_integer(number_integer_t)");
3538 static_assert(
3539 is_detected_exact<bool, number_unsigned_function_t, SAX,
3540 number_unsigned_t>::value,
3541 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
3542 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
3543 number_float_t, string_t>::value,
3544 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
3545 static_assert(
3546 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
3547 "Missing/invalid function: bool string(string_t&)");
3548 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
3549 "Missing/invalid function: bool start_object(std::size_t)");
3550 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
3551 "Missing/invalid function: bool key(string_t&)");
3552 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
3553 "Missing/invalid function: bool end_object()");
3554 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
3555 "Missing/invalid function: bool start_array(std::size_t)");
3556 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
3557 "Missing/invalid function: bool end_array()");
3558 static_assert(
3559 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
3560 "Missing/invalid function: bool parse_error(std::size_t, const "
3561 "std::string&, const exception&)");
3562 };
3563 } // namespace detail
3564 } // namespace nlohmann
3565
3566 // #include <nlohmann/detail/value_t.hpp>
3567
3568
3569 namespace nlohmann
3570 {
3571 namespace detail
3572 {
3573 ///////////////////
3574 // binary reader //
3575 ///////////////////
3576
3577 /*!
3578 @brief deserialization of CBOR, MessagePack, and UBJSON values
3579 */
3580 template<typename BasicJsonType, typename SAX = json_sax_dom_parser<BasicJsonType>>
3581 class binary_reader
3582 {
3583 using number_integer_t = typename BasicJsonType::number_integer_t;
3584 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
3585 using number_float_t = typename BasicJsonType::number_float_t;
3586 using string_t = typename BasicJsonType::string_t;
3587 using json_sax_t = SAX;
3588
3589 public:
3590 /*!
3591 @brief create a binary reader
3592
3593 @param[in] adapter input adapter to read from
3594 */
binary_reader(input_adapter_t adapter)3595 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
3596 {
3597 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
3598 assert(ia);
3599 }
3600
3601 // make class move-only
3602 binary_reader(const binary_reader&) = delete;
3603 binary_reader(binary_reader&&) = default;
3604 binary_reader& operator=(const binary_reader&) = delete;
3605 binary_reader& operator=(binary_reader&&) = default;
3606 ~binary_reader() = default;
3607
3608 /*!
3609 @param[in] format the binary format to parse
3610 @param[in] sax_ a SAX event processor
3611 @param[in] strict whether to expect the input to be consumed completed
3612
3613 @return
3614 */
sax_parse(const input_format_t format,json_sax_t * sax_,const bool strict=true)3615 bool sax_parse(const input_format_t format,
3616 json_sax_t* sax_,
3617 const bool strict = true)
3618 {
3619 sax = sax_;
3620 bool result = false;
3621
3622 switch (format)
3623 {
3624 case input_format_t::bson:
3625 result = parse_bson_internal();
3626 break;
3627
3628 case input_format_t::cbor:
3629 result = parse_cbor_internal();
3630 break;
3631
3632 case input_format_t::msgpack:
3633 result = parse_msgpack_internal();
3634 break;
3635
3636 case input_format_t::ubjson:
3637 result = parse_ubjson_internal();
3638 break;
3639
3640 default: // LCOV_EXCL_LINE
3641 assert(false); // LCOV_EXCL_LINE
3642 }
3643
3644 // strict mode: next byte must be EOF
3645 if (result and strict)
3646 {
3647 if (format == input_format_t::ubjson)
3648 {
3649 get_ignore_noop();
3650 }
3651 else
3652 {
3653 get();
3654 }
3655
3656 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
3657 {
3658 return sax->parse_error(chars_read, get_token_string(),
3659 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
3660 }
3661 }
3662
3663 return result;
3664 }
3665
3666 /*!
3667 @brief determine system byte order
3668
3669 @return true if and only if system's byte order is little endian
3670
3671 @note from http://stackoverflow.com/a/1001328/266378
3672 */
little_endianess(int num=1)3673 static constexpr bool little_endianess(int num = 1) noexcept
3674 {
3675 return *reinterpret_cast<char*>(&num) == 1;
3676 }
3677
3678 private:
3679 //////////
3680 // BSON //
3681 //////////
3682
3683 /*!
3684 @brief Reads in a BSON-object and passes it to the SAX-parser.
3685 @return whether a valid BSON-value was passed to the SAX parser
3686 */
parse_bson_internal()3687 bool parse_bson_internal()
3688 {
3689 std::int32_t document_size;
3690 get_number<std::int32_t, true>(input_format_t::bson, document_size);
3691
3692 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
3693 {
3694 return false;
3695 }
3696
3697 if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/false)))
3698 {
3699 return false;
3700 }
3701
3702 return sax->end_object();
3703 }
3704
3705 /*!
3706 @brief Parses a C-style string from the BSON input.
3707 @param[in, out] result A reference to the string variable where the read
3708 string is to be stored.
3709 @return `true` if the \x00-byte indicating the end of the string was
3710 encountered before the EOF; false` indicates an unexpected EOF.
3711 */
get_bson_cstr(string_t & result)3712 bool get_bson_cstr(string_t& result)
3713 {
3714 auto out = std::back_inserter(result);
3715 while (true)
3716 {
3717 get();
3718 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "cstring")))
3719 {
3720 return false;
3721 }
3722 if (current == 0x00)
3723 {
3724 return true;
3725 }
3726 *out++ = static_cast<char>(current);
3727 }
3728
3729 return true;
3730 }
3731
3732 /*!
3733 @brief Parses a zero-terminated string of length @a len from the BSON
3734 input.
3735 @param[in] len The length (including the zero-byte at the end) of the
3736 string to be read.
3737 @param[in, out] result A reference to the string variable where the read
3738 string is to be stored.
3739 @tparam NumberType The type of the length @a len
3740 @pre len >= 1
3741 @return `true` if the string was successfully parsed
3742 */
3743 template<typename NumberType>
get_bson_string(const NumberType len,string_t & result)3744 bool get_bson_string(const NumberType len, string_t& result)
3745 {
3746 if (JSON_UNLIKELY(len < 1))
3747 {
3748 auto last_token = get_token_string();
3749 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")));
3750 }
3751
3752 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) and get() != std::char_traits<char>::eof();
3753 }
3754
3755 /*!
3756 @brief Read a BSON document element of the given @a element_type.
3757 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
3758 @param[in] element_type_parse_position The position in the input stream,
3759 where the `element_type` was read.
3760 @warning Not all BSON element types are supported yet. An unsupported
3761 @a element_type will give rise to a parse_error.114:
3762 Unsupported BSON record type 0x...
3763 @return whether a valid BSON-object/array was passed to the SAX parser
3764 */
parse_bson_element_internal(const int element_type,const std::size_t element_type_parse_position)3765 bool parse_bson_element_internal(const int element_type,
3766 const std::size_t element_type_parse_position)
3767 {
3768 switch (element_type)
3769 {
3770 case 0x01: // double
3771 {
3772 double number;
3773 return get_number<double, true>(input_format_t::bson, number) and sax->number_float(static_cast<number_float_t>(number), "");
3774 }
3775
3776 case 0x02: // string
3777 {
3778 std::int32_t len;
3779 string_t value;
3780 return get_number<std::int32_t, true>(input_format_t::bson, len) and get_bson_string(len, value) and sax->string(value);
3781 }
3782
3783 case 0x03: // object
3784 {
3785 return parse_bson_internal();
3786 }
3787
3788 case 0x04: // array
3789 {
3790 return parse_bson_array();
3791 }
3792
3793 case 0x08: // boolean
3794 {
3795 return sax->boolean(get() != 0);
3796 }
3797
3798 case 0x0A: // null
3799 {
3800 return sax->null();
3801 }
3802
3803 case 0x10: // int32
3804 {
3805 std::int32_t value;
3806 return get_number<std::int32_t, true>(input_format_t::bson, value) and sax->number_integer(value);
3807 }
3808
3809 case 0x12: // int64
3810 {
3811 std::int64_t value;
3812 return get_number<std::int64_t, true>(input_format_t::bson, value) and sax->number_integer(value);
3813 }
3814
3815 default: // anything else not supported (yet)
3816 {
3817 std::array<char, 3> cr{{}};
3818 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type));
3819 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())));
3820 }
3821 }
3822 }
3823
3824 /*!
3825 @brief Read a BSON element list (as specified in the BSON-spec)
3826
3827 The same binary layout is used for objects and arrays, hence it must be
3828 indicated with the argument @a is_array which one is expected
3829 (true --> array, false --> object).
3830
3831 @param[in] is_array Determines if the element list being read is to be
3832 treated as an object (@a is_array == false), or as an
3833 array (@a is_array == true).
3834 @return whether a valid BSON-object/array was passed to the SAX parser
3835 */
parse_bson_element_list(const bool is_array)3836 bool parse_bson_element_list(const bool is_array)
3837 {
3838 string_t key;
3839 while (int element_type = get())
3840 {
3841 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::bson, "element list")))
3842 {
3843 return false;
3844 }
3845
3846 const std::size_t element_type_parse_position = chars_read;
3847 if (JSON_UNLIKELY(not get_bson_cstr(key)))
3848 {
3849 return false;
3850 }
3851
3852 if (not is_array and not sax->key(key))
3853 {
3854 return false;
3855 }
3856
3857 if (JSON_UNLIKELY(not parse_bson_element_internal(element_type, element_type_parse_position)))
3858 {
3859 return false;
3860 }
3861
3862 // get_bson_cstr only appends
3863 key.clear();
3864 }
3865
3866 return true;
3867 }
3868
3869 /*!
3870 @brief Reads an array from the BSON input and passes it to the SAX-parser.
3871 @return whether a valid BSON-array was passed to the SAX parser
3872 */
parse_bson_array()3873 bool parse_bson_array()
3874 {
3875 std::int32_t document_size;
3876 get_number<std::int32_t, true>(input_format_t::bson, document_size);
3877
3878 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
3879 {
3880 return false;
3881 }
3882
3883 if (JSON_UNLIKELY(not parse_bson_element_list(/*is_array*/true)))
3884 {
3885 return false;
3886 }
3887
3888 return sax->end_array();
3889 }
3890
3891 //////////
3892 // CBOR //
3893 //////////
3894
3895 /*!
3896 @param[in] get_char whether a new character should be retrieved from the
3897 input (true, default) or whether the last read
3898 character should be considered instead
3899
3900 @return whether a valid CBOR value was passed to the SAX parser
3901 */
parse_cbor_internal(const bool get_char=true)3902 bool parse_cbor_internal(const bool get_char = true)
3903 {
3904 switch (get_char ? get() : current)
3905 {
3906 // EOF
3907 case std::char_traits<char>::eof():
3908 return unexpect_eof(input_format_t::cbor, "value");
3909
3910 // Integer 0x00..0x17 (0..23)
3911 case 0x00:
3912 case 0x01:
3913 case 0x02:
3914 case 0x03:
3915 case 0x04:
3916 case 0x05:
3917 case 0x06:
3918 case 0x07:
3919 case 0x08:
3920 case 0x09:
3921 case 0x0A:
3922 case 0x0B:
3923 case 0x0C:
3924 case 0x0D:
3925 case 0x0E:
3926 case 0x0F:
3927 case 0x10:
3928 case 0x11:
3929 case 0x12:
3930 case 0x13:
3931 case 0x14:
3932 case 0x15:
3933 case 0x16:
3934 case 0x17:
3935 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
3936
3937 case 0x18: // Unsigned integer (one-byte uint8_t follows)
3938 {
3939 std::uint8_t number;
3940 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3941 }
3942
3943 case 0x19: // Unsigned integer (two-byte uint16_t follows)
3944 {
3945 std::uint16_t number;
3946 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3947 }
3948
3949 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
3950 {
3951 std::uint32_t number;
3952 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3953 }
3954
3955 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
3956 {
3957 std::uint64_t number;
3958 return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
3959 }
3960
3961 // Negative integer -1-0x00..-1-0x17 (-1..-24)
3962 case 0x20:
3963 case 0x21:
3964 case 0x22:
3965 case 0x23:
3966 case 0x24:
3967 case 0x25:
3968 case 0x26:
3969 case 0x27:
3970 case 0x28:
3971 case 0x29:
3972 case 0x2A:
3973 case 0x2B:
3974 case 0x2C:
3975 case 0x2D:
3976 case 0x2E:
3977 case 0x2F:
3978 case 0x30:
3979 case 0x31:
3980 case 0x32:
3981 case 0x33:
3982 case 0x34:
3983 case 0x35:
3984 case 0x36:
3985 case 0x37:
3986 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
3987
3988 case 0x38: // Negative integer (one-byte uint8_t follows)
3989 {
3990 std::uint8_t number;
3991 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3992 }
3993
3994 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
3995 {
3996 std::uint16_t number;
3997 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
3998 }
3999
4000 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
4001 {
4002 std::uint32_t number;
4003 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
4004 }
4005
4006 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
4007 {
4008 std::uint64_t number;
4009 return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
4010 - static_cast<number_integer_t>(number));
4011 }
4012
4013 // UTF-8 string (0x00..0x17 bytes follow)
4014 case 0x60:
4015 case 0x61:
4016 case 0x62:
4017 case 0x63:
4018 case 0x64:
4019 case 0x65:
4020 case 0x66:
4021 case 0x67:
4022 case 0x68:
4023 case 0x69:
4024 case 0x6A:
4025 case 0x6B:
4026 case 0x6C:
4027 case 0x6D:
4028 case 0x6E:
4029 case 0x6F:
4030 case 0x70:
4031 case 0x71:
4032 case 0x72:
4033 case 0x73:
4034 case 0x74:
4035 case 0x75:
4036 case 0x76:
4037 case 0x77:
4038 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4039 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4040 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4041 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4042 case 0x7F: // UTF-8 string (indefinite length)
4043 {
4044 string_t s;
4045 return get_cbor_string(s) and sax->string(s);
4046 }
4047
4048 // array (0x00..0x17 data items follow)
4049 case 0x80:
4050 case 0x81:
4051 case 0x82:
4052 case 0x83:
4053 case 0x84:
4054 case 0x85:
4055 case 0x86:
4056 case 0x87:
4057 case 0x88:
4058 case 0x89:
4059 case 0x8A:
4060 case 0x8B:
4061 case 0x8C:
4062 case 0x8D:
4063 case 0x8E:
4064 case 0x8F:
4065 case 0x90:
4066 case 0x91:
4067 case 0x92:
4068 case 0x93:
4069 case 0x94:
4070 case 0x95:
4071 case 0x96:
4072 case 0x97:
4073 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
4074
4075 case 0x98: // array (one-byte uint8_t for n follows)
4076 {
4077 std::uint8_t len;
4078 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4079 }
4080
4081 case 0x99: // array (two-byte uint16_t for n follow)
4082 {
4083 std::uint16_t len;
4084 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4085 }
4086
4087 case 0x9A: // array (four-byte uint32_t for n follow)
4088 {
4089 std::uint32_t len;
4090 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4091 }
4092
4093 case 0x9B: // array (eight-byte uint64_t for n follow)
4094 {
4095 std::uint64_t len;
4096 return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
4097 }
4098
4099 case 0x9F: // array (indefinite length)
4100 return get_cbor_array(std::size_t(-1));
4101
4102 // map (0x00..0x17 pairs of data items follow)
4103 case 0xA0:
4104 case 0xA1:
4105 case 0xA2:
4106 case 0xA3:
4107 case 0xA4:
4108 case 0xA5:
4109 case 0xA6:
4110 case 0xA7:
4111 case 0xA8:
4112 case 0xA9:
4113 case 0xAA:
4114 case 0xAB:
4115 case 0xAC:
4116 case 0xAD:
4117 case 0xAE:
4118 case 0xAF:
4119 case 0xB0:
4120 case 0xB1:
4121 case 0xB2:
4122 case 0xB3:
4123 case 0xB4:
4124 case 0xB5:
4125 case 0xB6:
4126 case 0xB7:
4127 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu));
4128
4129 case 0xB8: // map (one-byte uint8_t for n follows)
4130 {
4131 std::uint8_t len;
4132 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4133 }
4134
4135 case 0xB9: // map (two-byte uint16_t for n follow)
4136 {
4137 std::uint16_t len;
4138 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4139 }
4140
4141 case 0xBA: // map (four-byte uint32_t for n follow)
4142 {
4143 std::uint32_t len;
4144 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4145 }
4146
4147 case 0xBB: // map (eight-byte uint64_t for n follow)
4148 {
4149 std::uint64_t len;
4150 return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
4151 }
4152
4153 case 0xBF: // map (indefinite length)
4154 return get_cbor_object(std::size_t(-1));
4155
4156 case 0xF4: // false
4157 return sax->boolean(false);
4158
4159 case 0xF5: // true
4160 return sax->boolean(true);
4161
4162 case 0xF6: // null
4163 return sax->null();
4164
4165 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
4166 {
4167 const int byte1_raw = get();
4168 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
4169 {
4170 return false;
4171 }
4172 const int byte2_raw = get();
4173 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
4174 {
4175 return false;
4176 }
4177
4178 const auto byte1 = static_cast<unsigned char>(byte1_raw);
4179 const auto byte2 = static_cast<unsigned char>(byte2_raw);
4180
4181 // code from RFC 7049, Appendix D, Figure 3:
4182 // As half-precision floating-point numbers were only added
4183 // to IEEE 754 in 2008, today's programming platforms often
4184 // still only have limited support for them. It is very
4185 // easy to include at least decoding support for them even
4186 // without such support. An example of a small decoder for
4187 // half-precision floating-point numbers in the C language
4188 // is shown in Fig. 3.
4189 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
4190 const double val = [&half]
4191 {
4192 const int exp = (half >> 10u) & 0x1Fu;
4193 const unsigned int mant = half & 0x3FFu;
4194 assert(0 <= exp and exp <= 32);
4195 assert(0 <= mant and mant <= 1024);
4196 switch (exp)
4197 {
4198 case 0:
4199 return std::ldexp(mant, -24);
4200 case 31:
4201 return (mant == 0)
4202 ? std::numeric_limits<double>::infinity()
4203 : std::numeric_limits<double>::quiet_NaN();
4204 default:
4205 return std::ldexp(mant + 1024, exp - 25);
4206 }
4207 }();
4208 return sax->number_float((half & 0x8000u) != 0
4209 ? static_cast<number_float_t>(-val)
4210 : static_cast<number_float_t>(val), "");
4211 }
4212
4213 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
4214 {
4215 float number;
4216 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
4217 }
4218
4219 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
4220 {
4221 double number;
4222 return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
4223 }
4224
4225 default: // anything else (0xFF is handled inside the other types)
4226 {
4227 auto last_token = get_token_string();
4228 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")));
4229 }
4230 }
4231 }
4232
4233 /*!
4234 @brief reads a CBOR string
4235
4236 This function first reads starting bytes to determine the expected
4237 string length and then copies this number of bytes into a string.
4238 Additionally, CBOR's strings with indefinite lengths are supported.
4239
4240 @param[out] result created string
4241
4242 @return whether string creation completed
4243 */
get_cbor_string(string_t & result)4244 bool get_cbor_string(string_t& result)
4245 {
4246 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
4247 {
4248 return false;
4249 }
4250
4251 switch (current)
4252 {
4253 // UTF-8 string (0x00..0x17 bytes follow)
4254 case 0x60:
4255 case 0x61:
4256 case 0x62:
4257 case 0x63:
4258 case 0x64:
4259 case 0x65:
4260 case 0x66:
4261 case 0x67:
4262 case 0x68:
4263 case 0x69:
4264 case 0x6A:
4265 case 0x6B:
4266 case 0x6C:
4267 case 0x6D:
4268 case 0x6E:
4269 case 0x6F:
4270 case 0x70:
4271 case 0x71:
4272 case 0x72:
4273 case 0x73:
4274 case 0x74:
4275 case 0x75:
4276 case 0x76:
4277 case 0x77:
4278 {
4279 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
4280 }
4281
4282 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4283 {
4284 std::uint8_t len;
4285 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4286 }
4287
4288 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4289 {
4290 std::uint16_t len;
4291 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4292 }
4293
4294 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
4295 {
4296 std::uint32_t len;
4297 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4298 }
4299
4300 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
4301 {
4302 std::uint64_t len;
4303 return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
4304 }
4305
4306 case 0x7F: // UTF-8 string (indefinite length)
4307 {
4308 while (get() != 0xFF)
4309 {
4310 string_t chunk;
4311 if (not get_cbor_string(chunk))
4312 {
4313 return false;
4314 }
4315 result.append(chunk);
4316 }
4317 return true;
4318 }
4319
4320 default:
4321 {
4322 auto last_token = get_token_string();
4323 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")));
4324 }
4325 }
4326 }
4327
4328 /*!
4329 @param[in] len the length of the array or std::size_t(-1) for an
4330 array of indefinite size
4331 @return whether array creation completed
4332 */
get_cbor_array(const std::size_t len)4333 bool get_cbor_array(const std::size_t len)
4334 {
4335 if (JSON_UNLIKELY(not sax->start_array(len)))
4336 {
4337 return false;
4338 }
4339
4340 if (len != std::size_t(-1))
4341 {
4342 for (std::size_t i = 0; i < len; ++i)
4343 {
4344 if (JSON_UNLIKELY(not parse_cbor_internal()))
4345 {
4346 return false;
4347 }
4348 }
4349 }
4350 else
4351 {
4352 while (get() != 0xFF)
4353 {
4354 if (JSON_UNLIKELY(not parse_cbor_internal(false)))
4355 {
4356 return false;
4357 }
4358 }
4359 }
4360
4361 return sax->end_array();
4362 }
4363
4364 /*!
4365 @param[in] len the length of the object or std::size_t(-1) for an
4366 object of indefinite size
4367 @return whether object creation completed
4368 */
get_cbor_object(const std::size_t len)4369 bool get_cbor_object(const std::size_t len)
4370 {
4371 if (JSON_UNLIKELY(not sax->start_object(len)))
4372 {
4373 return false;
4374 }
4375
4376 string_t key;
4377 if (len != std::size_t(-1))
4378 {
4379 for (std::size_t i = 0; i < len; ++i)
4380 {
4381 get();
4382 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
4383 {
4384 return false;
4385 }
4386
4387 if (JSON_UNLIKELY(not parse_cbor_internal()))
4388 {
4389 return false;
4390 }
4391 key.clear();
4392 }
4393 }
4394 else
4395 {
4396 while (get() != 0xFF)
4397 {
4398 if (JSON_UNLIKELY(not get_cbor_string(key) or not sax->key(key)))
4399 {
4400 return false;
4401 }
4402
4403 if (JSON_UNLIKELY(not parse_cbor_internal()))
4404 {
4405 return false;
4406 }
4407 key.clear();
4408 }
4409 }
4410
4411 return sax->end_object();
4412 }
4413
4414 /////////////
4415 // MsgPack //
4416 /////////////
4417
4418 /*!
4419 @return whether a valid MessagePack value was passed to the SAX parser
4420 */
parse_msgpack_internal()4421 bool parse_msgpack_internal()
4422 {
4423 switch (get())
4424 {
4425 // EOF
4426 case std::char_traits<char>::eof():
4427 return unexpect_eof(input_format_t::msgpack, "value");
4428
4429 // positive fixint
4430 case 0x00:
4431 case 0x01:
4432 case 0x02:
4433 case 0x03:
4434 case 0x04:
4435 case 0x05:
4436 case 0x06:
4437 case 0x07:
4438 case 0x08:
4439 case 0x09:
4440 case 0x0A:
4441 case 0x0B:
4442 case 0x0C:
4443 case 0x0D:
4444 case 0x0E:
4445 case 0x0F:
4446 case 0x10:
4447 case 0x11:
4448 case 0x12:
4449 case 0x13:
4450 case 0x14:
4451 case 0x15:
4452 case 0x16:
4453 case 0x17:
4454 case 0x18:
4455 case 0x19:
4456 case 0x1A:
4457 case 0x1B:
4458 case 0x1C:
4459 case 0x1D:
4460 case 0x1E:
4461 case 0x1F:
4462 case 0x20:
4463 case 0x21:
4464 case 0x22:
4465 case 0x23:
4466 case 0x24:
4467 case 0x25:
4468 case 0x26:
4469 case 0x27:
4470 case 0x28:
4471 case 0x29:
4472 case 0x2A:
4473 case 0x2B:
4474 case 0x2C:
4475 case 0x2D:
4476 case 0x2E:
4477 case 0x2F:
4478 case 0x30:
4479 case 0x31:
4480 case 0x32:
4481 case 0x33:
4482 case 0x34:
4483 case 0x35:
4484 case 0x36:
4485 case 0x37:
4486 case 0x38:
4487 case 0x39:
4488 case 0x3A:
4489 case 0x3B:
4490 case 0x3C:
4491 case 0x3D:
4492 case 0x3E:
4493 case 0x3F:
4494 case 0x40:
4495 case 0x41:
4496 case 0x42:
4497 case 0x43:
4498 case 0x44:
4499 case 0x45:
4500 case 0x46:
4501 case 0x47:
4502 case 0x48:
4503 case 0x49:
4504 case 0x4A:
4505 case 0x4B:
4506 case 0x4C:
4507 case 0x4D:
4508 case 0x4E:
4509 case 0x4F:
4510 case 0x50:
4511 case 0x51:
4512 case 0x52:
4513 case 0x53:
4514 case 0x54:
4515 case 0x55:
4516 case 0x56:
4517 case 0x57:
4518 case 0x58:
4519 case 0x59:
4520 case 0x5A:
4521 case 0x5B:
4522 case 0x5C:
4523 case 0x5D:
4524 case 0x5E:
4525 case 0x5F:
4526 case 0x60:
4527 case 0x61:
4528 case 0x62:
4529 case 0x63:
4530 case 0x64:
4531 case 0x65:
4532 case 0x66:
4533 case 0x67:
4534 case 0x68:
4535 case 0x69:
4536 case 0x6A:
4537 case 0x6B:
4538 case 0x6C:
4539 case 0x6D:
4540 case 0x6E:
4541 case 0x6F:
4542 case 0x70:
4543 case 0x71:
4544 case 0x72:
4545 case 0x73:
4546 case 0x74:
4547 case 0x75:
4548 case 0x76:
4549 case 0x77:
4550 case 0x78:
4551 case 0x79:
4552 case 0x7A:
4553 case 0x7B:
4554 case 0x7C:
4555 case 0x7D:
4556 case 0x7E:
4557 case 0x7F:
4558 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
4559
4560 // fixmap
4561 case 0x80:
4562 case 0x81:
4563 case 0x82:
4564 case 0x83:
4565 case 0x84:
4566 case 0x85:
4567 case 0x86:
4568 case 0x87:
4569 case 0x88:
4570 case 0x89:
4571 case 0x8A:
4572 case 0x8B:
4573 case 0x8C:
4574 case 0x8D:
4575 case 0x8E:
4576 case 0x8F:
4577 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
4578
4579 // fixarray
4580 case 0x90:
4581 case 0x91:
4582 case 0x92:
4583 case 0x93:
4584 case 0x94:
4585 case 0x95:
4586 case 0x96:
4587 case 0x97:
4588 case 0x98:
4589 case 0x99:
4590 case 0x9A:
4591 case 0x9B:
4592 case 0x9C:
4593 case 0x9D:
4594 case 0x9E:
4595 case 0x9F:
4596 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
4597
4598 // fixstr
4599 case 0xA0:
4600 case 0xA1:
4601 case 0xA2:
4602 case 0xA3:
4603 case 0xA4:
4604 case 0xA5:
4605 case 0xA6:
4606 case 0xA7:
4607 case 0xA8:
4608 case 0xA9:
4609 case 0xAA:
4610 case 0xAB:
4611 case 0xAC:
4612 case 0xAD:
4613 case 0xAE:
4614 case 0xAF:
4615 case 0xB0:
4616 case 0xB1:
4617 case 0xB2:
4618 case 0xB3:
4619 case 0xB4:
4620 case 0xB5:
4621 case 0xB6:
4622 case 0xB7:
4623 case 0xB8:
4624 case 0xB9:
4625 case 0xBA:
4626 case 0xBB:
4627 case 0xBC:
4628 case 0xBD:
4629 case 0xBE:
4630 case 0xBF:
4631 {
4632 string_t s;
4633 return get_msgpack_string(s) and sax->string(s);
4634 }
4635
4636 case 0xC0: // nil
4637 return sax->null();
4638
4639 case 0xC2: // false
4640 return sax->boolean(false);
4641
4642 case 0xC3: // true
4643 return sax->boolean(true);
4644
4645 case 0xCA: // float 32
4646 {
4647 float number;
4648 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
4649 }
4650
4651 case 0xCB: // float 64
4652 {
4653 double number;
4654 return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
4655 }
4656
4657 case 0xCC: // uint 8
4658 {
4659 std::uint8_t number;
4660 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4661 }
4662
4663 case 0xCD: // uint 16
4664 {
4665 std::uint16_t number;
4666 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4667 }
4668
4669 case 0xCE: // uint 32
4670 {
4671 std::uint32_t number;
4672 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4673 }
4674
4675 case 0xCF: // uint 64
4676 {
4677 std::uint64_t number;
4678 return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
4679 }
4680
4681 case 0xD0: // int 8
4682 {
4683 std::int8_t number;
4684 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4685 }
4686
4687 case 0xD1: // int 16
4688 {
4689 std::int16_t number;
4690 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4691 }
4692
4693 case 0xD2: // int 32
4694 {
4695 std::int32_t number;
4696 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4697 }
4698
4699 case 0xD3: // int 64
4700 {
4701 std::int64_t number;
4702 return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
4703 }
4704
4705 case 0xD9: // str 8
4706 case 0xDA: // str 16
4707 case 0xDB: // str 32
4708 {
4709 string_t s;
4710 return get_msgpack_string(s) and sax->string(s);
4711 }
4712
4713 case 0xDC: // array 16
4714 {
4715 std::uint16_t len;
4716 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
4717 }
4718
4719 case 0xDD: // array 32
4720 {
4721 std::uint32_t len;
4722 return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
4723 }
4724
4725 case 0xDE: // map 16
4726 {
4727 std::uint16_t len;
4728 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
4729 }
4730
4731 case 0xDF: // map 32
4732 {
4733 std::uint32_t len;
4734 return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
4735 }
4736
4737 // negative fixint
4738 case 0xE0:
4739 case 0xE1:
4740 case 0xE2:
4741 case 0xE3:
4742 case 0xE4:
4743 case 0xE5:
4744 case 0xE6:
4745 case 0xE7:
4746 case 0xE8:
4747 case 0xE9:
4748 case 0xEA:
4749 case 0xEB:
4750 case 0xEC:
4751 case 0xED:
4752 case 0xEE:
4753 case 0xEF:
4754 case 0xF0:
4755 case 0xF1:
4756 case 0xF2:
4757 case 0xF3:
4758 case 0xF4:
4759 case 0xF5:
4760 case 0xF6:
4761 case 0xF7:
4762 case 0xF8:
4763 case 0xF9:
4764 case 0xFA:
4765 case 0xFB:
4766 case 0xFC:
4767 case 0xFD:
4768 case 0xFE:
4769 case 0xFF:
4770 return sax->number_integer(static_cast<std::int8_t>(current));
4771
4772 default: // anything else
4773 {
4774 auto last_token = get_token_string();
4775 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")));
4776 }
4777 }
4778 }
4779
4780 /*!
4781 @brief reads a MessagePack string
4782
4783 This function first reads starting bytes to determine the expected
4784 string length and then copies this number of bytes into a string.
4785
4786 @param[out] result created string
4787
4788 @return whether string creation completed
4789 */
get_msgpack_string(string_t & result)4790 bool get_msgpack_string(string_t& result)
4791 {
4792 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
4793 {
4794 return false;
4795 }
4796
4797 switch (current)
4798 {
4799 // fixstr
4800 case 0xA0:
4801 case 0xA1:
4802 case 0xA2:
4803 case 0xA3:
4804 case 0xA4:
4805 case 0xA5:
4806 case 0xA6:
4807 case 0xA7:
4808 case 0xA8:
4809 case 0xA9:
4810 case 0xAA:
4811 case 0xAB:
4812 case 0xAC:
4813 case 0xAD:
4814 case 0xAE:
4815 case 0xAF:
4816 case 0xB0:
4817 case 0xB1:
4818 case 0xB2:
4819 case 0xB3:
4820 case 0xB4:
4821 case 0xB5:
4822 case 0xB6:
4823 case 0xB7:
4824 case 0xB8:
4825 case 0xB9:
4826 case 0xBA:
4827 case 0xBB:
4828 case 0xBC:
4829 case 0xBD:
4830 case 0xBE:
4831 case 0xBF:
4832 {
4833 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
4834 }
4835
4836 case 0xD9: // str 8
4837 {
4838 std::uint8_t len;
4839 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4840 }
4841
4842 case 0xDA: // str 16
4843 {
4844 std::uint16_t len;
4845 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4846 }
4847
4848 case 0xDB: // str 32
4849 {
4850 std::uint32_t len;
4851 return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
4852 }
4853
4854 default:
4855 {
4856 auto last_token = get_token_string();
4857 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")));
4858 }
4859 }
4860 }
4861
4862 /*!
4863 @param[in] len the length of the array
4864 @return whether array creation completed
4865 */
get_msgpack_array(const std::size_t len)4866 bool get_msgpack_array(const std::size_t len)
4867 {
4868 if (JSON_UNLIKELY(not sax->start_array(len)))
4869 {
4870 return false;
4871 }
4872
4873 for (std::size_t i = 0; i < len; ++i)
4874 {
4875 if (JSON_UNLIKELY(not parse_msgpack_internal()))
4876 {
4877 return false;
4878 }
4879 }
4880
4881 return sax->end_array();
4882 }
4883
4884 /*!
4885 @param[in] len the length of the object
4886 @return whether object creation completed
4887 */
get_msgpack_object(const std::size_t len)4888 bool get_msgpack_object(const std::size_t len)
4889 {
4890 if (JSON_UNLIKELY(not sax->start_object(len)))
4891 {
4892 return false;
4893 }
4894
4895 string_t key;
4896 for (std::size_t i = 0; i < len; ++i)
4897 {
4898 get();
4899 if (JSON_UNLIKELY(not get_msgpack_string(key) or not sax->key(key)))
4900 {
4901 return false;
4902 }
4903
4904 if (JSON_UNLIKELY(not parse_msgpack_internal()))
4905 {
4906 return false;
4907 }
4908 key.clear();
4909 }
4910
4911 return sax->end_object();
4912 }
4913
4914 ////////////
4915 // UBJSON //
4916 ////////////
4917
4918 /*!
4919 @param[in] get_char whether a new character should be retrieved from the
4920 input (true, default) or whether the last read
4921 character should be considered instead
4922
4923 @return whether a valid UBJSON value was passed to the SAX parser
4924 */
parse_ubjson_internal(const bool get_char=true)4925 bool parse_ubjson_internal(const bool get_char = true)
4926 {
4927 return get_ubjson_value(get_char ? get_ignore_noop() : current);
4928 }
4929
4930 /*!
4931 @brief reads a UBJSON string
4932
4933 This function is either called after reading the 'S' byte explicitly
4934 indicating a string, or in case of an object key where the 'S' byte can be
4935 left out.
4936
4937 @param[out] result created string
4938 @param[in] get_char whether a new character should be retrieved from the
4939 input (true, default) or whether the last read
4940 character should be considered instead
4941
4942 @return whether string creation completed
4943 */
get_ubjson_string(string_t & result,const bool get_char=true)4944 bool get_ubjson_string(string_t& result, const bool get_char = true)
4945 {
4946 if (get_char)
4947 {
4948 get(); // TODO(niels): may we ignore N here?
4949 }
4950
4951 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
4952 {
4953 return false;
4954 }
4955
4956 switch (current)
4957 {
4958 case 'U':
4959 {
4960 std::uint8_t len;
4961 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4962 }
4963
4964 case 'i':
4965 {
4966 std::int8_t len;
4967 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4968 }
4969
4970 case 'I':
4971 {
4972 std::int16_t len;
4973 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4974 }
4975
4976 case 'l':
4977 {
4978 std::int32_t len;
4979 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4980 }
4981
4982 case 'L':
4983 {
4984 std::int64_t len;
4985 return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
4986 }
4987
4988 default:
4989 auto last_token = get_token_string();
4990 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")));
4991 }
4992 }
4993
4994 /*!
4995 @param[out] result determined size
4996 @return whether size determination completed
4997 */
get_ubjson_size_value(std::size_t & result)4998 bool get_ubjson_size_value(std::size_t& result)
4999 {
5000 switch (get_ignore_noop())
5001 {
5002 case 'U':
5003 {
5004 std::uint8_t number;
5005 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5006 {
5007 return false;
5008 }
5009 result = static_cast<std::size_t>(number);
5010 return true;
5011 }
5012
5013 case 'i':
5014 {
5015 std::int8_t number;
5016 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5017 {
5018 return false;
5019 }
5020 result = static_cast<std::size_t>(number);
5021 return true;
5022 }
5023
5024 case 'I':
5025 {
5026 std::int16_t number;
5027 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5028 {
5029 return false;
5030 }
5031 result = static_cast<std::size_t>(number);
5032 return true;
5033 }
5034
5035 case 'l':
5036 {
5037 std::int32_t number;
5038 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5039 {
5040 return false;
5041 }
5042 result = static_cast<std::size_t>(number);
5043 return true;
5044 }
5045
5046 case 'L':
5047 {
5048 std::int64_t number;
5049 if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
5050 {
5051 return false;
5052 }
5053 result = static_cast<std::size_t>(number);
5054 return true;
5055 }
5056
5057 default:
5058 {
5059 auto last_token = get_token_string();
5060 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")));
5061 }
5062 }
5063 }
5064
5065 /*!
5066 @brief determine the type and size for a container
5067
5068 In the optimized UBJSON format, a type and a size can be provided to allow
5069 for a more compact representation.
5070
5071 @param[out] result pair of the size and the type
5072
5073 @return whether pair creation completed
5074 */
get_ubjson_size_type(std::pair<std::size_t,int> & result)5075 bool get_ubjson_size_type(std::pair<std::size_t, int>& result)
5076 {
5077 result.first = string_t::npos; // size
5078 result.second = 0; // type
5079
5080 get_ignore_noop();
5081
5082 if (current == '$')
5083 {
5084 result.second = get(); // must not ignore 'N', because 'N' maybe the type
5085 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
5086 {
5087 return false;
5088 }
5089
5090 get_ignore_noop();
5091 if (JSON_UNLIKELY(current != '#'))
5092 {
5093 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
5094 {
5095 return false;
5096 }
5097 auto last_token = get_token_string();
5098 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")));
5099 }
5100
5101 return get_ubjson_size_value(result.first);
5102 }
5103
5104 if (current == '#')
5105 {
5106 return get_ubjson_size_value(result.first);
5107 }
5108
5109 return true;
5110 }
5111
5112 /*!
5113 @param prefix the previously read or set type prefix
5114 @return whether value creation completed
5115 */
get_ubjson_value(const int prefix)5116 bool get_ubjson_value(const int prefix)
5117 {
5118 switch (prefix)
5119 {
5120 case std::char_traits<char>::eof(): // EOF
5121 return unexpect_eof(input_format_t::ubjson, "value");
5122
5123 case 'T': // true
5124 return sax->boolean(true);
5125 case 'F': // false
5126 return sax->boolean(false);
5127
5128 case 'Z': // null
5129 return sax->null();
5130
5131 case 'U':
5132 {
5133 std::uint8_t number;
5134 return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
5135 }
5136
5137 case 'i':
5138 {
5139 std::int8_t number;
5140 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5141 }
5142
5143 case 'I':
5144 {
5145 std::int16_t number;
5146 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5147 }
5148
5149 case 'l':
5150 {
5151 std::int32_t number;
5152 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5153 }
5154
5155 case 'L':
5156 {
5157 std::int64_t number;
5158 return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
5159 }
5160
5161 case 'd':
5162 {
5163 float number;
5164 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5165 }
5166
5167 case 'D':
5168 {
5169 double number;
5170 return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
5171 }
5172
5173 case 'C': // char
5174 {
5175 get();
5176 if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
5177 {
5178 return false;
5179 }
5180 if (JSON_UNLIKELY(current > 127))
5181 {
5182 auto last_token = get_token_string();
5183 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")));
5184 }
5185 string_t s(1, static_cast<char>(current));
5186 return sax->string(s);
5187 }
5188
5189 case 'S': // string
5190 {
5191 string_t s;
5192 return get_ubjson_string(s) and sax->string(s);
5193 }
5194
5195 case '[': // array
5196 return get_ubjson_array();
5197
5198 case '{': // object
5199 return get_ubjson_object();
5200
5201 default: // anything else
5202 {
5203 auto last_token = get_token_string();
5204 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")));
5205 }
5206 }
5207 }
5208
5209 /*!
5210 @return whether array creation completed
5211 */
get_ubjson_array()5212 bool get_ubjson_array()
5213 {
5214 std::pair<std::size_t, int> size_and_type;
5215 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
5216 {
5217 return false;
5218 }
5219
5220 if (size_and_type.first != string_t::npos)
5221 {
5222 if (JSON_UNLIKELY(not sax->start_array(size_and_type.first)))
5223 {
5224 return false;
5225 }
5226
5227 if (size_and_type.second != 0)
5228 {
5229 if (size_and_type.second != 'N')
5230 {
5231 for (std::size_t i = 0; i < size_and_type.first; ++i)
5232 {
5233 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
5234 {
5235 return false;
5236 }
5237 }
5238 }
5239 }
5240 else
5241 {
5242 for (std::size_t i = 0; i < size_and_type.first; ++i)
5243 {
5244 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5245 {
5246 return false;
5247 }
5248 }
5249 }
5250 }
5251 else
5252 {
5253 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
5254 {
5255 return false;
5256 }
5257
5258 while (current != ']')
5259 {
5260 if (JSON_UNLIKELY(not parse_ubjson_internal(false)))
5261 {
5262 return false;
5263 }
5264 get_ignore_noop();
5265 }
5266 }
5267
5268 return sax->end_array();
5269 }
5270
5271 /*!
5272 @return whether object creation completed
5273 */
get_ubjson_object()5274 bool get_ubjson_object()
5275 {
5276 std::pair<std::size_t, int> size_and_type;
5277 if (JSON_UNLIKELY(not get_ubjson_size_type(size_and_type)))
5278 {
5279 return false;
5280 }
5281
5282 string_t key;
5283 if (size_and_type.first != string_t::npos)
5284 {
5285 if (JSON_UNLIKELY(not sax->start_object(size_and_type.first)))
5286 {
5287 return false;
5288 }
5289
5290 if (size_and_type.second != 0)
5291 {
5292 for (std::size_t i = 0; i < size_and_type.first; ++i)
5293 {
5294 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
5295 {
5296 return false;
5297 }
5298 if (JSON_UNLIKELY(not get_ubjson_value(size_and_type.second)))
5299 {
5300 return false;
5301 }
5302 key.clear();
5303 }
5304 }
5305 else
5306 {
5307 for (std::size_t i = 0; i < size_and_type.first; ++i)
5308 {
5309 if (JSON_UNLIKELY(not get_ubjson_string(key) or not sax->key(key)))
5310 {
5311 return false;
5312 }
5313 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5314 {
5315 return false;
5316 }
5317 key.clear();
5318 }
5319 }
5320 }
5321 else
5322 {
5323 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
5324 {
5325 return false;
5326 }
5327
5328 while (current != '}')
5329 {
5330 if (JSON_UNLIKELY(not get_ubjson_string(key, false) or not sax->key(key)))
5331 {
5332 return false;
5333 }
5334 if (JSON_UNLIKELY(not parse_ubjson_internal()))
5335 {
5336 return false;
5337 }
5338 get_ignore_noop();
5339 key.clear();
5340 }
5341 }
5342
5343 return sax->end_object();
5344 }
5345
5346 ///////////////////////
5347 // Utility functions //
5348 ///////////////////////
5349
5350 /*!
5351 @brief get next character from the input
5352
5353 This function provides the interface to the used input adapter. It does
5354 not throw in case the input reached EOF, but returns a -'ve valued
5355 `std::char_traits<char>::eof()` in that case.
5356
5357 @return character read from the input
5358 */
get()5359 int get()
5360 {
5361 ++chars_read;
5362 return current = ia->get_character();
5363 }
5364
5365 /*!
5366 @return character read from the input after ignoring all 'N' entries
5367 */
get_ignore_noop()5368 int get_ignore_noop()
5369 {
5370 do
5371 {
5372 get();
5373 }
5374 while (current == 'N');
5375
5376 return current;
5377 }
5378
5379 /*
5380 @brief read a number from the input
5381
5382 @tparam NumberType the type of the number
5383 @param[in] format the current format (for diagnostics)
5384 @param[out] result number of type @a NumberType
5385
5386 @return whether conversion completed
5387
5388 @note This function needs to respect the system's endianess, because
5389 bytes in CBOR, MessagePack, and UBJSON are stored in network order
5390 (big endian) and therefore need reordering on little endian systems.
5391 */
5392 template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)5393 bool get_number(const input_format_t format, NumberType& result)
5394 {
5395 // step 1: read input into array with system's byte order
5396 std::array<std::uint8_t, sizeof(NumberType)> vec;
5397 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5398 {
5399 get();
5400 if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
5401 {
5402 return false;
5403 }
5404
5405 // reverse byte order prior to conversion if necessary
5406 if (is_little_endian != InputIsLittleEndian)
5407 {
5408 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
5409 }
5410 else
5411 {
5412 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
5413 }
5414 }
5415
5416 // step 2: convert array into number of type T and return
5417 std::memcpy(&result, vec.data(), sizeof(NumberType));
5418 return true;
5419 }
5420
5421 /*!
5422 @brief create a string by reading characters from the input
5423
5424 @tparam NumberType the type of the number
5425 @param[in] format the current format (for diagnostics)
5426 @param[in] len number of characters to read
5427 @param[out] result string created by reading @a len bytes
5428
5429 @return whether string creation completed
5430
5431 @note We can not reserve @a len bytes for the result, because @a len
5432 may be too large. Usually, @ref unexpect_eof() detects the end of
5433 the input before we run out of string memory.
5434 */
5435 template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)5436 bool get_string(const input_format_t format,
5437 const NumberType len,
5438 string_t& result)
5439 {
5440 bool success = true;
5441 std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
5442 {
5443 get();
5444 if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
5445 {
5446 success = false;
5447 }
5448 return static_cast<char>(current);
5449 });
5450 return success;
5451 }
5452
5453 /*!
5454 @param[in] format the current format (for diagnostics)
5455 @param[in] context further context information (for diagnostics)
5456 @return whether the last read character is not EOF
5457 */
unexpect_eof(const input_format_t format,const char * context) const5458 bool unexpect_eof(const input_format_t format, const char* context) const
5459 {
5460 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
5461 {
5462 return sax->parse_error(chars_read, "<end of file>",
5463 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
5464 }
5465 return true;
5466 }
5467
5468 /*!
5469 @return a string representation of the last read byte
5470 */
get_token_string() const5471 std::string get_token_string() const
5472 {
5473 std::array<char, 3> cr{{}};
5474 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current));
5475 return std::string{cr.data()};
5476 }
5477
5478 /*!
5479 @param[in] format the current format
5480 @param[in] detail a detailed error message
5481 @param[in] context further contect information
5482 @return a message string to use in the parse_error exceptions
5483 */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const5484 std::string exception_message(const input_format_t format,
5485 const std::string& detail,
5486 const std::string& context) const
5487 {
5488 std::string error_msg = "syntax error while parsing ";
5489
5490 switch (format)
5491 {
5492 case input_format_t::cbor:
5493 error_msg += "CBOR";
5494 break;
5495
5496 case input_format_t::msgpack:
5497 error_msg += "MessagePack";
5498 break;
5499
5500 case input_format_t::ubjson:
5501 error_msg += "UBJSON";
5502 break;
5503
5504 case input_format_t::bson:
5505 error_msg += "BSON";
5506 break;
5507
5508 default: // LCOV_EXCL_LINE
5509 assert(false); // LCOV_EXCL_LINE
5510 }
5511
5512 return error_msg + " " + context + ": " + detail;
5513 }
5514
5515 private:
5516 /// input adapter
5517 input_adapter_t ia = nullptr;
5518
5519 /// the current character
5520 int current = std::char_traits<char>::eof();
5521
5522 /// the number of characters read
5523 std::size_t chars_read = 0;
5524
5525 /// whether we can assume little endianess
5526 const bool is_little_endian = little_endianess();
5527
5528 /// the SAX parser
5529 json_sax_t* sax = nullptr;
5530 };
5531 } // namespace detail
5532 } // namespace nlohmann
5533
5534 // #include <nlohmann/detail/input/input_adapters.hpp>
5535
5536 // #include <nlohmann/detail/input/lexer.hpp>
5537
5538
5539 #include <array> // array
5540 #include <clocale> // localeconv
5541 #include <cstddef> // size_t
5542 #include <cstdio> // snprintf
5543 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
5544 #include <initializer_list> // initializer_list
5545 #include <string> // char_traits, string
5546 #include <utility> // move
5547 #include <vector> // vector
5548
5549 // #include <nlohmann/detail/input/input_adapters.hpp>
5550
5551 // #include <nlohmann/detail/input/position_t.hpp>
5552
5553 // #include <nlohmann/detail/macro_scope.hpp>
5554
5555
5556 namespace nlohmann
5557 {
5558 namespace detail
5559 {
5560 ///////////
5561 // lexer //
5562 ///////////
5563
5564 /*!
5565 @brief lexical analysis
5566
5567 This class organizes the lexical analysis during JSON deserialization.
5568 */
5569 template<typename BasicJsonType>
5570 class lexer
5571 {
5572 using number_integer_t = typename BasicJsonType::number_integer_t;
5573 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5574 using number_float_t = typename BasicJsonType::number_float_t;
5575 using string_t = typename BasicJsonType::string_t;
5576
5577 public:
5578 /// token types for the parser
5579 enum class token_type
5580 {
5581 uninitialized, ///< indicating the scanner is uninitialized
5582 literal_true, ///< the `true` literal
5583 literal_false, ///< the `false` literal
5584 literal_null, ///< the `null` literal
5585 value_string, ///< a string -- use get_string() for actual value
5586 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
5587 value_integer, ///< a signed integer -- use get_number_integer() for actual value
5588 value_float, ///< an floating point number -- use get_number_float() for actual value
5589 begin_array, ///< the character for array begin `[`
5590 begin_object, ///< the character for object begin `{`
5591 end_array, ///< the character for array end `]`
5592 end_object, ///< the character for object end `}`
5593 name_separator, ///< the name separator `:`
5594 value_separator, ///< the value separator `,`
5595 parse_error, ///< indicating a parse error
5596 end_of_input, ///< indicating the end of the input buffer
5597 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
5598 };
5599
5600 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)5601 static const char* token_type_name(const token_type t) noexcept
5602 {
5603 switch (t)
5604 {
5605 case token_type::uninitialized:
5606 return "<uninitialized>";
5607 case token_type::literal_true:
5608 return "true literal";
5609 case token_type::literal_false:
5610 return "false literal";
5611 case token_type::literal_null:
5612 return "null literal";
5613 case token_type::value_string:
5614 return "string literal";
5615 case lexer::token_type::value_unsigned:
5616 case lexer::token_type::value_integer:
5617 case lexer::token_type::value_float:
5618 return "number literal";
5619 case token_type::begin_array:
5620 return "'['";
5621 case token_type::begin_object:
5622 return "'{'";
5623 case token_type::end_array:
5624 return "']'";
5625 case token_type::end_object:
5626 return "'}'";
5627 case token_type::name_separator:
5628 return "':'";
5629 case token_type::value_separator:
5630 return "','";
5631 case token_type::parse_error:
5632 return "<parse error>";
5633 case token_type::end_of_input:
5634 return "end of input";
5635 case token_type::literal_or_value:
5636 return "'[', '{', or a literal";
5637 // LCOV_EXCL_START
5638 default: // catch non-enum values
5639 return "unknown token";
5640 // LCOV_EXCL_STOP
5641 }
5642 }
5643
lexer(detail::input_adapter_t && adapter)5644 explicit lexer(detail::input_adapter_t&& adapter)
5645 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
5646
5647 // delete because of pointer members
5648 lexer(const lexer&) = delete;
5649 lexer(lexer&&) = delete;
5650 lexer& operator=(lexer&) = delete;
5651 lexer& operator=(lexer&&) = delete;
5652 ~lexer() = default;
5653
5654 private:
5655 /////////////////////
5656 // locales
5657 /////////////////////
5658
5659 /// return the locale-dependent decimal point
get_decimal_point()5660 static char get_decimal_point() noexcept
5661 {
5662 const auto loc = localeconv();
5663 assert(loc != nullptr);
5664 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
5665 }
5666
5667 /////////////////////
5668 // scan functions
5669 /////////////////////
5670
5671 /*!
5672 @brief get codepoint from 4 hex characters following `\u`
5673
5674 For input "\u c1 c2 c3 c4" the codepoint is:
5675 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
5676 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
5677
5678 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
5679 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
5680 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
5681 between the ASCII value of the character and the desired integer value.
5682
5683 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
5684 non-hex character)
5685 */
get_codepoint()5686 int get_codepoint()
5687 {
5688 // this function only makes sense after reading `\u`
5689 assert(current == 'u');
5690 int codepoint = 0;
5691
5692 const auto factors = { 12u, 8u, 4u, 0u };
5693 for (const auto factor : factors)
5694 {
5695 get();
5696
5697 if (current >= '0' and current <= '9')
5698 {
5699 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
5700 }
5701 else if (current >= 'A' and current <= 'F')
5702 {
5703 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
5704 }
5705 else if (current >= 'a' and current <= 'f')
5706 {
5707 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
5708 }
5709 else
5710 {
5711 return -1;
5712 }
5713 }
5714
5715 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
5716 return codepoint;
5717 }
5718
5719 /*!
5720 @brief check if the next byte(s) are inside a given range
5721
5722 Adds the current byte and, for each passed range, reads a new byte and
5723 checks if it is inside the range. If a violation was detected, set up an
5724 error message and return false. Otherwise, return true.
5725
5726 @param[in] ranges list of integers; interpreted as list of pairs of
5727 inclusive lower and upper bound, respectively
5728
5729 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
5730 1, 2, or 3 pairs. This precondition is enforced by an assertion.
5731
5732 @return true if and only if no range violation was detected
5733 */
next_byte_in_range(std::initializer_list<int> ranges)5734 bool next_byte_in_range(std::initializer_list<int> ranges)
5735 {
5736 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
5737 add(current);
5738
5739 for (auto range = ranges.begin(); range != ranges.end(); ++range)
5740 {
5741 get();
5742 if (JSON_LIKELY(*range <= current and current <= *(++range)))
5743 {
5744 add(current);
5745 }
5746 else
5747 {
5748 error_message = "invalid string: ill-formed UTF-8 byte";
5749 return false;
5750 }
5751 }
5752
5753 return true;
5754 }
5755
5756 /*!
5757 @brief scan a string literal
5758
5759 This function scans a string according to Sect. 7 of RFC 7159. While
5760 scanning, bytes are escaped and copied into buffer token_buffer. Then the
5761 function returns successfully, token_buffer is *not* null-terminated (as it
5762 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
5763 string.
5764
5765 @return token_type::value_string if string could be successfully scanned,
5766 token_type::parse_error otherwise
5767
5768 @note In case of errors, variable error_message contains a textual
5769 description.
5770 */
scan_string()5771 token_type scan_string()
5772 {
5773 // reset token_buffer (ignore opening quote)
5774 reset();
5775
5776 // we entered the function by reading an open quote
5777 assert(current == '\"');
5778
5779 while (true)
5780 {
5781 // get next character
5782 switch (get())
5783 {
5784 // end of file while parsing string
5785 case std::char_traits<char>::eof():
5786 {
5787 error_message = "invalid string: missing closing quote";
5788 return token_type::parse_error;
5789 }
5790
5791 // closing quote
5792 case '\"':
5793 {
5794 return token_type::value_string;
5795 }
5796
5797 // escapes
5798 case '\\':
5799 {
5800 switch (get())
5801 {
5802 // quotation mark
5803 case '\"':
5804 add('\"');
5805 break;
5806 // reverse solidus
5807 case '\\':
5808 add('\\');
5809 break;
5810 // solidus
5811 case '/':
5812 add('/');
5813 break;
5814 // backspace
5815 case 'b':
5816 add('\b');
5817 break;
5818 // form feed
5819 case 'f':
5820 add('\f');
5821 break;
5822 // line feed
5823 case 'n':
5824 add('\n');
5825 break;
5826 // carriage return
5827 case 'r':
5828 add('\r');
5829 break;
5830 // tab
5831 case 't':
5832 add('\t');
5833 break;
5834
5835 // unicode escapes
5836 case 'u':
5837 {
5838 const int codepoint1 = get_codepoint();
5839 int codepoint = codepoint1; // start with codepoint1
5840
5841 if (JSON_UNLIKELY(codepoint1 == -1))
5842 {
5843 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5844 return token_type::parse_error;
5845 }
5846
5847 // check if code point is a high surrogate
5848 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
5849 {
5850 // expect next \uxxxx entry
5851 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
5852 {
5853 const int codepoint2 = get_codepoint();
5854
5855 if (JSON_UNLIKELY(codepoint2 == -1))
5856 {
5857 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
5858 return token_type::parse_error;
5859 }
5860
5861 // check if codepoint2 is a low surrogate
5862 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
5863 {
5864 // overwrite codepoint
5865 codepoint = static_cast<int>(
5866 // high surrogate occupies the most significant 22 bits
5867 (static_cast<unsigned int>(codepoint1) << 10u)
5868 // low surrogate occupies the least significant 15 bits
5869 + static_cast<unsigned int>(codepoint2)
5870 // there is still the 0xD800, 0xDC00 and 0x10000 noise
5871 // in the result so we have to subtract with:
5872 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
5873 - 0x35FDC00u);
5874 }
5875 else
5876 {
5877 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5878 return token_type::parse_error;
5879 }
5880 }
5881 else
5882 {
5883 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
5884 return token_type::parse_error;
5885 }
5886 }
5887 else
5888 {
5889 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
5890 {
5891 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
5892 return token_type::parse_error;
5893 }
5894 }
5895
5896 // result of the above calculation yields a proper codepoint
5897 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
5898
5899 // translate codepoint into bytes
5900 if (codepoint < 0x80)
5901 {
5902 // 1-byte characters: 0xxxxxxx (ASCII)
5903 add(codepoint);
5904 }
5905 else if (codepoint <= 0x7FF)
5906 {
5907 // 2-byte characters: 110xxxxx 10xxxxxx
5908 add(static_cast<int>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
5909 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5910 }
5911 else if (codepoint <= 0xFFFF)
5912 {
5913 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
5914 add(static_cast<int>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
5915 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5916 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5917 }
5918 else
5919 {
5920 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5921 add(static_cast<int>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
5922 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
5923 add(static_cast<int>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
5924 add(static_cast<int>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
5925 }
5926
5927 break;
5928 }
5929
5930 // other characters after escape
5931 default:
5932 error_message = "invalid string: forbidden character after backslash";
5933 return token_type::parse_error;
5934 }
5935
5936 break;
5937 }
5938
5939 // invalid control characters
5940 case 0x00:
5941 {
5942 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
5943 return token_type::parse_error;
5944 }
5945
5946 case 0x01:
5947 {
5948 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
5949 return token_type::parse_error;
5950 }
5951
5952 case 0x02:
5953 {
5954 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
5955 return token_type::parse_error;
5956 }
5957
5958 case 0x03:
5959 {
5960 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
5961 return token_type::parse_error;
5962 }
5963
5964 case 0x04:
5965 {
5966 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
5967 return token_type::parse_error;
5968 }
5969
5970 case 0x05:
5971 {
5972 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
5973 return token_type::parse_error;
5974 }
5975
5976 case 0x06:
5977 {
5978 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
5979 return token_type::parse_error;
5980 }
5981
5982 case 0x07:
5983 {
5984 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
5985 return token_type::parse_error;
5986 }
5987
5988 case 0x08:
5989 {
5990 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
5991 return token_type::parse_error;
5992 }
5993
5994 case 0x09:
5995 {
5996 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
5997 return token_type::parse_error;
5998 }
5999
6000 case 0x0A:
6001 {
6002 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6003 return token_type::parse_error;
6004 }
6005
6006 case 0x0B:
6007 {
6008 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6009 return token_type::parse_error;
6010 }
6011
6012 case 0x0C:
6013 {
6014 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6015 return token_type::parse_error;
6016 }
6017
6018 case 0x0D:
6019 {
6020 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6021 return token_type::parse_error;
6022 }
6023
6024 case 0x0E:
6025 {
6026 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6027 return token_type::parse_error;
6028 }
6029
6030 case 0x0F:
6031 {
6032 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6033 return token_type::parse_error;
6034 }
6035
6036 case 0x10:
6037 {
6038 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6039 return token_type::parse_error;
6040 }
6041
6042 case 0x11:
6043 {
6044 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6045 return token_type::parse_error;
6046 }
6047
6048 case 0x12:
6049 {
6050 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6051 return token_type::parse_error;
6052 }
6053
6054 case 0x13:
6055 {
6056 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6057 return token_type::parse_error;
6058 }
6059
6060 case 0x14:
6061 {
6062 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6063 return token_type::parse_error;
6064 }
6065
6066 case 0x15:
6067 {
6068 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6069 return token_type::parse_error;
6070 }
6071
6072 case 0x16:
6073 {
6074 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6075 return token_type::parse_error;
6076 }
6077
6078 case 0x17:
6079 {
6080 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6081 return token_type::parse_error;
6082 }
6083
6084 case 0x18:
6085 {
6086 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6087 return token_type::parse_error;
6088 }
6089
6090 case 0x19:
6091 {
6092 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6093 return token_type::parse_error;
6094 }
6095
6096 case 0x1A:
6097 {
6098 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6099 return token_type::parse_error;
6100 }
6101
6102 case 0x1B:
6103 {
6104 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6105 return token_type::parse_error;
6106 }
6107
6108 case 0x1C:
6109 {
6110 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6111 return token_type::parse_error;
6112 }
6113
6114 case 0x1D:
6115 {
6116 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
6117 return token_type::parse_error;
6118 }
6119
6120 case 0x1E:
6121 {
6122 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
6123 return token_type::parse_error;
6124 }
6125
6126 case 0x1F:
6127 {
6128 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
6129 return token_type::parse_error;
6130 }
6131
6132 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
6133 case 0x20:
6134 case 0x21:
6135 case 0x23:
6136 case 0x24:
6137 case 0x25:
6138 case 0x26:
6139 case 0x27:
6140 case 0x28:
6141 case 0x29:
6142 case 0x2A:
6143 case 0x2B:
6144 case 0x2C:
6145 case 0x2D:
6146 case 0x2E:
6147 case 0x2F:
6148 case 0x30:
6149 case 0x31:
6150 case 0x32:
6151 case 0x33:
6152 case 0x34:
6153 case 0x35:
6154 case 0x36:
6155 case 0x37:
6156 case 0x38:
6157 case 0x39:
6158 case 0x3A:
6159 case 0x3B:
6160 case 0x3C:
6161 case 0x3D:
6162 case 0x3E:
6163 case 0x3F:
6164 case 0x40:
6165 case 0x41:
6166 case 0x42:
6167 case 0x43:
6168 case 0x44:
6169 case 0x45:
6170 case 0x46:
6171 case 0x47:
6172 case 0x48:
6173 case 0x49:
6174 case 0x4A:
6175 case 0x4B:
6176 case 0x4C:
6177 case 0x4D:
6178 case 0x4E:
6179 case 0x4F:
6180 case 0x50:
6181 case 0x51:
6182 case 0x52:
6183 case 0x53:
6184 case 0x54:
6185 case 0x55:
6186 case 0x56:
6187 case 0x57:
6188 case 0x58:
6189 case 0x59:
6190 case 0x5A:
6191 case 0x5B:
6192 case 0x5D:
6193 case 0x5E:
6194 case 0x5F:
6195 case 0x60:
6196 case 0x61:
6197 case 0x62:
6198 case 0x63:
6199 case 0x64:
6200 case 0x65:
6201 case 0x66:
6202 case 0x67:
6203 case 0x68:
6204 case 0x69:
6205 case 0x6A:
6206 case 0x6B:
6207 case 0x6C:
6208 case 0x6D:
6209 case 0x6E:
6210 case 0x6F:
6211 case 0x70:
6212 case 0x71:
6213 case 0x72:
6214 case 0x73:
6215 case 0x74:
6216 case 0x75:
6217 case 0x76:
6218 case 0x77:
6219 case 0x78:
6220 case 0x79:
6221 case 0x7A:
6222 case 0x7B:
6223 case 0x7C:
6224 case 0x7D:
6225 case 0x7E:
6226 case 0x7F:
6227 {
6228 add(current);
6229 break;
6230 }
6231
6232 // U+0080..U+07FF: bytes C2..DF 80..BF
6233 case 0xC2:
6234 case 0xC3:
6235 case 0xC4:
6236 case 0xC5:
6237 case 0xC6:
6238 case 0xC7:
6239 case 0xC8:
6240 case 0xC9:
6241 case 0xCA:
6242 case 0xCB:
6243 case 0xCC:
6244 case 0xCD:
6245 case 0xCE:
6246 case 0xCF:
6247 case 0xD0:
6248 case 0xD1:
6249 case 0xD2:
6250 case 0xD3:
6251 case 0xD4:
6252 case 0xD5:
6253 case 0xD6:
6254 case 0xD7:
6255 case 0xD8:
6256 case 0xD9:
6257 case 0xDA:
6258 case 0xDB:
6259 case 0xDC:
6260 case 0xDD:
6261 case 0xDE:
6262 case 0xDF:
6263 {
6264 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
6265 {
6266 return token_type::parse_error;
6267 }
6268 break;
6269 }
6270
6271 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
6272 case 0xE0:
6273 {
6274 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
6275 {
6276 return token_type::parse_error;
6277 }
6278 break;
6279 }
6280
6281 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
6282 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
6283 case 0xE1:
6284 case 0xE2:
6285 case 0xE3:
6286 case 0xE4:
6287 case 0xE5:
6288 case 0xE6:
6289 case 0xE7:
6290 case 0xE8:
6291 case 0xE9:
6292 case 0xEA:
6293 case 0xEB:
6294 case 0xEC:
6295 case 0xEE:
6296 case 0xEF:
6297 {
6298 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
6299 {
6300 return token_type::parse_error;
6301 }
6302 break;
6303 }
6304
6305 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
6306 case 0xED:
6307 {
6308 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
6309 {
6310 return token_type::parse_error;
6311 }
6312 break;
6313 }
6314
6315 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
6316 case 0xF0:
6317 {
6318 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6319 {
6320 return token_type::parse_error;
6321 }
6322 break;
6323 }
6324
6325 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
6326 case 0xF1:
6327 case 0xF2:
6328 case 0xF3:
6329 {
6330 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
6331 {
6332 return token_type::parse_error;
6333 }
6334 break;
6335 }
6336
6337 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
6338 case 0xF4:
6339 {
6340 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
6341 {
6342 return token_type::parse_error;
6343 }
6344 break;
6345 }
6346
6347 // remaining bytes (80..C1 and F5..FF) are ill-formed
6348 default:
6349 {
6350 error_message = "invalid string: ill-formed UTF-8 byte";
6351 return token_type::parse_error;
6352 }
6353 }
6354 }
6355 }
6356
strtof(float & f,const char * str,char ** endptr)6357 static void strtof(float& f, const char* str, char** endptr) noexcept
6358 {
6359 f = std::strtof(str, endptr);
6360 }
6361
strtof(double & f,const char * str,char ** endptr)6362 static void strtof(double& f, const char* str, char** endptr) noexcept
6363 {
6364 f = std::strtod(str, endptr);
6365 }
6366
strtof(long double & f,const char * str,char ** endptr)6367 static void strtof(long double& f, const char* str, char** endptr) noexcept
6368 {
6369 f = std::strtold(str, endptr);
6370 }
6371
6372 /*!
6373 @brief scan a number literal
6374
6375 This function scans a string according to Sect. 6 of RFC 7159.
6376
6377 The function is realized with a deterministic finite state machine derived
6378 from the grammar described in RFC 7159. Starting in state "init", the
6379 input is read and used to determined the next state. Only state "done"
6380 accepts the number. State "error" is a trap state to model errors. In the
6381 table below, "anything" means any character but the ones listed before.
6382
6383 state | 0 | 1-9 | e E | + | - | . | anything
6384 ---------|----------|----------|----------|---------|---------|----------|-----------
6385 init | zero | any1 | [error] | [error] | minus | [error] | [error]
6386 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
6387 zero | done | done | exponent | done | done | decimal1 | done
6388 any1 | any1 | any1 | exponent | done | done | decimal1 | done
6389 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
6390 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
6391 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
6392 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
6393 any2 | any2 | any2 | done | done | done | done | done
6394
6395 The state machine is realized with one label per state (prefixed with
6396 "scan_number_") and `goto` statements between them. The state machine
6397 contains cycles, but any cycle can be left when EOF is read. Therefore,
6398 the function is guaranteed to terminate.
6399
6400 During scanning, the read bytes are stored in token_buffer. This string is
6401 then converted to a signed integer, an unsigned integer, or a
6402 floating-point number.
6403
6404 @return token_type::value_unsigned, token_type::value_integer, or
6405 token_type::value_float if number could be successfully scanned,
6406 token_type::parse_error otherwise
6407
6408 @note The scanner is independent of the current locale. Internally, the
6409 locale's decimal point is used instead of `.` to work with the
6410 locale-dependent converters.
6411 */
scan_number()6412 token_type scan_number() // lgtm [cpp/use-of-goto]
6413 {
6414 // reset token_buffer to store the number's bytes
6415 reset();
6416
6417 // the type of the parsed number; initially set to unsigned; will be
6418 // changed if minus sign, decimal point or exponent is read
6419 token_type number_type = token_type::value_unsigned;
6420
6421 // state (init): we just found out we need to scan a number
6422 switch (current)
6423 {
6424 case '-':
6425 {
6426 add(current);
6427 goto scan_number_minus;
6428 }
6429
6430 case '0':
6431 {
6432 add(current);
6433 goto scan_number_zero;
6434 }
6435
6436 case '1':
6437 case '2':
6438 case '3':
6439 case '4':
6440 case '5':
6441 case '6':
6442 case '7':
6443 case '8':
6444 case '9':
6445 {
6446 add(current);
6447 goto scan_number_any1;
6448 }
6449
6450 // all other characters are rejected outside scan_number()
6451 default: // LCOV_EXCL_LINE
6452 assert(false); // LCOV_EXCL_LINE
6453 }
6454
6455 scan_number_minus:
6456 // state: we just parsed a leading minus sign
6457 number_type = token_type::value_integer;
6458 switch (get())
6459 {
6460 case '0':
6461 {
6462 add(current);
6463 goto scan_number_zero;
6464 }
6465
6466 case '1':
6467 case '2':
6468 case '3':
6469 case '4':
6470 case '5':
6471 case '6':
6472 case '7':
6473 case '8':
6474 case '9':
6475 {
6476 add(current);
6477 goto scan_number_any1;
6478 }
6479
6480 default:
6481 {
6482 error_message = "invalid number; expected digit after '-'";
6483 return token_type::parse_error;
6484 }
6485 }
6486
6487 scan_number_zero:
6488 // state: we just parse a zero (maybe with a leading minus sign)
6489 switch (get())
6490 {
6491 case '.':
6492 {
6493 add(decimal_point_char);
6494 goto scan_number_decimal1;
6495 }
6496
6497 case 'e':
6498 case 'E':
6499 {
6500 add(current);
6501 goto scan_number_exponent;
6502 }
6503
6504 default:
6505 goto scan_number_done;
6506 }
6507
6508 scan_number_any1:
6509 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
6510 switch (get())
6511 {
6512 case '0':
6513 case '1':
6514 case '2':
6515 case '3':
6516 case '4':
6517 case '5':
6518 case '6':
6519 case '7':
6520 case '8':
6521 case '9':
6522 {
6523 add(current);
6524 goto scan_number_any1;
6525 }
6526
6527 case '.':
6528 {
6529 add(decimal_point_char);
6530 goto scan_number_decimal1;
6531 }
6532
6533 case 'e':
6534 case 'E':
6535 {
6536 add(current);
6537 goto scan_number_exponent;
6538 }
6539
6540 default:
6541 goto scan_number_done;
6542 }
6543
6544 scan_number_decimal1:
6545 // state: we just parsed a decimal point
6546 number_type = token_type::value_float;
6547 switch (get())
6548 {
6549 case '0':
6550 case '1':
6551 case '2':
6552 case '3':
6553 case '4':
6554 case '5':
6555 case '6':
6556 case '7':
6557 case '8':
6558 case '9':
6559 {
6560 add(current);
6561 goto scan_number_decimal2;
6562 }
6563
6564 default:
6565 {
6566 error_message = "invalid number; expected digit after '.'";
6567 return token_type::parse_error;
6568 }
6569 }
6570
6571 scan_number_decimal2:
6572 // we just parsed at least one number after a decimal point
6573 switch (get())
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_decimal2;
6588 }
6589
6590 case 'e':
6591 case 'E':
6592 {
6593 add(current);
6594 goto scan_number_exponent;
6595 }
6596
6597 default:
6598 goto scan_number_done;
6599 }
6600
6601 scan_number_exponent:
6602 // we just parsed an exponent
6603 number_type = token_type::value_float;
6604 switch (get())
6605 {
6606 case '+':
6607 case '-':
6608 {
6609 add(current);
6610 goto scan_number_sign;
6611 }
6612
6613 case '0':
6614 case '1':
6615 case '2':
6616 case '3':
6617 case '4':
6618 case '5':
6619 case '6':
6620 case '7':
6621 case '8':
6622 case '9':
6623 {
6624 add(current);
6625 goto scan_number_any2;
6626 }
6627
6628 default:
6629 {
6630 error_message =
6631 "invalid number; expected '+', '-', or digit after exponent";
6632 return token_type::parse_error;
6633 }
6634 }
6635
6636 scan_number_sign:
6637 // we just parsed an exponent sign
6638 switch (get())
6639 {
6640 case '0':
6641 case '1':
6642 case '2':
6643 case '3':
6644 case '4':
6645 case '5':
6646 case '6':
6647 case '7':
6648 case '8':
6649 case '9':
6650 {
6651 add(current);
6652 goto scan_number_any2;
6653 }
6654
6655 default:
6656 {
6657 error_message = "invalid number; expected digit after exponent sign";
6658 return token_type::parse_error;
6659 }
6660 }
6661
6662 scan_number_any2:
6663 // we just parsed a number after the exponent or exponent sign
6664 switch (get())
6665 {
6666 case '0':
6667 case '1':
6668 case '2':
6669 case '3':
6670 case '4':
6671 case '5':
6672 case '6':
6673 case '7':
6674 case '8':
6675 case '9':
6676 {
6677 add(current);
6678 goto scan_number_any2;
6679 }
6680
6681 default:
6682 goto scan_number_done;
6683 }
6684
6685 scan_number_done:
6686 // unget the character after the number (we only read it to know that
6687 // we are done scanning a number)
6688 unget();
6689
6690 char* endptr = nullptr;
6691 errno = 0;
6692
6693 // try to parse integers first and fall back to floats
6694 if (number_type == token_type::value_unsigned)
6695 {
6696 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
6697
6698 // we checked the number format before
6699 assert(endptr == token_buffer.data() + token_buffer.size());
6700
6701 if (errno == 0)
6702 {
6703 value_unsigned = static_cast<number_unsigned_t>(x);
6704 if (value_unsigned == x)
6705 {
6706 return token_type::value_unsigned;
6707 }
6708 }
6709 }
6710 else if (number_type == token_type::value_integer)
6711 {
6712 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
6713
6714 // we checked the number format before
6715 assert(endptr == token_buffer.data() + token_buffer.size());
6716
6717 if (errno == 0)
6718 {
6719 value_integer = static_cast<number_integer_t>(x);
6720 if (value_integer == x)
6721 {
6722 return token_type::value_integer;
6723 }
6724 }
6725 }
6726
6727 // this code is reached if we parse a floating-point number or if an
6728 // integer conversion above failed
6729 strtof(value_float, token_buffer.data(), &endptr);
6730
6731 // we checked the number format before
6732 assert(endptr == token_buffer.data() + token_buffer.size());
6733
6734 return token_type::value_float;
6735 }
6736
6737 /*!
6738 @param[in] literal_text the literal text to expect
6739 @param[in] length the length of the passed literal text
6740 @param[in] return_type the token type to return on success
6741 */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)6742 token_type scan_literal(const char* literal_text, const std::size_t length,
6743 token_type return_type)
6744 {
6745 assert(current == literal_text[0]);
6746 for (std::size_t i = 1; i < length; ++i)
6747 {
6748 if (JSON_UNLIKELY(get() != literal_text[i]))
6749 {
6750 error_message = "invalid literal";
6751 return token_type::parse_error;
6752 }
6753 }
6754 return return_type;
6755 }
6756
6757 /////////////////////
6758 // input management
6759 /////////////////////
6760
6761 /// reset token_buffer; current character is beginning of token
reset()6762 void reset() noexcept
6763 {
6764 token_buffer.clear();
6765 token_string.clear();
6766 token_string.push_back(std::char_traits<char>::to_char_type(current));
6767 }
6768
6769 /*
6770 @brief get next character from the input
6771
6772 This function provides the interface to the used input adapter. It does
6773 not throw in case the input reached EOF, but returns a
6774 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
6775 for use in error messages.
6776
6777 @return character read from the input
6778 */
get()6779 std::char_traits<char>::int_type get()
6780 {
6781 ++position.chars_read_total;
6782 ++position.chars_read_current_line;
6783
6784 if (next_unget)
6785 {
6786 // just reset the next_unget variable and work with current
6787 next_unget = false;
6788 }
6789 else
6790 {
6791 current = ia->get_character();
6792 }
6793
6794 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6795 {
6796 token_string.push_back(std::char_traits<char>::to_char_type(current));
6797 }
6798
6799 if (current == '\n')
6800 {
6801 ++position.lines_read;
6802 position.chars_read_current_line = 0;
6803 }
6804
6805 return current;
6806 }
6807
6808 /*!
6809 @brief unget current character (read it again on next get)
6810
6811 We implement unget by setting variable next_unget to true. The input is not
6812 changed - we just simulate ungetting by modifying chars_read_total,
6813 chars_read_current_line, and token_string. The next call to get() will
6814 behave as if the unget character is read again.
6815 */
unget()6816 void unget()
6817 {
6818 next_unget = true;
6819
6820 --position.chars_read_total;
6821
6822 // in case we "unget" a newline, we have to also decrement the lines_read
6823 if (position.chars_read_current_line == 0)
6824 {
6825 if (position.lines_read > 0)
6826 {
6827 --position.lines_read;
6828 }
6829 }
6830 else
6831 {
6832 --position.chars_read_current_line;
6833 }
6834
6835 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
6836 {
6837 assert(not token_string.empty());
6838 token_string.pop_back();
6839 }
6840 }
6841
6842 /// add a character to token_buffer
add(int c)6843 void add(int c)
6844 {
6845 token_buffer.push_back(std::char_traits<char>::to_char_type(c));
6846 }
6847
6848 public:
6849 /////////////////////
6850 // value getters
6851 /////////////////////
6852
6853 /// return integer value
get_number_integer() const6854 constexpr number_integer_t get_number_integer() const noexcept
6855 {
6856 return value_integer;
6857 }
6858
6859 /// return unsigned integer value
get_number_unsigned() const6860 constexpr number_unsigned_t get_number_unsigned() const noexcept
6861 {
6862 return value_unsigned;
6863 }
6864
6865 /// return floating-point value
get_number_float() const6866 constexpr number_float_t get_number_float() const noexcept
6867 {
6868 return value_float;
6869 }
6870
6871 /// return current string value (implicitly resets the token; useful only once)
get_string()6872 string_t& get_string()
6873 {
6874 return token_buffer;
6875 }
6876
6877 /////////////////////
6878 // diagnostics
6879 /////////////////////
6880
6881 /// return position of last read token
get_position() const6882 constexpr position_t get_position() const noexcept
6883 {
6884 return position;
6885 }
6886
6887 /// return the last read token (for errors only). Will never contain EOF
6888 /// (an arbitrary value that is not a valid char value, often -1), because
6889 /// 255 may legitimately occur. May contain NUL, which should be escaped.
get_token_string() const6890 std::string get_token_string() const
6891 {
6892 // escape control characters
6893 std::string result;
6894 for (const auto c : token_string)
6895 {
6896 if ('\x00' <= c and c <= '\x1F')
6897 {
6898 // escape control characters
6899 std::array<char, 9> cs{{}};
6900 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c));
6901 result += cs.data();
6902 }
6903 else
6904 {
6905 // add character as is
6906 result.push_back(c);
6907 }
6908 }
6909
6910 return result;
6911 }
6912
6913 /// return syntax error message
get_error_message() const6914 constexpr const char* get_error_message() const noexcept
6915 {
6916 return error_message;
6917 }
6918
6919 /////////////////////
6920 // actual scanner
6921 /////////////////////
6922
6923 /*!
6924 @brief skip the UTF-8 byte order mark
6925 @return true iff there is no BOM or the correct BOM has been skipped
6926 */
skip_bom()6927 bool skip_bom()
6928 {
6929 if (get() == 0xEF)
6930 {
6931 // check if we completely parse the BOM
6932 return get() == 0xBB and get() == 0xBF;
6933 }
6934
6935 // the first character is not the beginning of the BOM; unget it to
6936 // process is later
6937 unget();
6938 return true;
6939 }
6940
scan()6941 token_type scan()
6942 {
6943 // initially, skip the BOM
6944 if (position.chars_read_total == 0 and not skip_bom())
6945 {
6946 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
6947 return token_type::parse_error;
6948 }
6949
6950 // read next character and ignore whitespace
6951 do
6952 {
6953 get();
6954 }
6955 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
6956
6957 switch (current)
6958 {
6959 // structural characters
6960 case '[':
6961 return token_type::begin_array;
6962 case ']':
6963 return token_type::end_array;
6964 case '{':
6965 return token_type::begin_object;
6966 case '}':
6967 return token_type::end_object;
6968 case ':':
6969 return token_type::name_separator;
6970 case ',':
6971 return token_type::value_separator;
6972
6973 // literals
6974 case 't':
6975 return scan_literal("true", 4, token_type::literal_true);
6976 case 'f':
6977 return scan_literal("false", 5, token_type::literal_false);
6978 case 'n':
6979 return scan_literal("null", 4, token_type::literal_null);
6980
6981 // string
6982 case '\"':
6983 return scan_string();
6984
6985 // number
6986 case '-':
6987 case '0':
6988 case '1':
6989 case '2':
6990 case '3':
6991 case '4':
6992 case '5':
6993 case '6':
6994 case '7':
6995 case '8':
6996 case '9':
6997 return scan_number();
6998
6999 // end of input (the null byte is needed when parsing from
7000 // string literals)
7001 case '\0':
7002 case std::char_traits<char>::eof():
7003 return token_type::end_of_input;
7004
7005 // error
7006 default:
7007 error_message = "invalid literal";
7008 return token_type::parse_error;
7009 }
7010 }
7011
7012 private:
7013 /// input adapter
7014 detail::input_adapter_t ia = nullptr;
7015
7016 /// the current character
7017 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
7018
7019 /// whether the next get() call should just return current
7020 bool next_unget = false;
7021
7022 /// the start position of the current token
7023 position_t position {};
7024
7025 /// raw input token string (for error messages)
7026 std::vector<char> token_string {};
7027
7028 /// buffer for variable-length tokens (numbers, strings)
7029 string_t token_buffer {};
7030
7031 /// a description of occurred lexer errors
7032 const char* error_message = "";
7033
7034 // number values
7035 number_integer_t value_integer = 0;
7036 number_unsigned_t value_unsigned = 0;
7037 number_float_t value_float = 0;
7038
7039 /// the decimal point
7040 const char decimal_point_char = '.';
7041 };
7042 } // namespace detail
7043 } // namespace nlohmann
7044
7045 // #include <nlohmann/detail/input/parser.hpp>
7046
7047
7048 #include <cassert> // assert
7049 #include <cmath> // isfinite
7050 #include <cstdint> // uint8_t
7051 #include <functional> // function
7052 #include <string> // string
7053 #include <utility> // move
7054 #include <vector> // vector
7055
7056 // #include <nlohmann/detail/exceptions.hpp>
7057
7058 // #include <nlohmann/detail/input/input_adapters.hpp>
7059
7060 // #include <nlohmann/detail/input/json_sax.hpp>
7061
7062 // #include <nlohmann/detail/input/lexer.hpp>
7063
7064 // #include <nlohmann/detail/macro_scope.hpp>
7065
7066 // #include <nlohmann/detail/meta/is_sax.hpp>
7067
7068 // #include <nlohmann/detail/value_t.hpp>
7069
7070
7071 namespace nlohmann
7072 {
7073 namespace detail
7074 {
7075 ////////////
7076 // parser //
7077 ////////////
7078
7079 /*!
7080 @brief syntax analysis
7081
7082 This class implements a recursive decent parser.
7083 */
7084 template<typename BasicJsonType>
7085 class parser
7086 {
7087 using number_integer_t = typename BasicJsonType::number_integer_t;
7088 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7089 using number_float_t = typename BasicJsonType::number_float_t;
7090 using string_t = typename BasicJsonType::string_t;
7091 using lexer_t = lexer<BasicJsonType>;
7092 using token_type = typename lexer_t::token_type;
7093
7094 public:
7095 enum class parse_event_t : uint8_t
7096 {
7097 /// the parser read `{` and started to process a JSON object
7098 object_start,
7099 /// the parser read `}` and finished processing a JSON object
7100 object_end,
7101 /// the parser read `[` and started to process a JSON array
7102 array_start,
7103 /// the parser read `]` and finished processing a JSON array
7104 array_end,
7105 /// the parser read a key of a value in an object
7106 key,
7107 /// the parser finished reading a JSON value
7108 value
7109 };
7110
7111 using parser_callback_t =
7112 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
7113
7114 /// a parser reading from an input adapter
parser(detail::input_adapter_t && adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)7115 explicit parser(detail::input_adapter_t&& adapter,
7116 const parser_callback_t cb = nullptr,
7117 const bool allow_exceptions_ = true)
7118 : callback(cb), m_lexer(std::move(adapter)), allow_exceptions(allow_exceptions_)
7119 {
7120 // read first token
7121 get_token();
7122 }
7123
7124 /*!
7125 @brief public parser interface
7126
7127 @param[in] strict whether to expect the last token to be EOF
7128 @param[in,out] result parsed JSON value
7129
7130 @throw parse_error.101 in case of an unexpected token
7131 @throw parse_error.102 if to_unicode fails or surrogate error
7132 @throw parse_error.103 if to_unicode fails
7133 */
parse(const bool strict,BasicJsonType & result)7134 void parse(const bool strict, BasicJsonType& result)
7135 {
7136 if (callback)
7137 {
7138 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
7139 sax_parse_internal(&sdp);
7140 result.assert_invariant();
7141
7142 // in strict mode, input must be completely read
7143 if (strict and (get_token() != token_type::end_of_input))
7144 {
7145 sdp.parse_error(m_lexer.get_position(),
7146 m_lexer.get_token_string(),
7147 parse_error::create(101, m_lexer.get_position(),
7148 exception_message(token_type::end_of_input, "value")));
7149 }
7150
7151 // in case of an error, return discarded value
7152 if (sdp.is_errored())
7153 {
7154 result = value_t::discarded;
7155 return;
7156 }
7157
7158 // set top-level value to null if it was discarded by the callback
7159 // function
7160 if (result.is_discarded())
7161 {
7162 result = nullptr;
7163 }
7164 }
7165 else
7166 {
7167 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
7168 sax_parse_internal(&sdp);
7169 result.assert_invariant();
7170
7171 // in strict mode, input must be completely read
7172 if (strict and (get_token() != token_type::end_of_input))
7173 {
7174 sdp.parse_error(m_lexer.get_position(),
7175 m_lexer.get_token_string(),
7176 parse_error::create(101, m_lexer.get_position(),
7177 exception_message(token_type::end_of_input, "value")));
7178 }
7179
7180 // in case of an error, return discarded value
7181 if (sdp.is_errored())
7182 {
7183 result = value_t::discarded;
7184 return;
7185 }
7186 }
7187 }
7188
7189 /*!
7190 @brief public accept interface
7191
7192 @param[in] strict whether to expect the last token to be EOF
7193 @return whether the input is a proper JSON text
7194 */
accept(const bool strict=true)7195 bool accept(const bool strict = true)
7196 {
7197 json_sax_acceptor<BasicJsonType> sax_acceptor;
7198 return sax_parse(&sax_acceptor, strict);
7199 }
7200
7201 template <typename SAX>
sax_parse(SAX * sax,const bool strict=true)7202 bool sax_parse(SAX* sax, const bool strict = true)
7203 {
7204 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
7205 const bool result = sax_parse_internal(sax);
7206
7207 // strict mode: next byte must be EOF
7208 if (result and strict and (get_token() != token_type::end_of_input))
7209 {
7210 return sax->parse_error(m_lexer.get_position(),
7211 m_lexer.get_token_string(),
7212 parse_error::create(101, m_lexer.get_position(),
7213 exception_message(token_type::end_of_input, "value")));
7214 }
7215
7216 return result;
7217 }
7218
7219 private:
7220 template <typename SAX>
sax_parse_internal(SAX * sax)7221 bool sax_parse_internal(SAX* sax)
7222 {
7223 // stack to remember the hierarchy of structured values we are parsing
7224 // true = array; false = object
7225 std::vector<bool> states;
7226 // value to avoid a goto (see comment where set to true)
7227 bool skip_to_state_evaluation = false;
7228
7229 while (true)
7230 {
7231 if (not skip_to_state_evaluation)
7232 {
7233 // invariant: get_token() was called before each iteration
7234 switch (last_token)
7235 {
7236 case token_type::begin_object:
7237 {
7238 if (JSON_UNLIKELY(not sax->start_object(std::size_t(-1))))
7239 {
7240 return false;
7241 }
7242
7243 // closing } -> we are done
7244 if (get_token() == token_type::end_object)
7245 {
7246 if (JSON_UNLIKELY(not sax->end_object()))
7247 {
7248 return false;
7249 }
7250 break;
7251 }
7252
7253 // parse key
7254 if (JSON_UNLIKELY(last_token != token_type::value_string))
7255 {
7256 return sax->parse_error(m_lexer.get_position(),
7257 m_lexer.get_token_string(),
7258 parse_error::create(101, m_lexer.get_position(),
7259 exception_message(token_type::value_string, "object key")));
7260 }
7261 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7262 {
7263 return false;
7264 }
7265
7266 // parse separator (:)
7267 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7268 {
7269 return sax->parse_error(m_lexer.get_position(),
7270 m_lexer.get_token_string(),
7271 parse_error::create(101, m_lexer.get_position(),
7272 exception_message(token_type::name_separator, "object separator")));
7273 }
7274
7275 // remember we are now inside an object
7276 states.push_back(false);
7277
7278 // parse values
7279 get_token();
7280 continue;
7281 }
7282
7283 case token_type::begin_array:
7284 {
7285 if (JSON_UNLIKELY(not sax->start_array(std::size_t(-1))))
7286 {
7287 return false;
7288 }
7289
7290 // closing ] -> we are done
7291 if (get_token() == token_type::end_array)
7292 {
7293 if (JSON_UNLIKELY(not sax->end_array()))
7294 {
7295 return false;
7296 }
7297 break;
7298 }
7299
7300 // remember we are now inside an array
7301 states.push_back(true);
7302
7303 // parse values (no need to call get_token)
7304 continue;
7305 }
7306
7307 case token_type::value_float:
7308 {
7309 const auto res = m_lexer.get_number_float();
7310
7311 if (JSON_UNLIKELY(not std::isfinite(res)))
7312 {
7313 return sax->parse_error(m_lexer.get_position(),
7314 m_lexer.get_token_string(),
7315 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'"));
7316 }
7317
7318 if (JSON_UNLIKELY(not sax->number_float(res, m_lexer.get_string())))
7319 {
7320 return false;
7321 }
7322
7323 break;
7324 }
7325
7326 case token_type::literal_false:
7327 {
7328 if (JSON_UNLIKELY(not sax->boolean(false)))
7329 {
7330 return false;
7331 }
7332 break;
7333 }
7334
7335 case token_type::literal_null:
7336 {
7337 if (JSON_UNLIKELY(not sax->null()))
7338 {
7339 return false;
7340 }
7341 break;
7342 }
7343
7344 case token_type::literal_true:
7345 {
7346 if (JSON_UNLIKELY(not sax->boolean(true)))
7347 {
7348 return false;
7349 }
7350 break;
7351 }
7352
7353 case token_type::value_integer:
7354 {
7355 if (JSON_UNLIKELY(not sax->number_integer(m_lexer.get_number_integer())))
7356 {
7357 return false;
7358 }
7359 break;
7360 }
7361
7362 case token_type::value_string:
7363 {
7364 if (JSON_UNLIKELY(not sax->string(m_lexer.get_string())))
7365 {
7366 return false;
7367 }
7368 break;
7369 }
7370
7371 case token_type::value_unsigned:
7372 {
7373 if (JSON_UNLIKELY(not sax->number_unsigned(m_lexer.get_number_unsigned())))
7374 {
7375 return false;
7376 }
7377 break;
7378 }
7379
7380 case token_type::parse_error:
7381 {
7382 // using "uninitialized" to avoid "expected" message
7383 return sax->parse_error(m_lexer.get_position(),
7384 m_lexer.get_token_string(),
7385 parse_error::create(101, m_lexer.get_position(),
7386 exception_message(token_type::uninitialized, "value")));
7387 }
7388
7389 default: // the last token was unexpected
7390 {
7391 return sax->parse_error(m_lexer.get_position(),
7392 m_lexer.get_token_string(),
7393 parse_error::create(101, m_lexer.get_position(),
7394 exception_message(token_type::literal_or_value, "value")));
7395 }
7396 }
7397 }
7398 else
7399 {
7400 skip_to_state_evaluation = false;
7401 }
7402
7403 // we reached this line after we successfully parsed a value
7404 if (states.empty())
7405 {
7406 // empty stack: we reached the end of the hierarchy: done
7407 return true;
7408 }
7409
7410 if (states.back()) // array
7411 {
7412 // comma -> next value
7413 if (get_token() == token_type::value_separator)
7414 {
7415 // parse a new value
7416 get_token();
7417 continue;
7418 }
7419
7420 // closing ]
7421 if (JSON_LIKELY(last_token == token_type::end_array))
7422 {
7423 if (JSON_UNLIKELY(not sax->end_array()))
7424 {
7425 return false;
7426 }
7427
7428 // We are done with this array. Before we can parse a
7429 // new value, we need to evaluate the new state first.
7430 // By setting skip_to_state_evaluation to false, we
7431 // are effectively jumping to the beginning of this if.
7432 assert(not states.empty());
7433 states.pop_back();
7434 skip_to_state_evaluation = true;
7435 continue;
7436 }
7437
7438 return sax->parse_error(m_lexer.get_position(),
7439 m_lexer.get_token_string(),
7440 parse_error::create(101, m_lexer.get_position(),
7441 exception_message(token_type::end_array, "array")));
7442 }
7443 else // object
7444 {
7445 // comma -> next value
7446 if (get_token() == token_type::value_separator)
7447 {
7448 // parse key
7449 if (JSON_UNLIKELY(get_token() != token_type::value_string))
7450 {
7451 return sax->parse_error(m_lexer.get_position(),
7452 m_lexer.get_token_string(),
7453 parse_error::create(101, m_lexer.get_position(),
7454 exception_message(token_type::value_string, "object key")));
7455 }
7456
7457 if (JSON_UNLIKELY(not sax->key(m_lexer.get_string())))
7458 {
7459 return false;
7460 }
7461
7462 // parse separator (:)
7463 if (JSON_UNLIKELY(get_token() != token_type::name_separator))
7464 {
7465 return sax->parse_error(m_lexer.get_position(),
7466 m_lexer.get_token_string(),
7467 parse_error::create(101, m_lexer.get_position(),
7468 exception_message(token_type::name_separator, "object separator")));
7469 }
7470
7471 // parse values
7472 get_token();
7473 continue;
7474 }
7475
7476 // closing }
7477 if (JSON_LIKELY(last_token == token_type::end_object))
7478 {
7479 if (JSON_UNLIKELY(not sax->end_object()))
7480 {
7481 return false;
7482 }
7483
7484 // We are done with this object. Before we can parse a
7485 // new value, we need to evaluate the new state first.
7486 // By setting skip_to_state_evaluation to false, we
7487 // are effectively jumping to the beginning of this if.
7488 assert(not states.empty());
7489 states.pop_back();
7490 skip_to_state_evaluation = true;
7491 continue;
7492 }
7493
7494 return sax->parse_error(m_lexer.get_position(),
7495 m_lexer.get_token_string(),
7496 parse_error::create(101, m_lexer.get_position(),
7497 exception_message(token_type::end_object, "object")));
7498 }
7499 }
7500 }
7501
7502 /// get next token from lexer
get_token()7503 token_type get_token()
7504 {
7505 return last_token = m_lexer.scan();
7506 }
7507
exception_message(const token_type expected,const std::string & context)7508 std::string exception_message(const token_type expected, const std::string& context)
7509 {
7510 std::string error_msg = "syntax error ";
7511
7512 if (not context.empty())
7513 {
7514 error_msg += "while parsing " + context + " ";
7515 }
7516
7517 error_msg += "- ";
7518
7519 if (last_token == token_type::parse_error)
7520 {
7521 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
7522 m_lexer.get_token_string() + "'";
7523 }
7524 else
7525 {
7526 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
7527 }
7528
7529 if (expected != token_type::uninitialized)
7530 {
7531 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
7532 }
7533
7534 return error_msg;
7535 }
7536
7537 private:
7538 /// callback function
7539 const parser_callback_t callback = nullptr;
7540 /// the type of the last read token
7541 token_type last_token = token_type::uninitialized;
7542 /// the lexer
7543 lexer_t m_lexer;
7544 /// whether to throw exceptions in case of errors
7545 const bool allow_exceptions = true;
7546 };
7547 } // namespace detail
7548 } // namespace nlohmann
7549
7550 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
7551
7552
7553 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
7554
7555
7556 #include <cstddef> // ptrdiff_t
7557 #include <limits> // numeric_limits
7558
7559 namespace nlohmann
7560 {
7561 namespace detail
7562 {
7563 /*
7564 @brief an iterator for primitive JSON types
7565
7566 This class models an iterator for primitive JSON types (boolean, number,
7567 string). It's only purpose is to allow the iterator/const_iterator classes
7568 to "iterate" over primitive values. Internally, the iterator is modeled by
7569 a `difference_type` variable. Value begin_value (`0`) models the begin,
7570 end_value (`1`) models past the end.
7571 */
7572 class primitive_iterator_t
7573 {
7574 private:
7575 using difference_type = std::ptrdiff_t;
7576 static constexpr difference_type begin_value = 0;
7577 static constexpr difference_type end_value = begin_value + 1;
7578
7579 /// iterator as signed integer type
7580 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
7581
7582 public:
get_value() const7583 constexpr difference_type get_value() const noexcept
7584 {
7585 return m_it;
7586 }
7587
7588 /// set iterator to a defined beginning
set_begin()7589 void set_begin() noexcept
7590 {
7591 m_it = begin_value;
7592 }
7593
7594 /// set iterator to a defined past the end
set_end()7595 void set_end() noexcept
7596 {
7597 m_it = end_value;
7598 }
7599
7600 /// return whether the iterator can be dereferenced
is_begin() const7601 constexpr bool is_begin() const noexcept
7602 {
7603 return m_it == begin_value;
7604 }
7605
7606 /// return whether the iterator is at end
is_end() const7607 constexpr bool is_end() const noexcept
7608 {
7609 return m_it == end_value;
7610 }
7611
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)7612 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7613 {
7614 return lhs.m_it == rhs.m_it;
7615 }
7616
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)7617 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7618 {
7619 return lhs.m_it < rhs.m_it;
7620 }
7621
operator +(difference_type n)7622 primitive_iterator_t operator+(difference_type n) noexcept
7623 {
7624 auto result = *this;
7625 result += n;
7626 return result;
7627 }
7628
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)7629 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
7630 {
7631 return lhs.m_it - rhs.m_it;
7632 }
7633
operator ++()7634 primitive_iterator_t& operator++() noexcept
7635 {
7636 ++m_it;
7637 return *this;
7638 }
7639
operator ++(int)7640 primitive_iterator_t const operator++(int) noexcept
7641 {
7642 auto result = *this;
7643 ++m_it;
7644 return result;
7645 }
7646
operator --()7647 primitive_iterator_t& operator--() noexcept
7648 {
7649 --m_it;
7650 return *this;
7651 }
7652
operator --(int)7653 primitive_iterator_t const operator--(int) noexcept
7654 {
7655 auto result = *this;
7656 --m_it;
7657 return result;
7658 }
7659
operator +=(difference_type n)7660 primitive_iterator_t& operator+=(difference_type n) noexcept
7661 {
7662 m_it += n;
7663 return *this;
7664 }
7665
operator -=(difference_type n)7666 primitive_iterator_t& operator-=(difference_type n) noexcept
7667 {
7668 m_it -= n;
7669 return *this;
7670 }
7671 };
7672 } // namespace detail
7673 } // namespace nlohmann
7674
7675
7676 namespace nlohmann
7677 {
7678 namespace detail
7679 {
7680 /*!
7681 @brief an iterator value
7682
7683 @note This structure could easily be a union, but MSVC currently does not allow
7684 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
7685 */
7686 template<typename BasicJsonType> struct internal_iterator
7687 {
7688 /// iterator for JSON objects
7689 typename BasicJsonType::object_t::iterator object_iterator {};
7690 /// iterator for JSON arrays
7691 typename BasicJsonType::array_t::iterator array_iterator {};
7692 /// generic iterator for all other types
7693 primitive_iterator_t primitive_iterator {};
7694 };
7695 } // namespace detail
7696 } // namespace nlohmann
7697
7698 // #include <nlohmann/detail/iterators/iter_impl.hpp>
7699
7700
7701 #include <ciso646> // not
7702 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
7703 #include <type_traits> // conditional, is_const, remove_const
7704
7705 // #include <nlohmann/detail/exceptions.hpp>
7706
7707 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
7708
7709 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
7710
7711 // #include <nlohmann/detail/macro_scope.hpp>
7712
7713 // #include <nlohmann/detail/meta/cpp_future.hpp>
7714
7715 // #include <nlohmann/detail/meta/type_traits.hpp>
7716
7717 // #include <nlohmann/detail/value_t.hpp>
7718
7719
7720 namespace nlohmann
7721 {
7722 namespace detail
7723 {
7724 // forward declare, to be able to friend it later on
7725 template<typename IteratorType> class iteration_proxy;
7726 template<typename IteratorType> class iteration_proxy_value;
7727
7728 /*!
7729 @brief a template for a bidirectional iterator for the @ref basic_json class
7730 This class implements a both iterators (iterator and const_iterator) for the
7731 @ref basic_json class.
7732 @note An iterator is called *initialized* when a pointer to a JSON value has
7733 been set (e.g., by a constructor or a copy assignment). If the iterator is
7734 default-constructed, it is *uninitialized* and most methods are undefined.
7735 **The library uses assertions to detect calls on uninitialized iterators.**
7736 @requirement The class satisfies the following concept requirements:
7737 -
7738 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
7739 The iterator that can be moved can be moved in both directions (i.e.
7740 incremented and decremented).
7741 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
7742 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
7743 */
7744 template<typename BasicJsonType>
7745 class iter_impl
7746 {
7747 /// allow basic_json to access private members
7748 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
7749 friend BasicJsonType;
7750 friend iteration_proxy<iter_impl>;
7751 friend iteration_proxy_value<iter_impl>;
7752
7753 using object_t = typename BasicJsonType::object_t;
7754 using array_t = typename BasicJsonType::array_t;
7755 // make sure BasicJsonType is basic_json or const basic_json
7756 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
7757 "iter_impl only accepts (const) basic_json");
7758
7759 public:
7760
7761 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
7762 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
7763 /// A user-defined iterator should provide publicly accessible typedefs named
7764 /// iterator_category, value_type, difference_type, pointer, and reference.
7765 /// Note that value_type is required to be non-const, even for constant iterators.
7766 using iterator_category = std::bidirectional_iterator_tag;
7767
7768 /// the type of the values when the iterator is dereferenced
7769 using value_type = typename BasicJsonType::value_type;
7770 /// a type to represent differences between iterators
7771 using difference_type = typename BasicJsonType::difference_type;
7772 /// defines a pointer to the type iterated over (value_type)
7773 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
7774 typename BasicJsonType::const_pointer,
7775 typename BasicJsonType::pointer>::type;
7776 /// defines a reference to the type iterated over (value_type)
7777 using reference =
7778 typename std::conditional<std::is_const<BasicJsonType>::value,
7779 typename BasicJsonType::const_reference,
7780 typename BasicJsonType::reference>::type;
7781
7782 /// default constructor
7783 iter_impl() = default;
7784
7785 /*!
7786 @brief constructor for a given JSON instance
7787 @param[in] object pointer to a JSON object for this iterator
7788 @pre object != nullptr
7789 @post The iterator is initialized; i.e. `m_object != nullptr`.
7790 */
iter_impl(pointer object)7791 explicit iter_impl(pointer object) noexcept : m_object(object)
7792 {
7793 assert(m_object != nullptr);
7794
7795 switch (m_object->m_type)
7796 {
7797 case value_t::object:
7798 {
7799 m_it.object_iterator = typename object_t::iterator();
7800 break;
7801 }
7802
7803 case value_t::array:
7804 {
7805 m_it.array_iterator = typename array_t::iterator();
7806 break;
7807 }
7808
7809 default:
7810 {
7811 m_it.primitive_iterator = primitive_iterator_t();
7812 break;
7813 }
7814 }
7815 }
7816
7817 /*!
7818 @note The conventional copy constructor and copy assignment are implicitly
7819 defined. Combined with the following converting constructor and
7820 assignment, they support: (1) copy from iterator to iterator, (2)
7821 copy from const iterator to const iterator, and (3) conversion from
7822 iterator to const iterator. However conversion from const iterator
7823 to iterator is not defined.
7824 */
7825
7826 /*!
7827 @brief converting constructor
7828 @param[in] other non-const iterator to copy from
7829 @note It is not checked whether @a other is initialized.
7830 */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)7831 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7832 : m_object(other.m_object), m_it(other.m_it) {}
7833
7834 /*!
7835 @brief converting assignment
7836 @param[in,out] other non-const iterator to copy from
7837 @return const/non-const iterator
7838 @note It is not checked whether @a other is initialized.
7839 */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)7840 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
7841 {
7842 m_object = other.m_object;
7843 m_it = other.m_it;
7844 return *this;
7845 }
7846
7847 private:
7848 /*!
7849 @brief set the iterator to the first value
7850 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7851 */
set_begin()7852 void set_begin() noexcept
7853 {
7854 assert(m_object != nullptr);
7855
7856 switch (m_object->m_type)
7857 {
7858 case value_t::object:
7859 {
7860 m_it.object_iterator = m_object->m_value.object->begin();
7861 break;
7862 }
7863
7864 case value_t::array:
7865 {
7866 m_it.array_iterator = m_object->m_value.array->begin();
7867 break;
7868 }
7869
7870 case value_t::null:
7871 {
7872 // set to end so begin()==end() is true: null is empty
7873 m_it.primitive_iterator.set_end();
7874 break;
7875 }
7876
7877 default:
7878 {
7879 m_it.primitive_iterator.set_begin();
7880 break;
7881 }
7882 }
7883 }
7884
7885 /*!
7886 @brief set the iterator past the last value
7887 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7888 */
set_end()7889 void set_end() noexcept
7890 {
7891 assert(m_object != nullptr);
7892
7893 switch (m_object->m_type)
7894 {
7895 case value_t::object:
7896 {
7897 m_it.object_iterator = m_object->m_value.object->end();
7898 break;
7899 }
7900
7901 case value_t::array:
7902 {
7903 m_it.array_iterator = m_object->m_value.array->end();
7904 break;
7905 }
7906
7907 default:
7908 {
7909 m_it.primitive_iterator.set_end();
7910 break;
7911 }
7912 }
7913 }
7914
7915 public:
7916 /*!
7917 @brief return a reference to the value pointed to by the iterator
7918 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7919 */
operator *() const7920 reference operator*() const
7921 {
7922 assert(m_object != nullptr);
7923
7924 switch (m_object->m_type)
7925 {
7926 case value_t::object:
7927 {
7928 assert(m_it.object_iterator != m_object->m_value.object->end());
7929 return m_it.object_iterator->second;
7930 }
7931
7932 case value_t::array:
7933 {
7934 assert(m_it.array_iterator != m_object->m_value.array->end());
7935 return *m_it.array_iterator;
7936 }
7937
7938 case value_t::null:
7939 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7940
7941 default:
7942 {
7943 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7944 {
7945 return *m_object;
7946 }
7947
7948 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7949 }
7950 }
7951 }
7952
7953 /*!
7954 @brief dereference the iterator
7955 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7956 */
operator ->() const7957 pointer operator->() const
7958 {
7959 assert(m_object != nullptr);
7960
7961 switch (m_object->m_type)
7962 {
7963 case value_t::object:
7964 {
7965 assert(m_it.object_iterator != m_object->m_value.object->end());
7966 return &(m_it.object_iterator->second);
7967 }
7968
7969 case value_t::array:
7970 {
7971 assert(m_it.array_iterator != m_object->m_value.array->end());
7972 return &*m_it.array_iterator;
7973 }
7974
7975 default:
7976 {
7977 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
7978 {
7979 return m_object;
7980 }
7981
7982 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
7983 }
7984 }
7985 }
7986
7987 /*!
7988 @brief post-increment (it++)
7989 @pre The iterator is initialized; i.e. `m_object != nullptr`.
7990 */
operator ++(int)7991 iter_impl const operator++(int)
7992 {
7993 auto result = *this;
7994 ++(*this);
7995 return result;
7996 }
7997
7998 /*!
7999 @brief pre-increment (++it)
8000 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8001 */
operator ++()8002 iter_impl& operator++()
8003 {
8004 assert(m_object != nullptr);
8005
8006 switch (m_object->m_type)
8007 {
8008 case value_t::object:
8009 {
8010 std::advance(m_it.object_iterator, 1);
8011 break;
8012 }
8013
8014 case value_t::array:
8015 {
8016 std::advance(m_it.array_iterator, 1);
8017 break;
8018 }
8019
8020 default:
8021 {
8022 ++m_it.primitive_iterator;
8023 break;
8024 }
8025 }
8026
8027 return *this;
8028 }
8029
8030 /*!
8031 @brief post-decrement (it--)
8032 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8033 */
operator --(int)8034 iter_impl const operator--(int)
8035 {
8036 auto result = *this;
8037 --(*this);
8038 return result;
8039 }
8040
8041 /*!
8042 @brief pre-decrement (--it)
8043 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8044 */
operator --()8045 iter_impl& operator--()
8046 {
8047 assert(m_object != nullptr);
8048
8049 switch (m_object->m_type)
8050 {
8051 case value_t::object:
8052 {
8053 std::advance(m_it.object_iterator, -1);
8054 break;
8055 }
8056
8057 case value_t::array:
8058 {
8059 std::advance(m_it.array_iterator, -1);
8060 break;
8061 }
8062
8063 default:
8064 {
8065 --m_it.primitive_iterator;
8066 break;
8067 }
8068 }
8069
8070 return *this;
8071 }
8072
8073 /*!
8074 @brief comparison: equal
8075 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8076 */
operator ==(const iter_impl & other) const8077 bool operator==(const iter_impl& other) const
8078 {
8079 // if objects are not the same, the comparison is undefined
8080 if (JSON_UNLIKELY(m_object != other.m_object))
8081 {
8082 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8083 }
8084
8085 assert(m_object != nullptr);
8086
8087 switch (m_object->m_type)
8088 {
8089 case value_t::object:
8090 return (m_it.object_iterator == other.m_it.object_iterator);
8091
8092 case value_t::array:
8093 return (m_it.array_iterator == other.m_it.array_iterator);
8094
8095 default:
8096 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
8097 }
8098 }
8099
8100 /*!
8101 @brief comparison: not equal
8102 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8103 */
operator !=(const iter_impl & other) const8104 bool operator!=(const iter_impl& other) const
8105 {
8106 return not operator==(other);
8107 }
8108
8109 /*!
8110 @brief comparison: smaller
8111 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8112 */
operator <(const iter_impl & other) const8113 bool operator<(const iter_impl& other) const
8114 {
8115 // if objects are not the same, the comparison is undefined
8116 if (JSON_UNLIKELY(m_object != other.m_object))
8117 {
8118 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
8119 }
8120
8121 assert(m_object != nullptr);
8122
8123 switch (m_object->m_type)
8124 {
8125 case value_t::object:
8126 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
8127
8128 case value_t::array:
8129 return (m_it.array_iterator < other.m_it.array_iterator);
8130
8131 default:
8132 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
8133 }
8134 }
8135
8136 /*!
8137 @brief comparison: less than or equal
8138 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8139 */
operator <=(const iter_impl & other) const8140 bool operator<=(const iter_impl& other) const
8141 {
8142 return not other.operator < (*this);
8143 }
8144
8145 /*!
8146 @brief comparison: greater than
8147 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8148 */
operator >(const iter_impl & other) const8149 bool operator>(const iter_impl& other) const
8150 {
8151 return not operator<=(other);
8152 }
8153
8154 /*!
8155 @brief comparison: greater than or equal
8156 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8157 */
operator >=(const iter_impl & other) const8158 bool operator>=(const iter_impl& other) const
8159 {
8160 return not operator<(other);
8161 }
8162
8163 /*!
8164 @brief add to iterator
8165 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8166 */
operator +=(difference_type i)8167 iter_impl& operator+=(difference_type i)
8168 {
8169 assert(m_object != nullptr);
8170
8171 switch (m_object->m_type)
8172 {
8173 case value_t::object:
8174 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8175
8176 case value_t::array:
8177 {
8178 std::advance(m_it.array_iterator, i);
8179 break;
8180 }
8181
8182 default:
8183 {
8184 m_it.primitive_iterator += i;
8185 break;
8186 }
8187 }
8188
8189 return *this;
8190 }
8191
8192 /*!
8193 @brief subtract from iterator
8194 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8195 */
operator -=(difference_type i)8196 iter_impl& operator-=(difference_type i)
8197 {
8198 return operator+=(-i);
8199 }
8200
8201 /*!
8202 @brief add to iterator
8203 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8204 */
operator +(difference_type i) const8205 iter_impl operator+(difference_type i) const
8206 {
8207 auto result = *this;
8208 result += i;
8209 return result;
8210 }
8211
8212 /*!
8213 @brief addition of distance and iterator
8214 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8215 */
operator +(difference_type i,const iter_impl & it)8216 friend iter_impl operator+(difference_type i, const iter_impl& it)
8217 {
8218 auto result = it;
8219 result += i;
8220 return result;
8221 }
8222
8223 /*!
8224 @brief subtract from iterator
8225 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8226 */
operator -(difference_type i) const8227 iter_impl operator-(difference_type i) const
8228 {
8229 auto result = *this;
8230 result -= i;
8231 return result;
8232 }
8233
8234 /*!
8235 @brief return difference
8236 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8237 */
operator -(const iter_impl & other) const8238 difference_type operator-(const iter_impl& other) const
8239 {
8240 assert(m_object != nullptr);
8241
8242 switch (m_object->m_type)
8243 {
8244 case value_t::object:
8245 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
8246
8247 case value_t::array:
8248 return m_it.array_iterator - other.m_it.array_iterator;
8249
8250 default:
8251 return m_it.primitive_iterator - other.m_it.primitive_iterator;
8252 }
8253 }
8254
8255 /*!
8256 @brief access to successor
8257 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8258 */
operator [](difference_type n) const8259 reference operator[](difference_type n) const
8260 {
8261 assert(m_object != nullptr);
8262
8263 switch (m_object->m_type)
8264 {
8265 case value_t::object:
8266 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
8267
8268 case value_t::array:
8269 return *std::next(m_it.array_iterator, n);
8270
8271 case value_t::null:
8272 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8273
8274 default:
8275 {
8276 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
8277 {
8278 return *m_object;
8279 }
8280
8281 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
8282 }
8283 }
8284 }
8285
8286 /*!
8287 @brief return the key of an object iterator
8288 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8289 */
key() const8290 const typename object_t::key_type& key() const
8291 {
8292 assert(m_object != nullptr);
8293
8294 if (JSON_LIKELY(m_object->is_object()))
8295 {
8296 return m_it.object_iterator->first;
8297 }
8298
8299 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
8300 }
8301
8302 /*!
8303 @brief return the value of an iterator
8304 @pre The iterator is initialized; i.e. `m_object != nullptr`.
8305 */
value() const8306 reference value() const
8307 {
8308 return operator*();
8309 }
8310
8311 private:
8312 /// associated JSON instance
8313 pointer m_object = nullptr;
8314 /// the actual iterator of the associated instance
8315 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
8316 };
8317 } // namespace detail
8318 } // namespace nlohmann
8319
8320 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
8321
8322 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
8323
8324
8325 #include <cstddef> // ptrdiff_t
8326 #include <iterator> // reverse_iterator
8327 #include <utility> // declval
8328
8329 namespace nlohmann
8330 {
8331 namespace detail
8332 {
8333 //////////////////////
8334 // reverse_iterator //
8335 //////////////////////
8336
8337 /*!
8338 @brief a template for a reverse iterator class
8339
8340 @tparam Base the base iterator type to reverse. Valid types are @ref
8341 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
8342 create @ref const_reverse_iterator).
8343
8344 @requirement The class satisfies the following concept requirements:
8345 -
8346 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
8347 The iterator that can be moved can be moved in both directions (i.e.
8348 incremented and decremented).
8349 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
8350 It is possible to write to the pointed-to element (only if @a Base is
8351 @ref iterator).
8352
8353 @since version 1.0.0
8354 */
8355 template<typename Base>
8356 class json_reverse_iterator : public std::reverse_iterator<Base>
8357 {
8358 public:
8359 using difference_type = std::ptrdiff_t;
8360 /// shortcut to the reverse iterator adapter
8361 using base_iterator = std::reverse_iterator<Base>;
8362 /// the reference type for the pointed-to element
8363 using reference = typename Base::reference;
8364
8365 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)8366 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
8367 : base_iterator(it) {}
8368
8369 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)8370 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
8371
8372 /// post-increment (it++)
operator ++(int)8373 json_reverse_iterator const operator++(int)
8374 {
8375 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
8376 }
8377
8378 /// pre-increment (++it)
operator ++()8379 json_reverse_iterator& operator++()
8380 {
8381 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
8382 }
8383
8384 /// post-decrement (it--)
operator --(int)8385 json_reverse_iterator const operator--(int)
8386 {
8387 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
8388 }
8389
8390 /// pre-decrement (--it)
operator --()8391 json_reverse_iterator& operator--()
8392 {
8393 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
8394 }
8395
8396 /// add to iterator
operator +=(difference_type i)8397 json_reverse_iterator& operator+=(difference_type i)
8398 {
8399 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
8400 }
8401
8402 /// add to iterator
operator +(difference_type i) const8403 json_reverse_iterator operator+(difference_type i) const
8404 {
8405 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
8406 }
8407
8408 /// subtract from iterator
operator -(difference_type i) const8409 json_reverse_iterator operator-(difference_type i) const
8410 {
8411 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
8412 }
8413
8414 /// return difference
operator -(const json_reverse_iterator & other) const8415 difference_type operator-(const json_reverse_iterator& other) const
8416 {
8417 return base_iterator(*this) - base_iterator(other);
8418 }
8419
8420 /// access to successor
operator [](difference_type n) const8421 reference operator[](difference_type n) const
8422 {
8423 return *(this->operator+(n));
8424 }
8425
8426 /// return the key of an object iterator
key() const8427 auto key() const -> decltype(std::declval<Base>().key())
8428 {
8429 auto it = --this->base();
8430 return it.key();
8431 }
8432
8433 /// return the value of an iterator
value() const8434 reference value() const
8435 {
8436 auto it = --this->base();
8437 return it.operator * ();
8438 }
8439 };
8440 } // namespace detail
8441 } // namespace nlohmann
8442
8443 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
8444
8445 // #include <nlohmann/detail/json_pointer.hpp>
8446
8447
8448 #include <algorithm> // all_of
8449 #include <cassert> // assert
8450 #include <numeric> // accumulate
8451 #include <string> // string
8452 #include <utility> // move
8453 #include <vector> // vector
8454
8455 // #include <nlohmann/detail/exceptions.hpp>
8456
8457 // #include <nlohmann/detail/macro_scope.hpp>
8458
8459 // #include <nlohmann/detail/value_t.hpp>
8460
8461
8462 namespace nlohmann
8463 {
8464 template<typename BasicJsonType>
8465 class json_pointer
8466 {
8467 // allow basic_json to access private members
8468 NLOHMANN_BASIC_JSON_TPL_DECLARATION
8469 friend class basic_json;
8470
8471 public:
8472 /*!
8473 @brief create JSON pointer
8474
8475 Create a JSON pointer according to the syntax described in
8476 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
8477
8478 @param[in] s string representing the JSON pointer; if omitted, the empty
8479 string is assumed which references the whole JSON value
8480
8481 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
8482 not begin with a slash (`/`); see example below
8483
8484 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
8485 not followed by `0` (representing `~`) or `1` (representing `/`); see
8486 example below
8487
8488 @liveexample{The example shows the construction several valid JSON pointers
8489 as well as the exceptional behavior.,json_pointer}
8490
8491 @since version 2.0.0
8492 */
json_pointer(const std::string & s="")8493 explicit json_pointer(const std::string& s = "")
8494 : reference_tokens(split(s))
8495 {}
8496
8497 /*!
8498 @brief return a string representation of the JSON pointer
8499
8500 @invariant For each JSON pointer `ptr`, it holds:
8501 @code {.cpp}
8502 ptr == json_pointer(ptr.to_string());
8503 @endcode
8504
8505 @return a string representation of the JSON pointer
8506
8507 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
8508
8509 @since version 2.0.0
8510 */
to_string() const8511 std::string to_string() const
8512 {
8513 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
8514 std::string{},
8515 [](const std::string & a, const std::string & b)
8516 {
8517 return a + "/" + escape(b);
8518 });
8519 }
8520
8521 /// @copydoc to_string()
operator std::string() const8522 operator std::string() const
8523 {
8524 return to_string();
8525 }
8526
8527 /*!
8528 @brief append another JSON pointer at the end of this JSON pointer
8529
8530 @param[in] ptr JSON pointer to append
8531 @return JSON pointer with @a ptr appended
8532
8533 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8534
8535 @complexity Linear in the length of @a ptr.
8536
8537 @sa @ref operator/=(std::string) to append a reference token
8538 @sa @ref operator/=(std::size_t) to append an array index
8539 @sa @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
8540
8541 @since version 3.6.0
8542 */
operator /=(const json_pointer & ptr)8543 json_pointer& operator/=(const json_pointer& ptr)
8544 {
8545 reference_tokens.insert(reference_tokens.end(),
8546 ptr.reference_tokens.begin(),
8547 ptr.reference_tokens.end());
8548 return *this;
8549 }
8550
8551 /*!
8552 @brief append an unescaped reference token at the end of this JSON pointer
8553
8554 @param[in] token reference token to append
8555 @return JSON pointer with @a token appended without escaping @a token
8556
8557 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8558
8559 @complexity Amortized constant.
8560
8561 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8562 @sa @ref operator/=(std::size_t) to append an array index
8563 @sa @ref operator/(const json_pointer&, std::size_t) for a binary operator
8564
8565 @since version 3.6.0
8566 */
operator /=(std::string token)8567 json_pointer& operator/=(std::string token)
8568 {
8569 push_back(std::move(token));
8570 return *this;
8571 }
8572
8573 /*!
8574 @brief append an array index at the end of this JSON pointer
8575
8576 @param[in] array_index array index ot append
8577 @return JSON pointer with @a array_index appended
8578
8579 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
8580
8581 @complexity Amortized constant.
8582
8583 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8584 @sa @ref operator/=(std::string) to append a reference token
8585 @sa @ref operator/(const json_pointer&, std::string) for a binary operator
8586
8587 @since version 3.6.0
8588 */
operator /=(std::size_t array_index)8589 json_pointer& operator/=(std::size_t array_index)
8590 {
8591 return *this /= std::to_string(array_index);
8592 }
8593
8594 /*!
8595 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
8596
8597 @param[in] lhs JSON pointer
8598 @param[in] rhs JSON pointer
8599 @return a new JSON pointer with @a rhs appended to @a lhs
8600
8601 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8602
8603 @complexity Linear in the length of @a lhs and @a rhs.
8604
8605 @sa @ref operator/=(const json_pointer&) to append a JSON pointer
8606
8607 @since version 3.6.0
8608 */
operator /(const json_pointer & lhs,const json_pointer & rhs)8609 friend json_pointer operator/(const json_pointer& lhs,
8610 const json_pointer& rhs)
8611 {
8612 return json_pointer(lhs) /= rhs;
8613 }
8614
8615 /*!
8616 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
8617
8618 @param[in] ptr JSON pointer
8619 @param[in] token reference token
8620 @return a new JSON pointer with unescaped @a token appended to @a ptr
8621
8622 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8623
8624 @complexity Linear in the length of @a ptr.
8625
8626 @sa @ref operator/=(std::string) to append a reference token
8627
8628 @since version 3.6.0
8629 */
operator /(const json_pointer & ptr,std::string token)8630 friend json_pointer operator/(const json_pointer& ptr, std::string token)
8631 {
8632 return json_pointer(ptr) /= std::move(token);
8633 }
8634
8635 /*!
8636 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
8637
8638 @param[in] ptr JSON pointer
8639 @param[in] array_index array index
8640 @return a new JSON pointer with @a array_index appended to @a ptr
8641
8642 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
8643
8644 @complexity Linear in the length of @a ptr.
8645
8646 @sa @ref operator/=(std::size_t) to append an array index
8647
8648 @since version 3.6.0
8649 */
operator /(const json_pointer & ptr,std::size_t array_index)8650 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_index)
8651 {
8652 return json_pointer(ptr) /= array_index;
8653 }
8654
8655 /*!
8656 @brief returns the parent of this JSON pointer
8657
8658 @return parent of this JSON pointer; in case this JSON pointer is the root,
8659 the root itself is returned
8660
8661 @complexity Linear in the length of the JSON pointer.
8662
8663 @liveexample{The example shows the result of `parent_pointer` for different
8664 JSON Pointers.,json_pointer__parent_pointer}
8665
8666 @since version 3.6.0
8667 */
parent_pointer() const8668 json_pointer parent_pointer() const
8669 {
8670 if (empty())
8671 {
8672 return *this;
8673 }
8674
8675 json_pointer res = *this;
8676 res.pop_back();
8677 return res;
8678 }
8679
8680 /*!
8681 @brief remove last reference token
8682
8683 @pre not `empty()`
8684
8685 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
8686
8687 @complexity Constant.
8688
8689 @throw out_of_range.405 if JSON pointer has no parent
8690
8691 @since version 3.6.0
8692 */
pop_back()8693 void pop_back()
8694 {
8695 if (JSON_UNLIKELY(empty()))
8696 {
8697 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8698 }
8699
8700 reference_tokens.pop_back();
8701 }
8702
8703 /*!
8704 @brief return last reference token
8705
8706 @pre not `empty()`
8707 @return last reference token
8708
8709 @liveexample{The example shows the usage of `back`.,json_pointer__back}
8710
8711 @complexity Constant.
8712
8713 @throw out_of_range.405 if JSON pointer has no parent
8714
8715 @since version 3.6.0
8716 */
back()8717 const std::string& back()
8718 {
8719 if (JSON_UNLIKELY(empty()))
8720 {
8721 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8722 }
8723
8724 return reference_tokens.back();
8725 }
8726
8727 /*!
8728 @brief append an unescaped token at the end of the reference pointer
8729
8730 @param[in] token token to add
8731
8732 @complexity Amortized constant.
8733
8734 @liveexample{The example shows the result of `push_back` for different
8735 JSON Pointers.,json_pointer__push_back}
8736
8737 @since version 3.6.0
8738 */
push_back(const std::string & token)8739 void push_back(const std::string& token)
8740 {
8741 reference_tokens.push_back(token);
8742 }
8743
8744 /// @copydoc push_back(const std::string&)
push_back(std::string && token)8745 void push_back(std::string&& token)
8746 {
8747 reference_tokens.push_back(std::move(token));
8748 }
8749
8750 /*!
8751 @brief return whether pointer points to the root document
8752
8753 @return true iff the JSON pointer points to the root document
8754
8755 @complexity Constant.
8756
8757 @exceptionsafety No-throw guarantee: this function never throws exceptions.
8758
8759 @liveexample{The example shows the result of `empty` for different JSON
8760 Pointers.,json_pointer__empty}
8761
8762 @since version 3.6.0
8763 */
empty() const8764 bool empty() const noexcept
8765 {
8766 return reference_tokens.empty();
8767 }
8768
8769 private:
8770 /*!
8771 @param[in] s reference token to be converted into an array index
8772
8773 @return integer representation of @a s
8774
8775 @throw out_of_range.404 if string @a s could not be converted to an integer
8776 */
array_index(const std::string & s)8777 static int array_index(const std::string& s)
8778 {
8779 std::size_t processed_chars = 0;
8780 const int res = std::stoi(s, &processed_chars);
8781
8782 // check if the string was completely read
8783 if (JSON_UNLIKELY(processed_chars != s.size()))
8784 {
8785 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
8786 }
8787
8788 return res;
8789 }
8790
top() const8791 json_pointer top() const
8792 {
8793 if (JSON_UNLIKELY(empty()))
8794 {
8795 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
8796 }
8797
8798 json_pointer result = *this;
8799 result.reference_tokens = {reference_tokens[0]};
8800 return result;
8801 }
8802
8803 /*!
8804 @brief create and return a reference to the pointed to value
8805
8806 @complexity Linear in the number of reference tokens.
8807
8808 @throw parse_error.109 if array index is not a number
8809 @throw type_error.313 if value cannot be unflattened
8810 */
get_and_create(BasicJsonType & j) const8811 BasicJsonType& get_and_create(BasicJsonType& j) const
8812 {
8813 using size_type = typename BasicJsonType::size_type;
8814 auto result = &j;
8815
8816 // in case no reference tokens exist, return a reference to the JSON value
8817 // j which will be overwritten by a primitive value
8818 for (const auto& reference_token : reference_tokens)
8819 {
8820 switch (result->m_type)
8821 {
8822 case detail::value_t::null:
8823 {
8824 if (reference_token == "0")
8825 {
8826 // start a new array if reference token is 0
8827 result = &result->operator[](0);
8828 }
8829 else
8830 {
8831 // start a new object otherwise
8832 result = &result->operator[](reference_token);
8833 }
8834 break;
8835 }
8836
8837 case detail::value_t::object:
8838 {
8839 // create an entry in the object
8840 result = &result->operator[](reference_token);
8841 break;
8842 }
8843
8844 case detail::value_t::array:
8845 {
8846 // create an entry in the array
8847 JSON_TRY
8848 {
8849 result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
8850 }
8851 JSON_CATCH(std::invalid_argument&)
8852 {
8853 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8854 }
8855 break;
8856 }
8857
8858 /*
8859 The following code is only reached if there exists a reference
8860 token _and_ the current value is primitive. In this case, we have
8861 an error situation, because primitive values may only occur as
8862 single value; that is, with an empty list of reference tokens.
8863 */
8864 default:
8865 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
8866 }
8867 }
8868
8869 return *result;
8870 }
8871
8872 /*!
8873 @brief return a reference to the pointed to value
8874
8875 @note This version does not throw if a value is not present, but tries to
8876 create nested values instead. For instance, calling this function
8877 with pointer `"/this/that"` on a null value is equivalent to calling
8878 `operator[]("this").operator[]("that")` on that value, effectively
8879 changing the null value to an object.
8880
8881 @param[in] ptr a JSON value
8882
8883 @return reference to the JSON value pointed to by the JSON pointer
8884
8885 @complexity Linear in the length of the JSON pointer.
8886
8887 @throw parse_error.106 if an array index begins with '0'
8888 @throw parse_error.109 if an array index was not a number
8889 @throw out_of_range.404 if the JSON pointer can not be resolved
8890 */
get_unchecked(BasicJsonType * ptr) const8891 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
8892 {
8893 using size_type = typename BasicJsonType::size_type;
8894 for (const auto& reference_token : reference_tokens)
8895 {
8896 // convert null values to arrays or objects before continuing
8897 if (ptr->m_type == detail::value_t::null)
8898 {
8899 // check if reference token is a number
8900 const bool nums =
8901 std::all_of(reference_token.begin(), reference_token.end(),
8902 [](const char x)
8903 {
8904 return x >= '0' and x <= '9';
8905 });
8906
8907 // change value to array for numbers or "-" or to object otherwise
8908 *ptr = (nums or reference_token == "-")
8909 ? detail::value_t::array
8910 : detail::value_t::object;
8911 }
8912
8913 switch (ptr->m_type)
8914 {
8915 case detail::value_t::object:
8916 {
8917 // use unchecked object access
8918 ptr = &ptr->operator[](reference_token);
8919 break;
8920 }
8921
8922 case detail::value_t::array:
8923 {
8924 // error condition (cf. RFC 6901, Sect. 4)
8925 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
8926 {
8927 JSON_THROW(detail::parse_error::create(106, 0,
8928 "array index '" + reference_token +
8929 "' must not begin with '0'"));
8930 }
8931
8932 if (reference_token == "-")
8933 {
8934 // explicitly treat "-" as index beyond the end
8935 ptr = &ptr->operator[](ptr->m_value.array->size());
8936 }
8937 else
8938 {
8939 // convert array index to number; unchecked access
8940 JSON_TRY
8941 {
8942 ptr = &ptr->operator[](
8943 static_cast<size_type>(array_index(reference_token)));
8944 }
8945 JSON_CATCH(std::invalid_argument&)
8946 {
8947 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
8948 }
8949 }
8950 break;
8951 }
8952
8953 default:
8954 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
8955 }
8956 }
8957
8958 return *ptr;
8959 }
8960
8961 /*!
8962 @throw parse_error.106 if an array index begins with '0'
8963 @throw parse_error.109 if an array index was not a number
8964 @throw out_of_range.402 if the array index '-' is used
8965 @throw out_of_range.404 if the JSON pointer can not be resolved
8966 */
get_checked(BasicJsonType * ptr) const8967 BasicJsonType& get_checked(BasicJsonType* ptr) const
8968 {
8969 using size_type = typename BasicJsonType::size_type;
8970 for (const auto& reference_token : reference_tokens)
8971 {
8972 switch (ptr->m_type)
8973 {
8974 case detail::value_t::object:
8975 {
8976 // note: at performs range check
8977 ptr = &ptr->at(reference_token);
8978 break;
8979 }
8980
8981 case detail::value_t::array:
8982 {
8983 if (JSON_UNLIKELY(reference_token == "-"))
8984 {
8985 // "-" always fails the range check
8986 JSON_THROW(detail::out_of_range::create(402,
8987 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
8988 ") is out of range"));
8989 }
8990
8991 // error condition (cf. RFC 6901, Sect. 4)
8992 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
8993 {
8994 JSON_THROW(detail::parse_error::create(106, 0,
8995 "array index '" + reference_token +
8996 "' must not begin with '0'"));
8997 }
8998
8999 // note: at performs range check
9000 JSON_TRY
9001 {
9002 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9003 }
9004 JSON_CATCH(std::invalid_argument&)
9005 {
9006 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9007 }
9008 break;
9009 }
9010
9011 default:
9012 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9013 }
9014 }
9015
9016 return *ptr;
9017 }
9018
9019 /*!
9020 @brief return a const reference to the pointed to value
9021
9022 @param[in] ptr a JSON value
9023
9024 @return const reference to the JSON value pointed to by the JSON
9025 pointer
9026
9027 @throw parse_error.106 if an array index begins with '0'
9028 @throw parse_error.109 if an array index was not a number
9029 @throw out_of_range.402 if the array index '-' is used
9030 @throw out_of_range.404 if the JSON pointer can not be resolved
9031 */
get_unchecked(const BasicJsonType * ptr) const9032 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
9033 {
9034 using size_type = typename BasicJsonType::size_type;
9035 for (const auto& reference_token : reference_tokens)
9036 {
9037 switch (ptr->m_type)
9038 {
9039 case detail::value_t::object:
9040 {
9041 // use unchecked object access
9042 ptr = &ptr->operator[](reference_token);
9043 break;
9044 }
9045
9046 case detail::value_t::array:
9047 {
9048 if (JSON_UNLIKELY(reference_token == "-"))
9049 {
9050 // "-" cannot be used for const access
9051 JSON_THROW(detail::out_of_range::create(402,
9052 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9053 ") is out of range"));
9054 }
9055
9056 // error condition (cf. RFC 6901, Sect. 4)
9057 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9058 {
9059 JSON_THROW(detail::parse_error::create(106, 0,
9060 "array index '" + reference_token +
9061 "' must not begin with '0'"));
9062 }
9063
9064 // use unchecked array access
9065 JSON_TRY
9066 {
9067 ptr = &ptr->operator[](
9068 static_cast<size_type>(array_index(reference_token)));
9069 }
9070 JSON_CATCH(std::invalid_argument&)
9071 {
9072 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9073 }
9074 break;
9075 }
9076
9077 default:
9078 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9079 }
9080 }
9081
9082 return *ptr;
9083 }
9084
9085 /*!
9086 @throw parse_error.106 if an array index begins with '0'
9087 @throw parse_error.109 if an array index was not a number
9088 @throw out_of_range.402 if the array index '-' is used
9089 @throw out_of_range.404 if the JSON pointer can not be resolved
9090 */
get_checked(const BasicJsonType * ptr) const9091 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
9092 {
9093 using size_type = typename BasicJsonType::size_type;
9094 for (const auto& reference_token : reference_tokens)
9095 {
9096 switch (ptr->m_type)
9097 {
9098 case detail::value_t::object:
9099 {
9100 // note: at performs range check
9101 ptr = &ptr->at(reference_token);
9102 break;
9103 }
9104
9105 case detail::value_t::array:
9106 {
9107 if (JSON_UNLIKELY(reference_token == "-"))
9108 {
9109 // "-" always fails the range check
9110 JSON_THROW(detail::out_of_range::create(402,
9111 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
9112 ") is out of range"));
9113 }
9114
9115 // error condition (cf. RFC 6901, Sect. 4)
9116 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
9117 {
9118 JSON_THROW(detail::parse_error::create(106, 0,
9119 "array index '" + reference_token +
9120 "' must not begin with '0'"));
9121 }
9122
9123 // note: at performs range check
9124 JSON_TRY
9125 {
9126 ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
9127 }
9128 JSON_CATCH(std::invalid_argument&)
9129 {
9130 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
9131 }
9132 break;
9133 }
9134
9135 default:
9136 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
9137 }
9138 }
9139
9140 return *ptr;
9141 }
9142
9143 /*!
9144 @brief split the string input to reference tokens
9145
9146 @note This function is only called by the json_pointer constructor.
9147 All exceptions below are documented there.
9148
9149 @throw parse_error.107 if the pointer is not empty or begins with '/'
9150 @throw parse_error.108 if character '~' is not followed by '0' or '1'
9151 */
split(const std::string & reference_string)9152 static std::vector<std::string> split(const std::string& reference_string)
9153 {
9154 std::vector<std::string> result;
9155
9156 // special case: empty reference string -> no reference tokens
9157 if (reference_string.empty())
9158 {
9159 return result;
9160 }
9161
9162 // check if nonempty reference string begins with slash
9163 if (JSON_UNLIKELY(reference_string[0] != '/'))
9164 {
9165 JSON_THROW(detail::parse_error::create(107, 1,
9166 "JSON pointer must be empty or begin with '/' - was: '" +
9167 reference_string + "'"));
9168 }
9169
9170 // extract the reference tokens:
9171 // - slash: position of the last read slash (or end of string)
9172 // - start: position after the previous slash
9173 for (
9174 // search for the first slash after the first character
9175 std::size_t slash = reference_string.find_first_of('/', 1),
9176 // set the beginning of the first reference token
9177 start = 1;
9178 // we can stop if start == 0 (if slash == std::string::npos)
9179 start != 0;
9180 // set the beginning of the next reference token
9181 // (will eventually be 0 if slash == std::string::npos)
9182 start = (slash == std::string::npos) ? 0 : slash + 1,
9183 // find next slash
9184 slash = reference_string.find_first_of('/', start))
9185 {
9186 // use the text between the beginning of the reference token
9187 // (start) and the last slash (slash).
9188 auto reference_token = reference_string.substr(start, slash - start);
9189
9190 // check reference tokens are properly escaped
9191 for (std::size_t pos = reference_token.find_first_of('~');
9192 pos != std::string::npos;
9193 pos = reference_token.find_first_of('~', pos + 1))
9194 {
9195 assert(reference_token[pos] == '~');
9196
9197 // ~ must be followed by 0 or 1
9198 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
9199 (reference_token[pos + 1] != '0' and
9200 reference_token[pos + 1] != '1')))
9201 {
9202 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
9203 }
9204 }
9205
9206 // finally, store the reference token
9207 unescape(reference_token);
9208 result.push_back(reference_token);
9209 }
9210
9211 return result;
9212 }
9213
9214 /*!
9215 @brief replace all occurrences of a substring by another string
9216
9217 @param[in,out] s the string to manipulate; changed so that all
9218 occurrences of @a f are replaced with @a t
9219 @param[in] f the substring to replace with @a t
9220 @param[in] t the string to replace @a f
9221
9222 @pre The search string @a f must not be empty. **This precondition is
9223 enforced with an assertion.**
9224
9225 @since version 2.0.0
9226 */
replace_substring(std::string & s,const std::string & f,const std::string & t)9227 static void replace_substring(std::string& s, const std::string& f,
9228 const std::string& t)
9229 {
9230 assert(not f.empty());
9231 for (auto pos = s.find(f); // find first occurrence of f
9232 pos != std::string::npos; // make sure f was found
9233 s.replace(pos, f.size(), t), // replace with t, and
9234 pos = s.find(f, pos + t.size())) // find next occurrence of f
9235 {}
9236 }
9237
9238 /// escape "~" to "~0" and "/" to "~1"
escape(std::string s)9239 static std::string escape(std::string s)
9240 {
9241 replace_substring(s, "~", "~0");
9242 replace_substring(s, "/", "~1");
9243 return s;
9244 }
9245
9246 /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)9247 static void unescape(std::string& s)
9248 {
9249 replace_substring(s, "~1", "/");
9250 replace_substring(s, "~0", "~");
9251 }
9252
9253 /*!
9254 @param[in] reference_string the reference string to the current value
9255 @param[in] value the value to consider
9256 @param[in,out] result the result object to insert values to
9257
9258 @note Empty objects or arrays are flattened to `null`.
9259 */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)9260 static void flatten(const std::string& reference_string,
9261 const BasicJsonType& value,
9262 BasicJsonType& result)
9263 {
9264 switch (value.m_type)
9265 {
9266 case detail::value_t::array:
9267 {
9268 if (value.m_value.array->empty())
9269 {
9270 // flatten empty array as null
9271 result[reference_string] = nullptr;
9272 }
9273 else
9274 {
9275 // iterate array and use index as reference string
9276 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
9277 {
9278 flatten(reference_string + "/" + std::to_string(i),
9279 value.m_value.array->operator[](i), result);
9280 }
9281 }
9282 break;
9283 }
9284
9285 case detail::value_t::object:
9286 {
9287 if (value.m_value.object->empty())
9288 {
9289 // flatten empty object as null
9290 result[reference_string] = nullptr;
9291 }
9292 else
9293 {
9294 // iterate object and use keys as reference string
9295 for (const auto& element : *value.m_value.object)
9296 {
9297 flatten(reference_string + "/" + escape(element.first), element.second, result);
9298 }
9299 }
9300 break;
9301 }
9302
9303 default:
9304 {
9305 // add primitive value with its reference string
9306 result[reference_string] = value;
9307 break;
9308 }
9309 }
9310 }
9311
9312 /*!
9313 @param[in] value flattened JSON
9314
9315 @return unflattened JSON
9316
9317 @throw parse_error.109 if array index is not a number
9318 @throw type_error.314 if value is not an object
9319 @throw type_error.315 if object values are not primitive
9320 @throw type_error.313 if value cannot be unflattened
9321 */
9322 static BasicJsonType
unflatten(const BasicJsonType & value)9323 unflatten(const BasicJsonType& value)
9324 {
9325 if (JSON_UNLIKELY(not value.is_object()))
9326 {
9327 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
9328 }
9329
9330 BasicJsonType result;
9331
9332 // iterate the JSON object values
9333 for (const auto& element : *value.m_value.object)
9334 {
9335 if (JSON_UNLIKELY(not element.second.is_primitive()))
9336 {
9337 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
9338 }
9339
9340 // assign value to reference pointed to by JSON pointer; Note that if
9341 // the JSON pointer is "" (i.e., points to the whole value), function
9342 // get_and_create returns a reference to result itself. An assignment
9343 // will then create a primitive value.
9344 json_pointer(element.first).get_and_create(result) = element.second;
9345 }
9346
9347 return result;
9348 }
9349
9350 /*!
9351 @brief compares two JSON pointers for equality
9352
9353 @param[in] lhs JSON pointer to compare
9354 @param[in] rhs JSON pointer to compare
9355 @return whether @a lhs is equal to @a rhs
9356
9357 @complexity Linear in the length of the JSON pointer
9358
9359 @exceptionsafety No-throw guarantee: this function never throws exceptions.
9360 */
operator ==(json_pointer const & lhs,json_pointer const & rhs)9361 friend bool operator==(json_pointer const& lhs,
9362 json_pointer const& rhs) noexcept
9363 {
9364 return lhs.reference_tokens == rhs.reference_tokens;
9365 }
9366
9367 /*!
9368 @brief compares two JSON pointers for inequality
9369
9370 @param[in] lhs JSON pointer to compare
9371 @param[in] rhs JSON pointer to compare
9372 @return whether @a lhs is not equal @a rhs
9373
9374 @complexity Linear in the length of the JSON pointer
9375
9376 @exceptionsafety No-throw guarantee: this function never throws exceptions.
9377 */
operator !=(json_pointer const & lhs,json_pointer const & rhs)9378 friend bool operator!=(json_pointer const& lhs,
9379 json_pointer const& rhs) noexcept
9380 {
9381 return not (lhs == rhs);
9382 }
9383
9384 /// the reference tokens
9385 std::vector<std::string> reference_tokens;
9386 };
9387 } // namespace nlohmann
9388
9389 // #include <nlohmann/detail/json_ref.hpp>
9390
9391
9392 #include <initializer_list>
9393 #include <utility>
9394
9395 // #include <nlohmann/detail/meta/type_traits.hpp>
9396
9397
9398 namespace nlohmann
9399 {
9400 namespace detail
9401 {
9402 template<typename BasicJsonType>
9403 class json_ref
9404 {
9405 public:
9406 using value_type = BasicJsonType;
9407
json_ref(value_type && value)9408 json_ref(value_type&& value)
9409 : owned_value(std::move(value)), value_ref(&owned_value), is_rvalue(true)
9410 {}
9411
json_ref(const value_type & value)9412 json_ref(const value_type& value)
9413 : value_ref(const_cast<value_type*>(&value)), is_rvalue(false)
9414 {}
9415
json_ref(std::initializer_list<json_ref> init)9416 json_ref(std::initializer_list<json_ref> init)
9417 : owned_value(init), value_ref(&owned_value), is_rvalue(true)
9418 {}
9419
9420 template <
9421 class... Args,
9422 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)9423 json_ref(Args && ... args)
9424 : owned_value(std::forward<Args>(args)...), value_ref(&owned_value),
9425 is_rvalue(true) {}
9426
9427 // class should be movable only
9428 json_ref(json_ref&&) = default;
9429 json_ref(const json_ref&) = delete;
9430 json_ref& operator=(const json_ref&) = delete;
9431 json_ref& operator=(json_ref&&) = delete;
9432 ~json_ref() = default;
9433
moved_or_copied() const9434 value_type moved_or_copied() const
9435 {
9436 if (is_rvalue)
9437 {
9438 return std::move(*value_ref);
9439 }
9440 return *value_ref;
9441 }
9442
operator *() const9443 value_type const& operator*() const
9444 {
9445 return *static_cast<value_type const*>(value_ref);
9446 }
9447
operator ->() const9448 value_type const* operator->() const
9449 {
9450 return static_cast<value_type const*>(value_ref);
9451 }
9452
9453 private:
9454 mutable value_type owned_value = nullptr;
9455 value_type* value_ref = nullptr;
9456 const bool is_rvalue;
9457 };
9458 } // namespace detail
9459 } // namespace nlohmann
9460
9461 // #include <nlohmann/detail/macro_scope.hpp>
9462
9463 // #include <nlohmann/detail/meta/cpp_future.hpp>
9464
9465 // #include <nlohmann/detail/meta/type_traits.hpp>
9466
9467 // #include <nlohmann/detail/output/binary_writer.hpp>
9468
9469
9470 #include <algorithm> // reverse
9471 #include <array> // array
9472 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
9473 #include <cstring> // memcpy
9474 #include <limits> // numeric_limits
9475 #include <string> // string
9476
9477 // #include <nlohmann/detail/input/binary_reader.hpp>
9478
9479 // #include <nlohmann/detail/output/output_adapters.hpp>
9480
9481
9482 #include <algorithm> // copy
9483 #include <cstddef> // size_t
9484 #include <ios> // streamsize
9485 #include <iterator> // back_inserter
9486 #include <memory> // shared_ptr, make_shared
9487 #include <ostream> // basic_ostream
9488 #include <string> // basic_string
9489 #include <vector> // vector
9490
9491 namespace nlohmann
9492 {
9493 namespace detail
9494 {
9495 /// abstract output adapter interface
9496 template<typename CharType> struct output_adapter_protocol
9497 {
9498 virtual void write_character(CharType c) = 0;
9499 virtual void write_characters(const CharType* s, std::size_t length) = 0;
9500 virtual ~output_adapter_protocol() = default;
9501 };
9502
9503 /// a type to simplify interfaces
9504 template<typename CharType>
9505 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
9506
9507 /// output adapter for byte vectors
9508 template<typename CharType>
9509 class output_vector_adapter : public output_adapter_protocol<CharType>
9510 {
9511 public:
output_vector_adapter(std::vector<CharType> & vec)9512 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
9513 : v(vec)
9514 {}
9515
write_character(CharType c)9516 void write_character(CharType c) override
9517 {
9518 v.push_back(c);
9519 }
9520
write_characters(const CharType * s,std::size_t length)9521 void write_characters(const CharType* s, std::size_t length) override
9522 {
9523 std::copy(s, s + length, std::back_inserter(v));
9524 }
9525
9526 private:
9527 std::vector<CharType>& v;
9528 };
9529
9530 /// output adapter for output streams
9531 template<typename CharType>
9532 class output_stream_adapter : public output_adapter_protocol<CharType>
9533 {
9534 public:
output_stream_adapter(std::basic_ostream<CharType> & s)9535 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
9536 : stream(s)
9537 {}
9538
write_character(CharType c)9539 void write_character(CharType c) override
9540 {
9541 stream.put(c);
9542 }
9543
write_characters(const CharType * s,std::size_t length)9544 void write_characters(const CharType* s, std::size_t length) override
9545 {
9546 stream.write(s, static_cast<std::streamsize>(length));
9547 }
9548
9549 private:
9550 std::basic_ostream<CharType>& stream;
9551 };
9552
9553 /// output adapter for basic_string
9554 template<typename CharType, typename StringType = std::basic_string<CharType>>
9555 class output_string_adapter : public output_adapter_protocol<CharType>
9556 {
9557 public:
output_string_adapter(StringType & s)9558 explicit output_string_adapter(StringType& s) noexcept
9559 : str(s)
9560 {}
9561
write_character(CharType c)9562 void write_character(CharType c) override
9563 {
9564 str.push_back(c);
9565 }
9566
write_characters(const CharType * s,std::size_t length)9567 void write_characters(const CharType* s, std::size_t length) override
9568 {
9569 str.append(s, length);
9570 }
9571
9572 private:
9573 StringType& str;
9574 };
9575
9576 template<typename CharType, typename StringType = std::basic_string<CharType>>
9577 class output_adapter
9578 {
9579 public:
output_adapter(std::vector<CharType> & vec)9580 output_adapter(std::vector<CharType>& vec)
9581 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
9582
output_adapter(std::basic_ostream<CharType> & s)9583 output_adapter(std::basic_ostream<CharType>& s)
9584 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
9585
output_adapter(StringType & s)9586 output_adapter(StringType& s)
9587 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
9588
operator output_adapter_t<CharType>()9589 operator output_adapter_t<CharType>()
9590 {
9591 return oa;
9592 }
9593
9594 private:
9595 output_adapter_t<CharType> oa = nullptr;
9596 };
9597 } // namespace detail
9598 } // namespace nlohmann
9599
9600
9601 namespace nlohmann
9602 {
9603 namespace detail
9604 {
9605 ///////////////////
9606 // binary writer //
9607 ///////////////////
9608
9609 /*!
9610 @brief serialization to CBOR and MessagePack values
9611 */
9612 template<typename BasicJsonType, typename CharType>
9613 class binary_writer
9614 {
9615 using string_t = typename BasicJsonType::string_t;
9616
9617 public:
9618 /*!
9619 @brief create a binary writer
9620
9621 @param[in] adapter output adapter to write to
9622 */
binary_writer(output_adapter_t<CharType> adapter)9623 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
9624 {
9625 assert(oa);
9626 }
9627
9628 /*!
9629 @param[in] j JSON value to serialize
9630 @pre j.type() == value_t::object
9631 */
write_bson(const BasicJsonType & j)9632 void write_bson(const BasicJsonType& j)
9633 {
9634 switch (j.type())
9635 {
9636 case value_t::object:
9637 {
9638 write_bson_object(*j.m_value.object);
9639 break;
9640 }
9641
9642 default:
9643 {
9644 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name())));
9645 }
9646 }
9647 }
9648
9649 /*!
9650 @param[in] j JSON value to serialize
9651 */
write_cbor(const BasicJsonType & j)9652 void write_cbor(const BasicJsonType& j)
9653 {
9654 switch (j.type())
9655 {
9656 case value_t::null:
9657 {
9658 oa->write_character(to_char_type(0xF6));
9659 break;
9660 }
9661
9662 case value_t::boolean:
9663 {
9664 oa->write_character(j.m_value.boolean
9665 ? to_char_type(0xF5)
9666 : to_char_type(0xF4));
9667 break;
9668 }
9669
9670 case value_t::number_integer:
9671 {
9672 if (j.m_value.number_integer >= 0)
9673 {
9674 // CBOR does not differentiate between positive signed
9675 // integers and unsigned integers. Therefore, we used the
9676 // code from the value_t::number_unsigned case here.
9677 if (j.m_value.number_integer <= 0x17)
9678 {
9679 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9680 }
9681 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
9682 {
9683 oa->write_character(to_char_type(0x18));
9684 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9685 }
9686 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
9687 {
9688 oa->write_character(to_char_type(0x19));
9689 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9690 }
9691 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
9692 {
9693 oa->write_character(to_char_type(0x1A));
9694 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9695 }
9696 else
9697 {
9698 oa->write_character(to_char_type(0x1B));
9699 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9700 }
9701 }
9702 else
9703 {
9704 // The conversions below encode the sign in the first
9705 // byte, and the value is converted to a positive number.
9706 const auto positive_number = -1 - j.m_value.number_integer;
9707 if (j.m_value.number_integer >= -24)
9708 {
9709 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
9710 }
9711 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
9712 {
9713 oa->write_character(to_char_type(0x38));
9714 write_number(static_cast<std::uint8_t>(positive_number));
9715 }
9716 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
9717 {
9718 oa->write_character(to_char_type(0x39));
9719 write_number(static_cast<std::uint16_t>(positive_number));
9720 }
9721 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
9722 {
9723 oa->write_character(to_char_type(0x3A));
9724 write_number(static_cast<std::uint32_t>(positive_number));
9725 }
9726 else
9727 {
9728 oa->write_character(to_char_type(0x3B));
9729 write_number(static_cast<std::uint64_t>(positive_number));
9730 }
9731 }
9732 break;
9733 }
9734
9735 case value_t::number_unsigned:
9736 {
9737 if (j.m_value.number_unsigned <= 0x17)
9738 {
9739 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
9740 }
9741 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9742 {
9743 oa->write_character(to_char_type(0x18));
9744 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
9745 }
9746 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9747 {
9748 oa->write_character(to_char_type(0x19));
9749 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
9750 }
9751 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9752 {
9753 oa->write_character(to_char_type(0x1A));
9754 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
9755 }
9756 else
9757 {
9758 oa->write_character(to_char_type(0x1B));
9759 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
9760 }
9761 break;
9762 }
9763
9764 case value_t::number_float:
9765 {
9766 oa->write_character(get_cbor_float_prefix(j.m_value.number_float));
9767 write_number(j.m_value.number_float);
9768 break;
9769 }
9770
9771 case value_t::string:
9772 {
9773 // step 1: write control byte and the string length
9774 const auto N = j.m_value.string->size();
9775 if (N <= 0x17)
9776 {
9777 write_number(static_cast<std::uint8_t>(0x60 + N));
9778 }
9779 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9780 {
9781 oa->write_character(to_char_type(0x78));
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(0x79));
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(0x7A));
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(0x7B));
9798 write_number(static_cast<std::uint64_t>(N));
9799 }
9800 // LCOV_EXCL_STOP
9801
9802 // step 2: write the string
9803 oa->write_characters(
9804 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
9805 j.m_value.string->size());
9806 break;
9807 }
9808
9809 case value_t::array:
9810 {
9811 // step 1: write control byte and the array size
9812 const auto N = j.m_value.array->size();
9813 if (N <= 0x17)
9814 {
9815 write_number(static_cast<std::uint8_t>(0x80 + N));
9816 }
9817 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9818 {
9819 oa->write_character(to_char_type(0x98));
9820 write_number(static_cast<std::uint8_t>(N));
9821 }
9822 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9823 {
9824 oa->write_character(to_char_type(0x99));
9825 write_number(static_cast<std::uint16_t>(N));
9826 }
9827 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9828 {
9829 oa->write_character(to_char_type(0x9A));
9830 write_number(static_cast<std::uint32_t>(N));
9831 }
9832 // LCOV_EXCL_START
9833 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9834 {
9835 oa->write_character(to_char_type(0x9B));
9836 write_number(static_cast<std::uint64_t>(N));
9837 }
9838 // LCOV_EXCL_STOP
9839
9840 // step 2: write each element
9841 for (const auto& el : *j.m_value.array)
9842 {
9843 write_cbor(el);
9844 }
9845 break;
9846 }
9847
9848 case value_t::object:
9849 {
9850 // step 1: write control byte and the object size
9851 const auto N = j.m_value.object->size();
9852 if (N <= 0x17)
9853 {
9854 write_number(static_cast<std::uint8_t>(0xA0 + N));
9855 }
9856 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
9857 {
9858 oa->write_character(to_char_type(0xB8));
9859 write_number(static_cast<std::uint8_t>(N));
9860 }
9861 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
9862 {
9863 oa->write_character(to_char_type(0xB9));
9864 write_number(static_cast<std::uint16_t>(N));
9865 }
9866 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
9867 {
9868 oa->write_character(to_char_type(0xBA));
9869 write_number(static_cast<std::uint32_t>(N));
9870 }
9871 // LCOV_EXCL_START
9872 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
9873 {
9874 oa->write_character(to_char_type(0xBB));
9875 write_number(static_cast<std::uint64_t>(N));
9876 }
9877 // LCOV_EXCL_STOP
9878
9879 // step 2: write each element
9880 for (const auto& el : *j.m_value.object)
9881 {
9882 write_cbor(el.first);
9883 write_cbor(el.second);
9884 }
9885 break;
9886 }
9887
9888 default:
9889 break;
9890 }
9891 }
9892
9893 /*!
9894 @param[in] j JSON value to serialize
9895 */
write_msgpack(const BasicJsonType & j)9896 void write_msgpack(const BasicJsonType& j)
9897 {
9898 switch (j.type())
9899 {
9900 case value_t::null: // nil
9901 {
9902 oa->write_character(to_char_type(0xC0));
9903 break;
9904 }
9905
9906 case value_t::boolean: // true and false
9907 {
9908 oa->write_character(j.m_value.boolean
9909 ? to_char_type(0xC3)
9910 : to_char_type(0xC2));
9911 break;
9912 }
9913
9914 case value_t::number_integer:
9915 {
9916 if (j.m_value.number_integer >= 0)
9917 {
9918 // MessagePack does not differentiate between positive
9919 // signed integers and unsigned integers. Therefore, we used
9920 // the code from the value_t::number_unsigned case here.
9921 if (j.m_value.number_unsigned < 128)
9922 {
9923 // positive fixnum
9924 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9925 }
9926 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9927 {
9928 // uint 8
9929 oa->write_character(to_char_type(0xCC));
9930 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9931 }
9932 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
9933 {
9934 // uint 16
9935 oa->write_character(to_char_type(0xCD));
9936 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
9937 }
9938 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
9939 {
9940 // uint 32
9941 oa->write_character(to_char_type(0xCE));
9942 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
9943 }
9944 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
9945 {
9946 // uint 64
9947 oa->write_character(to_char_type(0xCF));
9948 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
9949 }
9950 }
9951 else
9952 {
9953 if (j.m_value.number_integer >= -32)
9954 {
9955 // negative fixnum
9956 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
9957 }
9958 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() and
9959 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
9960 {
9961 // int 8
9962 oa->write_character(to_char_type(0xD0));
9963 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
9964 }
9965 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() and
9966 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
9967 {
9968 // int 16
9969 oa->write_character(to_char_type(0xD1));
9970 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
9971 }
9972 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() and
9973 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
9974 {
9975 // int 32
9976 oa->write_character(to_char_type(0xD2));
9977 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
9978 }
9979 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() and
9980 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
9981 {
9982 // int 64
9983 oa->write_character(to_char_type(0xD3));
9984 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
9985 }
9986 }
9987 break;
9988 }
9989
9990 case value_t::number_unsigned:
9991 {
9992 if (j.m_value.number_unsigned < 128)
9993 {
9994 // positive fixnum
9995 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
9996 }
9997 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
9998 {
9999 // uint 8
10000 oa->write_character(to_char_type(0xCC));
10001 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
10002 }
10003 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
10004 {
10005 // uint 16
10006 oa->write_character(to_char_type(0xCD));
10007 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
10008 }
10009 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
10010 {
10011 // uint 32
10012 oa->write_character(to_char_type(0xCE));
10013 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
10014 }
10015 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
10016 {
10017 // uint 64
10018 oa->write_character(to_char_type(0xCF));
10019 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
10020 }
10021 break;
10022 }
10023
10024 case value_t::number_float:
10025 {
10026 oa->write_character(get_msgpack_float_prefix(j.m_value.number_float));
10027 write_number(j.m_value.number_float);
10028 break;
10029 }
10030
10031 case value_t::string:
10032 {
10033 // step 1: write control byte and the string length
10034 const auto N = j.m_value.string->size();
10035 if (N <= 31)
10036 {
10037 // fixstr
10038 write_number(static_cast<std::uint8_t>(0xA0 | N));
10039 }
10040 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
10041 {
10042 // str 8
10043 oa->write_character(to_char_type(0xD9));
10044 write_number(static_cast<std::uint8_t>(N));
10045 }
10046 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10047 {
10048 // str 16
10049 oa->write_character(to_char_type(0xDA));
10050 write_number(static_cast<std::uint16_t>(N));
10051 }
10052 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10053 {
10054 // str 32
10055 oa->write_character(to_char_type(0xDB));
10056 write_number(static_cast<std::uint32_t>(N));
10057 }
10058
10059 // step 2: write the string
10060 oa->write_characters(
10061 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
10062 j.m_value.string->size());
10063 break;
10064 }
10065
10066 case value_t::array:
10067 {
10068 // step 1: write control byte and the array size
10069 const auto N = j.m_value.array->size();
10070 if (N <= 15)
10071 {
10072 // fixarray
10073 write_number(static_cast<std::uint8_t>(0x90 | N));
10074 }
10075 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10076 {
10077 // array 16
10078 oa->write_character(to_char_type(0xDC));
10079 write_number(static_cast<std::uint16_t>(N));
10080 }
10081 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10082 {
10083 // array 32
10084 oa->write_character(to_char_type(0xDD));
10085 write_number(static_cast<std::uint32_t>(N));
10086 }
10087
10088 // step 2: write each element
10089 for (const auto& el : *j.m_value.array)
10090 {
10091 write_msgpack(el);
10092 }
10093 break;
10094 }
10095
10096 case value_t::object:
10097 {
10098 // step 1: write control byte and the object size
10099 const auto N = j.m_value.object->size();
10100 if (N <= 15)
10101 {
10102 // fixmap
10103 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
10104 }
10105 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
10106 {
10107 // map 16
10108 oa->write_character(to_char_type(0xDE));
10109 write_number(static_cast<std::uint16_t>(N));
10110 }
10111 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
10112 {
10113 // map 32
10114 oa->write_character(to_char_type(0xDF));
10115 write_number(static_cast<std::uint32_t>(N));
10116 }
10117
10118 // step 2: write each element
10119 for (const auto& el : *j.m_value.object)
10120 {
10121 write_msgpack(el.first);
10122 write_msgpack(el.second);
10123 }
10124 break;
10125 }
10126
10127 default:
10128 break;
10129 }
10130 }
10131
10132 /*!
10133 @param[in] j JSON value to serialize
10134 @param[in] use_count whether to use '#' prefixes (optimized format)
10135 @param[in] use_type whether to use '$' prefixes (optimized format)
10136 @param[in] add_prefix whether prefixes need to be used for this value
10137 */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)10138 void write_ubjson(const BasicJsonType& j, const bool use_count,
10139 const bool use_type, const bool add_prefix = true)
10140 {
10141 switch (j.type())
10142 {
10143 case value_t::null:
10144 {
10145 if (add_prefix)
10146 {
10147 oa->write_character(to_char_type('Z'));
10148 }
10149 break;
10150 }
10151
10152 case value_t::boolean:
10153 {
10154 if (add_prefix)
10155 {
10156 oa->write_character(j.m_value.boolean
10157 ? to_char_type('T')
10158 : to_char_type('F'));
10159 }
10160 break;
10161 }
10162
10163 case value_t::number_integer:
10164 {
10165 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
10166 break;
10167 }
10168
10169 case value_t::number_unsigned:
10170 {
10171 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
10172 break;
10173 }
10174
10175 case value_t::number_float:
10176 {
10177 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
10178 break;
10179 }
10180
10181 case value_t::string:
10182 {
10183 if (add_prefix)
10184 {
10185 oa->write_character(to_char_type('S'));
10186 }
10187 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
10188 oa->write_characters(
10189 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
10190 j.m_value.string->size());
10191 break;
10192 }
10193
10194 case value_t::array:
10195 {
10196 if (add_prefix)
10197 {
10198 oa->write_character(to_char_type('['));
10199 }
10200
10201 bool prefix_required = true;
10202 if (use_type and not j.m_value.array->empty())
10203 {
10204 assert(use_count);
10205 const CharType first_prefix = ubjson_prefix(j.front());
10206 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
10207 [this, first_prefix](const BasicJsonType & v)
10208 {
10209 return ubjson_prefix(v) == first_prefix;
10210 });
10211
10212 if (same_prefix)
10213 {
10214 prefix_required = false;
10215 oa->write_character(to_char_type('$'));
10216 oa->write_character(first_prefix);
10217 }
10218 }
10219
10220 if (use_count)
10221 {
10222 oa->write_character(to_char_type('#'));
10223 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
10224 }
10225
10226 for (const auto& el : *j.m_value.array)
10227 {
10228 write_ubjson(el, use_count, use_type, prefix_required);
10229 }
10230
10231 if (not use_count)
10232 {
10233 oa->write_character(to_char_type(']'));
10234 }
10235
10236 break;
10237 }
10238
10239 case value_t::object:
10240 {
10241 if (add_prefix)
10242 {
10243 oa->write_character(to_char_type('{'));
10244 }
10245
10246 bool prefix_required = true;
10247 if (use_type and not j.m_value.object->empty())
10248 {
10249 assert(use_count);
10250 const CharType first_prefix = ubjson_prefix(j.front());
10251 const bool same_prefix = std::all_of(j.begin(), j.end(),
10252 [this, first_prefix](const BasicJsonType & v)
10253 {
10254 return ubjson_prefix(v) == first_prefix;
10255 });
10256
10257 if (same_prefix)
10258 {
10259 prefix_required = false;
10260 oa->write_character(to_char_type('$'));
10261 oa->write_character(first_prefix);
10262 }
10263 }
10264
10265 if (use_count)
10266 {
10267 oa->write_character(to_char_type('#'));
10268 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
10269 }
10270
10271 for (const auto& el : *j.m_value.object)
10272 {
10273 write_number_with_ubjson_prefix(el.first.size(), true);
10274 oa->write_characters(
10275 reinterpret_cast<const CharType*>(el.first.c_str()),
10276 el.first.size());
10277 write_ubjson(el.second, use_count, use_type, prefix_required);
10278 }
10279
10280 if (not use_count)
10281 {
10282 oa->write_character(to_char_type('}'));
10283 }
10284
10285 break;
10286 }
10287
10288 default:
10289 break;
10290 }
10291 }
10292
10293 private:
10294 //////////
10295 // BSON //
10296 //////////
10297
10298 /*!
10299 @return The size of a BSON document entry header, including the id marker
10300 and the entry name size (and its null-terminator).
10301 */
calc_bson_entry_header_size(const string_t & name)10302 static std::size_t calc_bson_entry_header_size(const string_t& name)
10303 {
10304 const auto it = name.find(static_cast<typename string_t::value_type>(0));
10305 if (JSON_UNLIKELY(it != BasicJsonType::string_t::npos))
10306 {
10307 JSON_THROW(out_of_range::create(409,
10308 "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")"));
10309 }
10310
10311 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
10312 }
10313
10314 /*!
10315 @brief Writes the given @a element_type and @a name to the output adapter
10316 */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)10317 void write_bson_entry_header(const string_t& name,
10318 const std::uint8_t element_type)
10319 {
10320 oa->write_character(to_char_type(element_type)); // boolean
10321 oa->write_characters(
10322 reinterpret_cast<const CharType*>(name.c_str()),
10323 name.size() + 1u);
10324 }
10325
10326 /*!
10327 @brief Writes a BSON element with key @a name and boolean value @a value
10328 */
write_bson_boolean(const string_t & name,const bool value)10329 void write_bson_boolean(const string_t& name,
10330 const bool value)
10331 {
10332 write_bson_entry_header(name, 0x08);
10333 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
10334 }
10335
10336 /*!
10337 @brief Writes a BSON element with key @a name and double value @a value
10338 */
write_bson_double(const string_t & name,const double value)10339 void write_bson_double(const string_t& name,
10340 const double value)
10341 {
10342 write_bson_entry_header(name, 0x01);
10343 write_number<double, true>(value);
10344 }
10345
10346 /*!
10347 @return The size of the BSON-encoded string in @a value
10348 */
calc_bson_string_size(const string_t & value)10349 static std::size_t calc_bson_string_size(const string_t& value)
10350 {
10351 return sizeof(std::int32_t) + value.size() + 1ul;
10352 }
10353
10354 /*!
10355 @brief Writes a BSON element with key @a name and string value @a value
10356 */
write_bson_string(const string_t & name,const string_t & value)10357 void write_bson_string(const string_t& name,
10358 const string_t& value)
10359 {
10360 write_bson_entry_header(name, 0x02);
10361
10362 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
10363 oa->write_characters(
10364 reinterpret_cast<const CharType*>(value.c_str()),
10365 value.size() + 1);
10366 }
10367
10368 /*!
10369 @brief Writes a BSON element with key @a name and null value
10370 */
write_bson_null(const string_t & name)10371 void write_bson_null(const string_t& name)
10372 {
10373 write_bson_entry_header(name, 0x0A);
10374 }
10375
10376 /*!
10377 @return The size of the BSON-encoded integer @a value
10378 */
calc_bson_integer_size(const std::int64_t value)10379 static std::size_t calc_bson_integer_size(const std::int64_t value)
10380 {
10381 return (std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)()
10382 ? sizeof(std::int32_t)
10383 : sizeof(std::int64_t);
10384 }
10385
10386 /*!
10387 @brief Writes a BSON element with key @a name and integer @a value
10388 */
write_bson_integer(const string_t & name,const std::int64_t value)10389 void write_bson_integer(const string_t& name,
10390 const std::int64_t value)
10391 {
10392 if ((std::numeric_limits<std::int32_t>::min)() <= value and value <= (std::numeric_limits<std::int32_t>::max)())
10393 {
10394 write_bson_entry_header(name, 0x10); // int32
10395 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
10396 }
10397 else
10398 {
10399 write_bson_entry_header(name, 0x12); // int64
10400 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
10401 }
10402 }
10403
10404 /*!
10405 @return The size of the BSON-encoded unsigned integer in @a j
10406 */
calc_bson_unsigned_size(const std::uint64_t value)10407 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
10408 {
10409 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10410 ? sizeof(std::int32_t)
10411 : sizeof(std::int64_t);
10412 }
10413
10414 /*!
10415 @brief Writes a BSON element with key @a name and unsigned @a value
10416 */
write_bson_unsigned(const string_t & name,const std::uint64_t value)10417 void write_bson_unsigned(const string_t& name,
10418 const std::uint64_t value)
10419 {
10420 if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10421 {
10422 write_bson_entry_header(name, 0x10 /* int32 */);
10423 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
10424 }
10425 else if (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10426 {
10427 write_bson_entry_header(name, 0x12 /* int64 */);
10428 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
10429 }
10430 else
10431 {
10432 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(value) + " cannot be represented by BSON as it does not fit int64"));
10433 }
10434 }
10435
10436 /*!
10437 @brief Writes a BSON element with key @a name and object @a value
10438 */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)10439 void write_bson_object_entry(const string_t& name,
10440 const typename BasicJsonType::object_t& value)
10441 {
10442 write_bson_entry_header(name, 0x03); // object
10443 write_bson_object(value);
10444 }
10445
10446 /*!
10447 @return The size of the BSON-encoded array @a value
10448 */
calc_bson_array_size(const typename BasicJsonType::array_t & value)10449 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
10450 {
10451 std::size_t embedded_document_size = 0ul;
10452 std::size_t array_index = 0ul;
10453
10454 for (const auto& el : value)
10455 {
10456 embedded_document_size += calc_bson_element_size(std::to_string(array_index++), el);
10457 }
10458
10459 return sizeof(std::int32_t) + embedded_document_size + 1ul;
10460 }
10461
10462 /*!
10463 @brief Writes a BSON element with key @a name and array @a value
10464 */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)10465 void write_bson_array(const string_t& name,
10466 const typename BasicJsonType::array_t& value)
10467 {
10468 write_bson_entry_header(name, 0x04); // array
10469 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
10470
10471 std::size_t array_index = 0ul;
10472
10473 for (const auto& el : value)
10474 {
10475 write_bson_element(std::to_string(array_index++), el);
10476 }
10477
10478 oa->write_character(to_char_type(0x00));
10479 }
10480
10481 /*!
10482 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
10483 @return The calculated size for the BSON document entry for @a j with the given @a name.
10484 */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)10485 static std::size_t calc_bson_element_size(const string_t& name,
10486 const BasicJsonType& j)
10487 {
10488 const auto header_size = calc_bson_entry_header_size(name);
10489 switch (j.type())
10490 {
10491 case value_t::object:
10492 return header_size + calc_bson_object_size(*j.m_value.object);
10493
10494 case value_t::array:
10495 return header_size + calc_bson_array_size(*j.m_value.array);
10496
10497 case value_t::boolean:
10498 return header_size + 1ul;
10499
10500 case value_t::number_float:
10501 return header_size + 8ul;
10502
10503 case value_t::number_integer:
10504 return header_size + calc_bson_integer_size(j.m_value.number_integer);
10505
10506 case value_t::number_unsigned:
10507 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
10508
10509 case value_t::string:
10510 return header_size + calc_bson_string_size(*j.m_value.string);
10511
10512 case value_t::null:
10513 return header_size + 0ul;
10514
10515 // LCOV_EXCL_START
10516 default:
10517 assert(false);
10518 return 0ul;
10519 // LCOV_EXCL_STOP
10520 }
10521 }
10522
10523 /*!
10524 @brief Serializes the JSON value @a j to BSON and associates it with the
10525 key @a name.
10526 @param name The name to associate with the JSON entity @a j within the
10527 current BSON document
10528 @return The size of the BSON entry
10529 */
write_bson_element(const string_t & name,const BasicJsonType & j)10530 void write_bson_element(const string_t& name,
10531 const BasicJsonType& j)
10532 {
10533 switch (j.type())
10534 {
10535 case value_t::object:
10536 return write_bson_object_entry(name, *j.m_value.object);
10537
10538 case value_t::array:
10539 return write_bson_array(name, *j.m_value.array);
10540
10541 case value_t::boolean:
10542 return write_bson_boolean(name, j.m_value.boolean);
10543
10544 case value_t::number_float:
10545 return write_bson_double(name, j.m_value.number_float);
10546
10547 case value_t::number_integer:
10548 return write_bson_integer(name, j.m_value.number_integer);
10549
10550 case value_t::number_unsigned:
10551 return write_bson_unsigned(name, j.m_value.number_unsigned);
10552
10553 case value_t::string:
10554 return write_bson_string(name, *j.m_value.string);
10555
10556 case value_t::null:
10557 return write_bson_null(name);
10558
10559 // LCOV_EXCL_START
10560 default:
10561 assert(false);
10562 return;
10563 // LCOV_EXCL_STOP
10564 }
10565 }
10566
10567 /*!
10568 @brief Calculates the size of the BSON serialization of the given
10569 JSON-object @a j.
10570 @param[in] j JSON value to serialize
10571 @pre j.type() == value_t::object
10572 */
calc_bson_object_size(const typename BasicJsonType::object_t & value)10573 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
10574 {
10575 std::size_t document_size = std::accumulate(value.begin(), value.end(), 0ul,
10576 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
10577 {
10578 return result += calc_bson_element_size(el.first, el.second);
10579 });
10580
10581 return sizeof(std::int32_t) + document_size + 1ul;
10582 }
10583
10584 /*!
10585 @param[in] j JSON value to serialize
10586 @pre j.type() == value_t::object
10587 */
write_bson_object(const typename BasicJsonType::object_t & value)10588 void write_bson_object(const typename BasicJsonType::object_t& value)
10589 {
10590 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
10591
10592 for (const auto& el : value)
10593 {
10594 write_bson_element(el.first, el.second);
10595 }
10596
10597 oa->write_character(to_char_type(0x00));
10598 }
10599
10600 //////////
10601 // CBOR //
10602 //////////
10603
get_cbor_float_prefix(float)10604 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
10605 {
10606 return to_char_type(0xFA); // Single-Precision Float
10607 }
10608
get_cbor_float_prefix(double)10609 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
10610 {
10611 return to_char_type(0xFB); // Double-Precision Float
10612 }
10613
10614 /////////////
10615 // MsgPack //
10616 /////////////
10617
get_msgpack_float_prefix(float)10618 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
10619 {
10620 return to_char_type(0xCA); // float 32
10621 }
10622
get_msgpack_float_prefix(double)10623 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
10624 {
10625 return to_char_type(0xCB); // float 64
10626 }
10627
10628 ////////////
10629 // UBJSON //
10630 ////////////
10631
10632 // UBJSON: write number (floating point)
10633 template<typename NumberType, typename std::enable_if<
10634 std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10635 void write_number_with_ubjson_prefix(const NumberType n,
10636 const bool add_prefix)
10637 {
10638 if (add_prefix)
10639 {
10640 oa->write_character(get_ubjson_float_prefix(n));
10641 }
10642 write_number(n);
10643 }
10644
10645 // UBJSON: write number (unsigned integer)
10646 template<typename NumberType, typename std::enable_if<
10647 std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10648 void write_number_with_ubjson_prefix(const NumberType n,
10649 const bool add_prefix)
10650 {
10651 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
10652 {
10653 if (add_prefix)
10654 {
10655 oa->write_character(to_char_type('i')); // int8
10656 }
10657 write_number(static_cast<std::uint8_t>(n));
10658 }
10659 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
10660 {
10661 if (add_prefix)
10662 {
10663 oa->write_character(to_char_type('U')); // uint8
10664 }
10665 write_number(static_cast<std::uint8_t>(n));
10666 }
10667 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
10668 {
10669 if (add_prefix)
10670 {
10671 oa->write_character(to_char_type('I')); // int16
10672 }
10673 write_number(static_cast<std::int16_t>(n));
10674 }
10675 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
10676 {
10677 if (add_prefix)
10678 {
10679 oa->write_character(to_char_type('l')); // int32
10680 }
10681 write_number(static_cast<std::int32_t>(n));
10682 }
10683 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
10684 {
10685 if (add_prefix)
10686 {
10687 oa->write_character(to_char_type('L')); // int64
10688 }
10689 write_number(static_cast<std::int64_t>(n));
10690 }
10691 else
10692 {
10693 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
10694 }
10695 }
10696
10697 // UBJSON: write number (signed integer)
10698 template<typename NumberType, typename std::enable_if<
10699 std::is_signed<NumberType>::value and
10700 not std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)10701 void write_number_with_ubjson_prefix(const NumberType n,
10702 const bool add_prefix)
10703 {
10704 if ((std::numeric_limits<std::int8_t>::min)() <= n and n <= (std::numeric_limits<std::int8_t>::max)())
10705 {
10706 if (add_prefix)
10707 {
10708 oa->write_character(to_char_type('i')); // int8
10709 }
10710 write_number(static_cast<std::int8_t>(n));
10711 }
10712 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)()))
10713 {
10714 if (add_prefix)
10715 {
10716 oa->write_character(to_char_type('U')); // uint8
10717 }
10718 write_number(static_cast<std::uint8_t>(n));
10719 }
10720 else if ((std::numeric_limits<std::int16_t>::min)() <= n and n <= (std::numeric_limits<std::int16_t>::max)())
10721 {
10722 if (add_prefix)
10723 {
10724 oa->write_character(to_char_type('I')); // int16
10725 }
10726 write_number(static_cast<std::int16_t>(n));
10727 }
10728 else if ((std::numeric_limits<std::int32_t>::min)() <= n and n <= (std::numeric_limits<std::int32_t>::max)())
10729 {
10730 if (add_prefix)
10731 {
10732 oa->write_character(to_char_type('l')); // int32
10733 }
10734 write_number(static_cast<std::int32_t>(n));
10735 }
10736 else if ((std::numeric_limits<std::int64_t>::min)() <= n and n <= (std::numeric_limits<std::int64_t>::max)())
10737 {
10738 if (add_prefix)
10739 {
10740 oa->write_character(to_char_type('L')); // int64
10741 }
10742 write_number(static_cast<std::int64_t>(n));
10743 }
10744 // LCOV_EXCL_START
10745 else
10746 {
10747 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
10748 }
10749 // LCOV_EXCL_STOP
10750 }
10751
10752 /*!
10753 @brief determine the type prefix of container values
10754
10755 @note This function does not need to be 100% accurate when it comes to
10756 integer limits. In case a number exceeds the limits of int64_t,
10757 this will be detected by a later call to function
10758 write_number_with_ubjson_prefix. Therefore, we return 'L' for any
10759 value that does not fit the previous limits.
10760 */
ubjson_prefix(const BasicJsonType & j) const10761 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
10762 {
10763 switch (j.type())
10764 {
10765 case value_t::null:
10766 return 'Z';
10767
10768 case value_t::boolean:
10769 return j.m_value.boolean ? 'T' : 'F';
10770
10771 case value_t::number_integer:
10772 {
10773 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)())
10774 {
10775 return 'i';
10776 }
10777 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)())
10778 {
10779 return 'U';
10780 }
10781 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)())
10782 {
10783 return 'I';
10784 }
10785 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)())
10786 {
10787 return 'l';
10788 }
10789 // no check and assume int64_t (see note above)
10790 return 'L';
10791 }
10792
10793 case value_t::number_unsigned:
10794 {
10795 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int8_t>::max)())
10796 {
10797 return 'i';
10798 }
10799 if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
10800 {
10801 return 'U';
10802 }
10803 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int16_t>::max)())
10804 {
10805 return 'I';
10806 }
10807 if (j.m_value.number_unsigned <= (std::numeric_limits<std::int32_t>::max)())
10808 {
10809 return 'l';
10810 }
10811 // no check and assume int64_t (see note above)
10812 return 'L';
10813 }
10814
10815 case value_t::number_float:
10816 return get_ubjson_float_prefix(j.m_value.number_float);
10817
10818 case value_t::string:
10819 return 'S';
10820
10821 case value_t::array:
10822 return '[';
10823
10824 case value_t::object:
10825 return '{';
10826
10827 default: // discarded values
10828 return 'N';
10829 }
10830 }
10831
get_ubjson_float_prefix(float)10832 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
10833 {
10834 return 'd'; // float 32
10835 }
10836
get_ubjson_float_prefix(double)10837 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
10838 {
10839 return 'D'; // float 64
10840 }
10841
10842 ///////////////////////
10843 // Utility functions //
10844 ///////////////////////
10845
10846 /*
10847 @brief write a number to output input
10848 @param[in] n number of type @a NumberType
10849 @tparam NumberType the type of the number
10850 @tparam OutputIsLittleEndian Set to true if output data is
10851 required to be little endian
10852
10853 @note This function needs to respect the system's endianess, because bytes
10854 in CBOR, MessagePack, and UBJSON are stored in network order (big
10855 endian) and therefore need reordering on little endian systems.
10856 */
10857 template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)10858 void write_number(const NumberType n)
10859 {
10860 // step 1: write number to array of length NumberType
10861 std::array<CharType, sizeof(NumberType)> vec;
10862 std::memcpy(vec.data(), &n, sizeof(NumberType));
10863
10864 // step 2: write array to output (with possible reordering)
10865 if (is_little_endian != OutputIsLittleEndian)
10866 {
10867 // reverse byte order prior to conversion if necessary
10868 std::reverse(vec.begin(), vec.end());
10869 }
10870
10871 oa->write_characters(vec.data(), sizeof(NumberType));
10872 }
10873
10874 public:
10875 // The following to_char_type functions are implement the conversion
10876 // between uint8_t and CharType. In case CharType is not unsigned,
10877 // such a conversion is required to allow values greater than 128.
10878 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
10879 template < typename C = CharType,
10880 enable_if_t < std::is_signed<C>::value and std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)10881 static constexpr CharType to_char_type(std::uint8_t x) noexcept
10882 {
10883 return *reinterpret_cast<char*>(&x);
10884 }
10885
10886 template < typename C = CharType,
10887 enable_if_t < std::is_signed<C>::value and std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)10888 static CharType to_char_type(std::uint8_t x) noexcept
10889 {
10890 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
10891 static_assert(std::is_pod<CharType>::value, "CharType must be POD");
10892 CharType result;
10893 std::memcpy(&result, &x, sizeof(x));
10894 return result;
10895 }
10896
10897 template<typename C = CharType,
10898 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)10899 static constexpr CharType to_char_type(std::uint8_t x) noexcept
10900 {
10901 return x;
10902 }
10903
10904 template < typename InputCharType, typename C = CharType,
10905 enable_if_t <
10906 std::is_signed<C>::value and
10907 std::is_signed<char>::value and
10908 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
10909 > * = nullptr >
to_char_type(InputCharType x)10910 static constexpr CharType to_char_type(InputCharType x) noexcept
10911 {
10912 return x;
10913 }
10914
10915 private:
10916 /// whether we can assume little endianess
10917 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
10918
10919 /// the output
10920 output_adapter_t<CharType> oa = nullptr;
10921 };
10922 } // namespace detail
10923 } // namespace nlohmann
10924
10925 // #include <nlohmann/detail/output/output_adapters.hpp>
10926
10927 // #include <nlohmann/detail/output/serializer.hpp>
10928
10929
10930 #include <algorithm> // reverse, remove, fill, find, none_of
10931 #include <array> // array
10932 #include <cassert> // assert
10933 #include <ciso646> // and, or
10934 #include <clocale> // localeconv, lconv
10935 #include <cmath> // labs, isfinite, isnan, signbit
10936 #include <cstddef> // size_t, ptrdiff_t
10937 #include <cstdint> // uint8_t
10938 #include <cstdio> // snprintf
10939 #include <limits> // numeric_limits
10940 #include <string> // string
10941 #include <type_traits> // is_same
10942 #include <utility> // move
10943
10944 // #include <nlohmann/detail/conversions/to_chars.hpp>
10945
10946
10947 #include <array> // array
10948 #include <cassert> // assert
10949 #include <ciso646> // or, and, not
10950 #include <cmath> // signbit, isfinite
10951 #include <cstdint> // intN_t, uintN_t
10952 #include <cstring> // memcpy, memmove
10953 #include <limits> // numeric_limits
10954 #include <type_traits> // conditional
10955
10956 namespace nlohmann
10957 {
10958 namespace detail
10959 {
10960
10961 /*!
10962 @brief implements the Grisu2 algorithm for binary to decimal floating-point
10963 conversion.
10964
10965 This implementation is a slightly modified version of the reference
10966 implementation which may be obtained from
10967 http://florian.loitsch.com/publications (bench.tar.gz).
10968
10969 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
10970
10971 For a detailed description of the algorithm see:
10972
10973 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
10974 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
10975 Language Design and Implementation, PLDI 2010
10976 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
10977 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
10978 Design and Implementation, PLDI 1996
10979 */
10980 namespace dtoa_impl
10981 {
10982
10983 template <typename Target, typename Source>
10984 Target reinterpret_bits(const Source source)
10985 {
10986 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
10987
10988 Target target;
10989 std::memcpy(&target, &source, sizeof(Source));
10990 return target;
10991 }
10992
10993 struct diyfp // f * 2^e
10994 {
10995 static constexpr int kPrecision = 64; // = q
10996
10997 std::uint64_t f = 0;
10998 int e = 0;
10999
diyfpnlohmann::detail::dtoa_impl::diyfp11000 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
11001
11002 /*!
11003 @brief returns x - y
11004 @pre x.e == y.e and x.f >= y.f
11005 */
subnlohmann::detail::dtoa_impl::diyfp11006 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
11007 {
11008 assert(x.e == y.e);
11009 assert(x.f >= y.f);
11010
11011 return {x.f - y.f, x.e};
11012 }
11013
11014 /*!
11015 @brief returns x * y
11016 @note The result is rounded. (Only the upper q bits are returned.)
11017 */
mulnlohmann::detail::dtoa_impl::diyfp11018 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
11019 {
11020 static_assert(kPrecision == 64, "internal error");
11021
11022 // Computes:
11023 // f = round((x.f * y.f) / 2^q)
11024 // e = x.e + y.e + q
11025
11026 // Emulate the 64-bit * 64-bit multiplication:
11027 //
11028 // p = u * v
11029 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
11030 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
11031 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
11032 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
11033 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
11034 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
11035 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
11036 //
11037 // (Since Q might be larger than 2^32 - 1)
11038 //
11039 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
11040 //
11041 // (Q_hi + H does not overflow a 64-bit int)
11042 //
11043 // = p_lo + 2^64 p_hi
11044
11045 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
11046 const std::uint64_t u_hi = x.f >> 32u;
11047 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
11048 const std::uint64_t v_hi = y.f >> 32u;
11049
11050 const std::uint64_t p0 = u_lo * v_lo;
11051 const std::uint64_t p1 = u_lo * v_hi;
11052 const std::uint64_t p2 = u_hi * v_lo;
11053 const std::uint64_t p3 = u_hi * v_hi;
11054
11055 const std::uint64_t p0_hi = p0 >> 32u;
11056 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
11057 const std::uint64_t p1_hi = p1 >> 32u;
11058 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
11059 const std::uint64_t p2_hi = p2 >> 32u;
11060
11061 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
11062
11063 // The full product might now be computed as
11064 //
11065 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
11066 // p_lo = p0_lo + (Q << 32)
11067 //
11068 // But in this particular case here, the full p_lo is not required.
11069 // Effectively we only need to add the highest bit in p_lo to p_hi (and
11070 // Q_hi + 1 does not overflow).
11071
11072 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
11073
11074 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
11075
11076 return {h, x.e + y.e + 64};
11077 }
11078
11079 /*!
11080 @brief normalize x such that the significand is >= 2^(q-1)
11081 @pre x.f != 0
11082 */
normalizenlohmann::detail::dtoa_impl::diyfp11083 static diyfp normalize(diyfp x) noexcept
11084 {
11085 assert(x.f != 0);
11086
11087 while ((x.f >> 63u) == 0)
11088 {
11089 x.f <<= 1u;
11090 x.e--;
11091 }
11092
11093 return x;
11094 }
11095
11096 /*!
11097 @brief normalize x such that the result has the exponent E
11098 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
11099 */
normalize_tonlohmann::detail::dtoa_impl::diyfp11100 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
11101 {
11102 const int delta = x.e - target_exponent;
11103
11104 assert(delta >= 0);
11105 assert(((x.f << delta) >> delta) == x.f);
11106
11107 return {x.f << delta, target_exponent};
11108 }
11109 };
11110
11111 struct boundaries
11112 {
11113 diyfp w;
11114 diyfp minus;
11115 diyfp plus;
11116 };
11117
11118 /*!
11119 Compute the (normalized) diyfp representing the input number 'value' and its
11120 boundaries.
11121
11122 @pre value must be finite and positive
11123 */
11124 template <typename FloatType>
compute_boundaries(FloatType value)11125 boundaries compute_boundaries(FloatType value)
11126 {
11127 assert(std::isfinite(value));
11128 assert(value > 0);
11129
11130 // Convert the IEEE representation into a diyfp.
11131 //
11132 // If v is denormal:
11133 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
11134 // If v is normalized:
11135 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
11136
11137 static_assert(std::numeric_limits<FloatType>::is_iec559,
11138 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
11139
11140 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
11141 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
11142 constexpr int kMinExp = 1 - kBias;
11143 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
11144
11145 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
11146
11147 const std::uint64_t bits = reinterpret_bits<bits_type>(value);
11148 const std::uint64_t E = bits >> (kPrecision - 1);
11149 const std::uint64_t F = bits & (kHiddenBit - 1);
11150
11151 const bool is_denormal = E == 0;
11152 const diyfp v = is_denormal
11153 ? diyfp(F, kMinExp)
11154 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
11155
11156 // Compute the boundaries m- and m+ of the floating-point value
11157 // v = f * 2^e.
11158 //
11159 // Determine v- and v+, the floating-point predecessor and successor if v,
11160 // respectively.
11161 //
11162 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
11163 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
11164 //
11165 // v+ = v + 2^e
11166 //
11167 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
11168 // between m- and m+ round to v, regardless of how the input rounding
11169 // algorithm breaks ties.
11170 //
11171 // ---+-------------+-------------+-------------+-------------+--- (A)
11172 // v- m- v m+ v+
11173 //
11174 // -----------------+------+------+-------------+-------------+--- (B)
11175 // v- m- v m+ v+
11176
11177 const bool lower_boundary_is_closer = F == 0 and E > 1;
11178 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
11179 const diyfp m_minus = lower_boundary_is_closer
11180 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
11181 : diyfp(2 * v.f - 1, v.e - 1); // (A)
11182
11183 // Determine the normalized w+ = m+.
11184 const diyfp w_plus = diyfp::normalize(m_plus);
11185
11186 // Determine w- = m- such that e_(w-) = e_(w+).
11187 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
11188
11189 return {diyfp::normalize(v), w_minus, w_plus};
11190 }
11191
11192 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
11193 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
11194 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
11195 //
11196 // alpha <= e = e_c + e_w + q <= gamma
11197 //
11198 // or
11199 //
11200 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
11201 // <= f_c * f_w * 2^gamma
11202 //
11203 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
11204 //
11205 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
11206 //
11207 // or
11208 //
11209 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
11210 //
11211 // The choice of (alpha,gamma) determines the size of the table and the form of
11212 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
11213 // in practice:
11214 //
11215 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
11216 // processed independently: An integral part p1, and a fractional part p2:
11217 //
11218 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
11219 // = (f div 2^-e) + (f mod 2^-e) * 2^e
11220 // = p1 + p2 * 2^e
11221 //
11222 // The conversion of p1 into decimal form requires a series of divisions and
11223 // modulos by (a power of) 10. These operations are faster for 32-bit than for
11224 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
11225 // achieved by choosing
11226 //
11227 // -e >= 32 or e <= -32 := gamma
11228 //
11229 // In order to convert the fractional part
11230 //
11231 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
11232 //
11233 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
11234 // d[-i] are extracted in order:
11235 //
11236 // (10 * p2) div 2^-e = d[-1]
11237 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
11238 //
11239 // The multiplication by 10 must not overflow. It is sufficient to choose
11240 //
11241 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
11242 //
11243 // Since p2 = f mod 2^-e < 2^-e,
11244 //
11245 // -e <= 60 or e >= -60 := alpha
11246
11247 constexpr int kAlpha = -60;
11248 constexpr int kGamma = -32;
11249
11250 struct cached_power // c = f * 2^e ~= 10^k
11251 {
11252 std::uint64_t f;
11253 int e;
11254 int k;
11255 };
11256
11257 /*!
11258 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
11259 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
11260 satisfies (Definition 3.2 from [1])
11261
11262 alpha <= e_c + e + q <= gamma.
11263 */
get_cached_power_for_binary_exponent(int e)11264 inline cached_power get_cached_power_for_binary_exponent(int e)
11265 {
11266 // Now
11267 //
11268 // alpha <= e_c + e + q <= gamma (1)
11269 // ==> f_c * 2^alpha <= c * 2^e * 2^q
11270 //
11271 // and since the c's are normalized, 2^(q-1) <= f_c,
11272 //
11273 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
11274 // ==> 2^(alpha - e - 1) <= c
11275 //
11276 // If c were an exakt power of ten, i.e. c = 10^k, one may determine k as
11277 //
11278 // k = ceil( log_10( 2^(alpha - e - 1) ) )
11279 // = ceil( (alpha - e - 1) * log_10(2) )
11280 //
11281 // From the paper:
11282 // "In theory the result of the procedure could be wrong since c is rounded,
11283 // and the computation itself is approximated [...]. In practice, however,
11284 // this simple function is sufficient."
11285 //
11286 // For IEEE double precision floating-point numbers converted into
11287 // normalized diyfp's w = f * 2^e, with q = 64,
11288 //
11289 // e >= -1022 (min IEEE exponent)
11290 // -52 (p - 1)
11291 // -52 (p - 1, possibly normalize denormal IEEE numbers)
11292 // -11 (normalize the diyfp)
11293 // = -1137
11294 //
11295 // and
11296 //
11297 // e <= +1023 (max IEEE exponent)
11298 // -52 (p - 1)
11299 // -11 (normalize the diyfp)
11300 // = 960
11301 //
11302 // This binary exponent range [-1137,960] results in a decimal exponent
11303 // range [-307,324]. One does not need to store a cached power for each
11304 // k in this range. For each such k it suffices to find a cached power
11305 // such that the exponent of the product lies in [alpha,gamma].
11306 // This implies that the difference of the decimal exponents of adjacent
11307 // table entries must be less than or equal to
11308 //
11309 // floor( (gamma - alpha) * log_10(2) ) = 8.
11310 //
11311 // (A smaller distance gamma-alpha would require a larger table.)
11312
11313 // NB:
11314 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
11315
11316 constexpr int kCachedPowersMinDecExp = -300;
11317 constexpr int kCachedPowersDecStep = 8;
11318
11319 static constexpr std::array<cached_power, 79> kCachedPowers =
11320 {
11321 {
11322 { 0xAB70FE17C79AC6CA, -1060, -300 },
11323 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
11324 { 0xBE5691EF416BD60C, -1007, -284 },
11325 { 0x8DD01FAD907FFC3C, -980, -276 },
11326 { 0xD3515C2831559A83, -954, -268 },
11327 { 0x9D71AC8FADA6C9B5, -927, -260 },
11328 { 0xEA9C227723EE8BCB, -901, -252 },
11329 { 0xAECC49914078536D, -874, -244 },
11330 { 0x823C12795DB6CE57, -847, -236 },
11331 { 0xC21094364DFB5637, -821, -228 },
11332 { 0x9096EA6F3848984F, -794, -220 },
11333 { 0xD77485CB25823AC7, -768, -212 },
11334 { 0xA086CFCD97BF97F4, -741, -204 },
11335 { 0xEF340A98172AACE5, -715, -196 },
11336 { 0xB23867FB2A35B28E, -688, -188 },
11337 { 0x84C8D4DFD2C63F3B, -661, -180 },
11338 { 0xC5DD44271AD3CDBA, -635, -172 },
11339 { 0x936B9FCEBB25C996, -608, -164 },
11340 { 0xDBAC6C247D62A584, -582, -156 },
11341 { 0xA3AB66580D5FDAF6, -555, -148 },
11342 { 0xF3E2F893DEC3F126, -529, -140 },
11343 { 0xB5B5ADA8AAFF80B8, -502, -132 },
11344 { 0x87625F056C7C4A8B, -475, -124 },
11345 { 0xC9BCFF6034C13053, -449, -116 },
11346 { 0x964E858C91BA2655, -422, -108 },
11347 { 0xDFF9772470297EBD, -396, -100 },
11348 { 0xA6DFBD9FB8E5B88F, -369, -92 },
11349 { 0xF8A95FCF88747D94, -343, -84 },
11350 { 0xB94470938FA89BCF, -316, -76 },
11351 { 0x8A08F0F8BF0F156B, -289, -68 },
11352 { 0xCDB02555653131B6, -263, -60 },
11353 { 0x993FE2C6D07B7FAC, -236, -52 },
11354 { 0xE45C10C42A2B3B06, -210, -44 },
11355 { 0xAA242499697392D3, -183, -36 },
11356 { 0xFD87B5F28300CA0E, -157, -28 },
11357 { 0xBCE5086492111AEB, -130, -20 },
11358 { 0x8CBCCC096F5088CC, -103, -12 },
11359 { 0xD1B71758E219652C, -77, -4 },
11360 { 0x9C40000000000000, -50, 4 },
11361 { 0xE8D4A51000000000, -24, 12 },
11362 { 0xAD78EBC5AC620000, 3, 20 },
11363 { 0x813F3978F8940984, 30, 28 },
11364 { 0xC097CE7BC90715B3, 56, 36 },
11365 { 0x8F7E32CE7BEA5C70, 83, 44 },
11366 { 0xD5D238A4ABE98068, 109, 52 },
11367 { 0x9F4F2726179A2245, 136, 60 },
11368 { 0xED63A231D4C4FB27, 162, 68 },
11369 { 0xB0DE65388CC8ADA8, 189, 76 },
11370 { 0x83C7088E1AAB65DB, 216, 84 },
11371 { 0xC45D1DF942711D9A, 242, 92 },
11372 { 0x924D692CA61BE758, 269, 100 },
11373 { 0xDA01EE641A708DEA, 295, 108 },
11374 { 0xA26DA3999AEF774A, 322, 116 },
11375 { 0xF209787BB47D6B85, 348, 124 },
11376 { 0xB454E4A179DD1877, 375, 132 },
11377 { 0x865B86925B9BC5C2, 402, 140 },
11378 { 0xC83553C5C8965D3D, 428, 148 },
11379 { 0x952AB45CFA97A0B3, 455, 156 },
11380 { 0xDE469FBD99A05FE3, 481, 164 },
11381 { 0xA59BC234DB398C25, 508, 172 },
11382 { 0xF6C69A72A3989F5C, 534, 180 },
11383 { 0xB7DCBF5354E9BECE, 561, 188 },
11384 { 0x88FCF317F22241E2, 588, 196 },
11385 { 0xCC20CE9BD35C78A5, 614, 204 },
11386 { 0x98165AF37B2153DF, 641, 212 },
11387 { 0xE2A0B5DC971F303A, 667, 220 },
11388 { 0xA8D9D1535CE3B396, 694, 228 },
11389 { 0xFB9B7CD9A4A7443C, 720, 236 },
11390 { 0xBB764C4CA7A44410, 747, 244 },
11391 { 0x8BAB8EEFB6409C1A, 774, 252 },
11392 { 0xD01FEF10A657842C, 800, 260 },
11393 { 0x9B10A4E5E9913129, 827, 268 },
11394 { 0xE7109BFBA19C0C9D, 853, 276 },
11395 { 0xAC2820D9623BF429, 880, 284 },
11396 { 0x80444B5E7AA7CF85, 907, 292 },
11397 { 0xBF21E44003ACDD2D, 933, 300 },
11398 { 0x8E679C2F5E44FF8F, 960, 308 },
11399 { 0xD433179D9C8CB841, 986, 316 },
11400 { 0x9E19DB92B4E31BA9, 1013, 324 },
11401 }
11402 };
11403
11404 // This computation gives exactly the same results for k as
11405 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
11406 // for |e| <= 1500, but doesn't require floating-point operations.
11407 // NB: log_10(2) ~= 78913 / 2^18
11408 assert(e >= -1500);
11409 assert(e <= 1500);
11410 const int f = kAlpha - e - 1;
11411 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
11412
11413 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
11414 assert(index >= 0);
11415 assert(static_cast<std::size_t>(index) < kCachedPowers.size());
11416
11417 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
11418 assert(kAlpha <= cached.e + e + 64);
11419 assert(kGamma >= cached.e + e + 64);
11420
11421 return cached;
11422 }
11423
11424 /*!
11425 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
11426 For n == 0, returns 1 and sets pow10 := 1.
11427 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)11428 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
11429 {
11430 // LCOV_EXCL_START
11431 if (n >= 1000000000)
11432 {
11433 pow10 = 1000000000;
11434 return 10;
11435 }
11436 // LCOV_EXCL_STOP
11437 else if (n >= 100000000)
11438 {
11439 pow10 = 100000000;
11440 return 9;
11441 }
11442 else if (n >= 10000000)
11443 {
11444 pow10 = 10000000;
11445 return 8;
11446 }
11447 else if (n >= 1000000)
11448 {
11449 pow10 = 1000000;
11450 return 7;
11451 }
11452 else if (n >= 100000)
11453 {
11454 pow10 = 100000;
11455 return 6;
11456 }
11457 else if (n >= 10000)
11458 {
11459 pow10 = 10000;
11460 return 5;
11461 }
11462 else if (n >= 1000)
11463 {
11464 pow10 = 1000;
11465 return 4;
11466 }
11467 else if (n >= 100)
11468 {
11469 pow10 = 100;
11470 return 3;
11471 }
11472 else if (n >= 10)
11473 {
11474 pow10 = 10;
11475 return 2;
11476 }
11477 else
11478 {
11479 pow10 = 1;
11480 return 1;
11481 }
11482 }
11483
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)11484 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
11485 std::uint64_t rest, std::uint64_t ten_k)
11486 {
11487 assert(len >= 1);
11488 assert(dist <= delta);
11489 assert(rest <= delta);
11490 assert(ten_k > 0);
11491
11492 // <--------------------------- delta ---->
11493 // <---- dist --------->
11494 // --------------[------------------+-------------------]--------------
11495 // M- w M+
11496 //
11497 // ten_k
11498 // <------>
11499 // <---- rest ---->
11500 // --------------[------------------+----+--------------]--------------
11501 // w V
11502 // = buf * 10^k
11503 //
11504 // ten_k represents a unit-in-the-last-place in the decimal representation
11505 // stored in buf.
11506 // Decrement buf by ten_k while this takes buf closer to w.
11507
11508 // The tests are written in this order to avoid overflow in unsigned
11509 // integer arithmetic.
11510
11511 while (rest < dist
11512 and delta - rest >= ten_k
11513 and (rest + ten_k < dist or dist - rest > rest + ten_k - dist))
11514 {
11515 assert(buf[len - 1] != '0');
11516 buf[len - 1]--;
11517 rest += ten_k;
11518 }
11519 }
11520
11521 /*!
11522 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
11523 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
11524 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)11525 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
11526 diyfp M_minus, diyfp w, diyfp M_plus)
11527 {
11528 static_assert(kAlpha >= -60, "internal error");
11529 static_assert(kGamma <= -32, "internal error");
11530
11531 // Generates the digits (and the exponent) of a decimal floating-point
11532 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
11533 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
11534 //
11535 // <--------------------------- delta ---->
11536 // <---- dist --------->
11537 // --------------[------------------+-------------------]--------------
11538 // M- w M+
11539 //
11540 // Grisu2 generates the digits of M+ from left to right and stops as soon as
11541 // V is in [M-,M+].
11542
11543 assert(M_plus.e >= kAlpha);
11544 assert(M_plus.e <= kGamma);
11545
11546 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
11547 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
11548
11549 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
11550 //
11551 // M+ = f * 2^e
11552 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
11553 // = ((p1 ) * 2^-e + (p2 )) * 2^e
11554 // = p1 + p2 * 2^e
11555
11556 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
11557
11558 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.)
11559 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
11560
11561 // 1)
11562 //
11563 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
11564
11565 assert(p1 > 0);
11566
11567 std::uint32_t pow10;
11568 const int k = find_largest_pow10(p1, pow10);
11569
11570 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
11571 //
11572 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
11573 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
11574 //
11575 // M+ = p1 + p2 * 2^e
11576 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
11577 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
11578 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
11579 //
11580 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
11581 //
11582 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
11583 //
11584 // but stop as soon as
11585 //
11586 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
11587
11588 int n = k;
11589 while (n > 0)
11590 {
11591 // Invariants:
11592 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
11593 // pow10 = 10^(n-1) <= p1 < 10^n
11594 //
11595 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
11596 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
11597 //
11598 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
11599 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
11600 //
11601 assert(d <= 9);
11602 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11603 //
11604 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
11605 //
11606 p1 = r;
11607 n--;
11608 //
11609 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
11610 // pow10 = 10^n
11611 //
11612
11613 // Now check if enough digits have been generated.
11614 // Compute
11615 //
11616 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
11617 //
11618 // Note:
11619 // Since rest and delta share the same exponent e, it suffices to
11620 // compare the significands.
11621 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
11622 if (rest <= delta)
11623 {
11624 // V = buffer * 10^n, with M- <= V <= M+.
11625
11626 decimal_exponent += n;
11627
11628 // We may now just stop. But instead look if the buffer could be
11629 // decremented to bring V closer to w.
11630 //
11631 // pow10 = 10^n is now 1 ulp in the decimal representation V.
11632 // The rounding procedure works with diyfp's with an implicit
11633 // exponent of e.
11634 //
11635 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
11636 //
11637 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
11638 grisu2_round(buffer, length, dist, delta, rest, ten_n);
11639
11640 return;
11641 }
11642
11643 pow10 /= 10;
11644 //
11645 // pow10 = 10^(n-1) <= p1 < 10^n
11646 // Invariants restored.
11647 }
11648
11649 // 2)
11650 //
11651 // The digits of the integral part have been generated:
11652 //
11653 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
11654 // = buffer + p2 * 2^e
11655 //
11656 // Now generate the digits of the fractional part p2 * 2^e.
11657 //
11658 // Note:
11659 // No decimal point is generated: the exponent is adjusted instead.
11660 //
11661 // p2 actually represents the fraction
11662 //
11663 // p2 * 2^e
11664 // = p2 / 2^-e
11665 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
11666 //
11667 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
11668 //
11669 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
11670 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
11671 //
11672 // using
11673 //
11674 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
11675 // = ( d) * 2^-e + ( r)
11676 //
11677 // or
11678 // 10^m * p2 * 2^e = d + r * 2^e
11679 //
11680 // i.e.
11681 //
11682 // M+ = buffer + p2 * 2^e
11683 // = buffer + 10^-m * (d + r * 2^e)
11684 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
11685 //
11686 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
11687
11688 assert(p2 > delta);
11689
11690 int m = 0;
11691 for (;;)
11692 {
11693 // Invariant:
11694 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
11695 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
11696 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
11697 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
11698 //
11699 assert(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
11700 p2 *= 10;
11701 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
11702 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
11703 //
11704 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
11705 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
11706 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
11707 //
11708 assert(d <= 9);
11709 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
11710 //
11711 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
11712 //
11713 p2 = r;
11714 m++;
11715 //
11716 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
11717 // Invariant restored.
11718
11719 // Check if enough digits have been generated.
11720 //
11721 // 10^-m * p2 * 2^e <= delta * 2^e
11722 // p2 * 2^e <= 10^m * delta * 2^e
11723 // p2 <= 10^m * delta
11724 delta *= 10;
11725 dist *= 10;
11726 if (p2 <= delta)
11727 {
11728 break;
11729 }
11730 }
11731
11732 // V = buffer * 10^-m, with M- <= V <= M+.
11733
11734 decimal_exponent -= m;
11735
11736 // 1 ulp in the decimal representation is now 10^-m.
11737 // Since delta and dist are now scaled by 10^m, we need to do the
11738 // same with ulp in order to keep the units in sync.
11739 //
11740 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
11741 //
11742 const std::uint64_t ten_m = one.f;
11743 grisu2_round(buffer, length, dist, delta, p2, ten_m);
11744
11745 // By construction this algorithm generates the shortest possible decimal
11746 // number (Loitsch, Theorem 6.2) which rounds back to w.
11747 // For an input number of precision p, at least
11748 //
11749 // N = 1 + ceil(p * log_10(2))
11750 //
11751 // decimal digits are sufficient to identify all binary floating-point
11752 // numbers (Matula, "In-and-Out conversions").
11753 // This implies that the algorithm does not produce more than N decimal
11754 // digits.
11755 //
11756 // N = 17 for p = 53 (IEEE double precision)
11757 // N = 9 for p = 24 (IEEE single precision)
11758 }
11759
11760 /*!
11761 v = buf * 10^decimal_exponent
11762 len is the length of the buffer (number of decimal digits)
11763 The buffer must be large enough, i.e. >= max_digits10.
11764 */
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)11765 inline void grisu2(char* buf, int& len, int& decimal_exponent,
11766 diyfp m_minus, diyfp v, diyfp m_plus)
11767 {
11768 assert(m_plus.e == m_minus.e);
11769 assert(m_plus.e == v.e);
11770
11771 // --------(-----------------------+-----------------------)-------- (A)
11772 // m- v m+
11773 //
11774 // --------------------(-----------+-----------------------)-------- (B)
11775 // m- v m+
11776 //
11777 // First scale v (and m- and m+) such that the exponent is in the range
11778 // [alpha, gamma].
11779
11780 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
11781
11782 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
11783
11784 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
11785 const diyfp w = diyfp::mul(v, c_minus_k);
11786 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
11787 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
11788
11789 // ----(---+---)---------------(---+---)---------------(---+---)----
11790 // w- w w+
11791 // = c*m- = c*v = c*m+
11792 //
11793 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
11794 // w+ are now off by a small amount.
11795 // In fact:
11796 //
11797 // w - v * 10^k < 1 ulp
11798 //
11799 // To account for this inaccuracy, add resp. subtract 1 ulp.
11800 //
11801 // --------+---[---------------(---+---)---------------]---+--------
11802 // w- M- w M+ w+
11803 //
11804 // Now any number in [M-, M+] (bounds included) will round to w when input,
11805 // regardless of how the input rounding algorithm breaks ties.
11806 //
11807 // And digit_gen generates the shortest possible such number in [M-, M+].
11808 // Note that this does not mean that Grisu2 always generates the shortest
11809 // possible number in the interval (m-, m+).
11810 const diyfp M_minus(w_minus.f + 1, w_minus.e);
11811 const diyfp M_plus (w_plus.f - 1, w_plus.e );
11812
11813 decimal_exponent = -cached.k; // = -(-k) = k
11814
11815 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
11816 }
11817
11818 /*!
11819 v = buf * 10^decimal_exponent
11820 len is the length of the buffer (number of decimal digits)
11821 The buffer must be large enough, i.e. >= max_digits10.
11822 */
11823 template <typename FloatType>
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)11824 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
11825 {
11826 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
11827 "internal error: not enough precision");
11828
11829 assert(std::isfinite(value));
11830 assert(value > 0);
11831
11832 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
11833 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
11834 // decimal representations are not exactly "short".
11835 //
11836 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
11837 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
11838 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
11839 // does.
11840 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
11841 // representation using the corresponding std::from_chars function recovers value exactly". That
11842 // indicates that single precision floating-point numbers should be recovered using
11843 // 'std::strtof'.
11844 //
11845 // NB: If the neighbors are computed for single-precision numbers, there is a single float
11846 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
11847 // value is off by 1 ulp.
11848 #if 0
11849 const boundaries w = compute_boundaries(static_cast<double>(value));
11850 #else
11851 const boundaries w = compute_boundaries(value);
11852 #endif
11853
11854 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
11855 }
11856
11857 /*!
11858 @brief appends a decimal representation of e to buf
11859 @return a pointer to the element following the exponent.
11860 @pre -1000 < e < 1000
11861 */
append_exponent(char * buf,int e)11862 inline char* append_exponent(char* buf, int e)
11863 {
11864 assert(e > -1000);
11865 assert(e < 1000);
11866
11867 if (e < 0)
11868 {
11869 e = -e;
11870 *buf++ = '-';
11871 }
11872 else
11873 {
11874 *buf++ = '+';
11875 }
11876
11877 auto k = static_cast<std::uint32_t>(e);
11878 if (k < 10)
11879 {
11880 // Always print at least two digits in the exponent.
11881 // This is for compatibility with printf("%g").
11882 *buf++ = '0';
11883 *buf++ = static_cast<char>('0' + k);
11884 }
11885 else if (k < 100)
11886 {
11887 *buf++ = static_cast<char>('0' + k / 10);
11888 k %= 10;
11889 *buf++ = static_cast<char>('0' + k);
11890 }
11891 else
11892 {
11893 *buf++ = static_cast<char>('0' + k / 100);
11894 k %= 100;
11895 *buf++ = static_cast<char>('0' + k / 10);
11896 k %= 10;
11897 *buf++ = static_cast<char>('0' + k);
11898 }
11899
11900 return buf;
11901 }
11902
11903 /*!
11904 @brief prettify v = buf * 10^decimal_exponent
11905
11906 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
11907 notation. Otherwise it will be printed in exponential notation.
11908
11909 @pre min_exp < 0
11910 @pre max_exp > 0
11911 */
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)11912 inline char* format_buffer(char* buf, int len, int decimal_exponent,
11913 int min_exp, int max_exp)
11914 {
11915 assert(min_exp < 0);
11916 assert(max_exp > 0);
11917
11918 const int k = len;
11919 const int n = len + decimal_exponent;
11920
11921 // v = buf * 10^(n-k)
11922 // k is the length of the buffer (number of decimal digits)
11923 // n is the position of the decimal point relative to the start of the buffer.
11924
11925 if (k <= n and n <= max_exp)
11926 {
11927 // digits[000]
11928 // len <= max_exp + 2
11929
11930 std::memset(buf + k, '0', static_cast<size_t>(n - k));
11931 // Make it look like a floating-point number (#362, #378)
11932 buf[n + 0] = '.';
11933 buf[n + 1] = '0';
11934 return buf + (n + 2);
11935 }
11936
11937 if (0 < n and n <= max_exp)
11938 {
11939 // dig.its
11940 // len <= max_digits10 + 1
11941
11942 assert(k > n);
11943
11944 std::memmove(buf + (n + 1), buf + n, static_cast<size_t>(k - n));
11945 buf[n] = '.';
11946 return buf + (k + 1);
11947 }
11948
11949 if (min_exp < n and n <= 0)
11950 {
11951 // 0.[000]digits
11952 // len <= 2 + (-min_exp - 1) + max_digits10
11953
11954 std::memmove(buf + (2 + -n), buf, static_cast<size_t>(k));
11955 buf[0] = '0';
11956 buf[1] = '.';
11957 std::memset(buf + 2, '0', static_cast<size_t>(-n));
11958 return buf + (2 + (-n) + k);
11959 }
11960
11961 if (k == 1)
11962 {
11963 // dE+123
11964 // len <= 1 + 5
11965
11966 buf += 1;
11967 }
11968 else
11969 {
11970 // d.igitsE+123
11971 // len <= max_digits10 + 1 + 5
11972
11973 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k - 1));
11974 buf[1] = '.';
11975 buf += 1 + k;
11976 }
11977
11978 *buf++ = 'e';
11979 return append_exponent(buf, n - 1);
11980 }
11981
11982 } // namespace dtoa_impl
11983
11984 /*!
11985 @brief generates a decimal representation of the floating-point number value in [first, last).
11986
11987 The format of the resulting decimal representation is similar to printf's %g
11988 format. Returns an iterator pointing past-the-end of the decimal representation.
11989
11990 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
11991 @note The buffer must be large enough.
11992 @note The result is NOT null-terminated.
11993 */
11994 template <typename FloatType>
to_chars(char * first,const char * last,FloatType value)11995 char* to_chars(char* first, const char* last, FloatType value)
11996 {
11997 static_cast<void>(last); // maybe unused - fix warning
11998 assert(std::isfinite(value));
11999
12000 // Use signbit(value) instead of (value < 0) since signbit works for -0.
12001 if (std::signbit(value))
12002 {
12003 value = -value;
12004 *first++ = '-';
12005 }
12006
12007 if (value == 0) // +-0
12008 {
12009 *first++ = '0';
12010 // Make it look like a floating-point number (#362, #378)
12011 *first++ = '.';
12012 *first++ = '0';
12013 return first;
12014 }
12015
12016 assert(last - first >= std::numeric_limits<FloatType>::max_digits10);
12017
12018 // Compute v = buffer * 10^decimal_exponent.
12019 // The decimal digits are stored in the buffer, which needs to be interpreted
12020 // as an unsigned decimal integer.
12021 // len is the length of the buffer, i.e. the number of decimal digits.
12022 int len = 0;
12023 int decimal_exponent = 0;
12024 dtoa_impl::grisu2(first, len, decimal_exponent, value);
12025
12026 assert(len <= std::numeric_limits<FloatType>::max_digits10);
12027
12028 // Format the buffer like printf("%.*g", prec, value)
12029 constexpr int kMinExp = -4;
12030 // Use digits10 here to increase compatibility with version 2.
12031 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
12032
12033 assert(last - first >= kMaxExp + 2);
12034 assert(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
12035 assert(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
12036
12037 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
12038 }
12039
12040 } // namespace detail
12041 } // namespace nlohmann
12042
12043 // #include <nlohmann/detail/exceptions.hpp>
12044
12045 // #include <nlohmann/detail/macro_scope.hpp>
12046
12047 // #include <nlohmann/detail/meta/cpp_future.hpp>
12048
12049 // #include <nlohmann/detail/output/binary_writer.hpp>
12050
12051 // #include <nlohmann/detail/output/output_adapters.hpp>
12052
12053 // #include <nlohmann/detail/value_t.hpp>
12054
12055
12056 namespace nlohmann
12057 {
12058 namespace detail
12059 {
12060 ///////////////////
12061 // serialization //
12062 ///////////////////
12063
12064 /// how to treat decoding errors
12065 enum class error_handler_t
12066 {
12067 strict, ///< throw a type_error exception in case of invalid UTF-8
12068 replace, ///< replace invalid UTF-8 sequences with U+FFFD
12069 ignore ///< ignore invalid UTF-8 sequences
12070 };
12071
12072 template<typename BasicJsonType>
12073 class serializer
12074 {
12075 using string_t = typename BasicJsonType::string_t;
12076 using number_float_t = typename BasicJsonType::number_float_t;
12077 using number_integer_t = typename BasicJsonType::number_integer_t;
12078 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
12079 static constexpr std::uint8_t UTF8_ACCEPT = 0;
12080 static constexpr std::uint8_t UTF8_REJECT = 1;
12081
12082 public:
12083 /*!
12084 @param[in] s output stream to serialize to
12085 @param[in] ichar indentation character to use
12086 @param[in] error_handler_ how to react on decoding errors
12087 */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)12088 serializer(output_adapter_t<char> s, const char ichar,
12089 error_handler_t error_handler_ = error_handler_t::strict)
12090 : o(std::move(s))
12091 , loc(std::localeconv())
12092 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : * (loc->thousands_sep))
12093 , decimal_point(loc->decimal_point == nullptr ? '\0' : * (loc->decimal_point))
12094 , indent_char(ichar)
12095 , indent_string(512, indent_char)
12096 , error_handler(error_handler_)
12097 {}
12098
12099 // delete because of pointer members
12100 serializer(const serializer&) = delete;
12101 serializer& operator=(const serializer&) = delete;
12102 serializer(serializer&&) = delete;
12103 serializer& operator=(serializer&&) = delete;
12104 ~serializer() = default;
12105
12106 /*!
12107 @brief internal implementation of the serialization function
12108
12109 This function is called by the public member function dump and organizes
12110 the serialization internally. The indentation level is propagated as
12111 additional parameter. In case of arrays and objects, the function is
12112 called recursively.
12113
12114 - strings and object keys are escaped using `escape_string()`
12115 - integer numbers are converted implicitly via `operator<<`
12116 - floating-point numbers are converted to a string using `"%g"` format
12117
12118 @param[in] val value to serialize
12119 @param[in] pretty_print whether the output shall be pretty-printed
12120 @param[in] indent_step the indent level
12121 @param[in] current_indent the current indent level (only used internally)
12122 */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)12123 void dump(const BasicJsonType& val, const bool pretty_print,
12124 const bool ensure_ascii,
12125 const unsigned int indent_step,
12126 const unsigned int current_indent = 0)
12127 {
12128 switch (val.m_type)
12129 {
12130 case value_t::object:
12131 {
12132 if (val.m_value.object->empty())
12133 {
12134 o->write_characters("{}", 2);
12135 return;
12136 }
12137
12138 if (pretty_print)
12139 {
12140 o->write_characters("{\n", 2);
12141
12142 // variable to hold indentation for recursive calls
12143 const auto new_indent = current_indent + indent_step;
12144 if (JSON_UNLIKELY(indent_string.size() < new_indent))
12145 {
12146 indent_string.resize(indent_string.size() * 2, ' ');
12147 }
12148
12149 // first n-1 elements
12150 auto i = val.m_value.object->cbegin();
12151 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12152 {
12153 o->write_characters(indent_string.c_str(), new_indent);
12154 o->write_character('\"');
12155 dump_escaped(i->first, ensure_ascii);
12156 o->write_characters("\": ", 3);
12157 dump(i->second, true, ensure_ascii, indent_step, new_indent);
12158 o->write_characters(",\n", 2);
12159 }
12160
12161 // last element
12162 assert(i != val.m_value.object->cend());
12163 assert(std::next(i) == val.m_value.object->cend());
12164 o->write_characters(indent_string.c_str(), new_indent);
12165 o->write_character('\"');
12166 dump_escaped(i->first, ensure_ascii);
12167 o->write_characters("\": ", 3);
12168 dump(i->second, true, ensure_ascii, indent_step, new_indent);
12169
12170 o->write_character('\n');
12171 o->write_characters(indent_string.c_str(), current_indent);
12172 o->write_character('}');
12173 }
12174 else
12175 {
12176 o->write_character('{');
12177
12178 // first n-1 elements
12179 auto i = val.m_value.object->cbegin();
12180 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
12181 {
12182 o->write_character('\"');
12183 dump_escaped(i->first, ensure_ascii);
12184 o->write_characters("\":", 2);
12185 dump(i->second, false, ensure_ascii, indent_step, current_indent);
12186 o->write_character(',');
12187 }
12188
12189 // last element
12190 assert(i != val.m_value.object->cend());
12191 assert(std::next(i) == val.m_value.object->cend());
12192 o->write_character('\"');
12193 dump_escaped(i->first, ensure_ascii);
12194 o->write_characters("\":", 2);
12195 dump(i->second, false, ensure_ascii, indent_step, current_indent);
12196
12197 o->write_character('}');
12198 }
12199
12200 return;
12201 }
12202
12203 case value_t::array:
12204 {
12205 if (val.m_value.array->empty())
12206 {
12207 o->write_characters("[]", 2);
12208 return;
12209 }
12210
12211 if (pretty_print)
12212 {
12213 o->write_characters("[\n", 2);
12214
12215 // variable to hold indentation for recursive calls
12216 const auto new_indent = current_indent + indent_step;
12217 if (JSON_UNLIKELY(indent_string.size() < new_indent))
12218 {
12219 indent_string.resize(indent_string.size() * 2, ' ');
12220 }
12221
12222 // first n-1 elements
12223 for (auto i = val.m_value.array->cbegin();
12224 i != val.m_value.array->cend() - 1; ++i)
12225 {
12226 o->write_characters(indent_string.c_str(), new_indent);
12227 dump(*i, true, ensure_ascii, indent_step, new_indent);
12228 o->write_characters(",\n", 2);
12229 }
12230
12231 // last element
12232 assert(not val.m_value.array->empty());
12233 o->write_characters(indent_string.c_str(), new_indent);
12234 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
12235
12236 o->write_character('\n');
12237 o->write_characters(indent_string.c_str(), current_indent);
12238 o->write_character(']');
12239 }
12240 else
12241 {
12242 o->write_character('[');
12243
12244 // first n-1 elements
12245 for (auto i = val.m_value.array->cbegin();
12246 i != val.m_value.array->cend() - 1; ++i)
12247 {
12248 dump(*i, false, ensure_ascii, indent_step, current_indent);
12249 o->write_character(',');
12250 }
12251
12252 // last element
12253 assert(not val.m_value.array->empty());
12254 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
12255
12256 o->write_character(']');
12257 }
12258
12259 return;
12260 }
12261
12262 case value_t::string:
12263 {
12264 o->write_character('\"');
12265 dump_escaped(*val.m_value.string, ensure_ascii);
12266 o->write_character('\"');
12267 return;
12268 }
12269
12270 case value_t::boolean:
12271 {
12272 if (val.m_value.boolean)
12273 {
12274 o->write_characters("true", 4);
12275 }
12276 else
12277 {
12278 o->write_characters("false", 5);
12279 }
12280 return;
12281 }
12282
12283 case value_t::number_integer:
12284 {
12285 dump_integer(val.m_value.number_integer);
12286 return;
12287 }
12288
12289 case value_t::number_unsigned:
12290 {
12291 dump_integer(val.m_value.number_unsigned);
12292 return;
12293 }
12294
12295 case value_t::number_float:
12296 {
12297 dump_float(val.m_value.number_float);
12298 return;
12299 }
12300
12301 case value_t::discarded:
12302 {
12303 o->write_characters("<discarded>", 11);
12304 return;
12305 }
12306
12307 case value_t::null:
12308 {
12309 o->write_characters("null", 4);
12310 return;
12311 }
12312
12313 default: // LCOV_EXCL_LINE
12314 assert(false); // LCOV_EXCL_LINE
12315 }
12316 }
12317
12318 private:
12319 /*!
12320 @brief dump escaped string
12321
12322 Escape a string by replacing certain special characters by a sequence of an
12323 escape character (backslash) and another character and other control
12324 characters by a sequence of "\u" followed by a four-digit hex
12325 representation. The escaped string is written to output stream @a o.
12326
12327 @param[in] s the string to escape
12328 @param[in] ensure_ascii whether to escape non-ASCII characters with
12329 \uXXXX sequences
12330
12331 @complexity Linear in the length of string @a s.
12332 */
dump_escaped(const string_t & s,const bool ensure_ascii)12333 void dump_escaped(const string_t& s, const bool ensure_ascii)
12334 {
12335 std::uint32_t codepoint;
12336 std::uint8_t state = UTF8_ACCEPT;
12337 std::size_t bytes = 0; // number of bytes written to string_buffer
12338
12339 // number of bytes written at the point of the last valid byte
12340 std::size_t bytes_after_last_accept = 0;
12341 std::size_t undumped_chars = 0;
12342
12343 for (std::size_t i = 0; i < s.size(); ++i)
12344 {
12345 const auto byte = static_cast<uint8_t>(s[i]);
12346
12347 switch (decode(state, codepoint, byte))
12348 {
12349 case UTF8_ACCEPT: // decode found a new code point
12350 {
12351 switch (codepoint)
12352 {
12353 case 0x08: // backspace
12354 {
12355 string_buffer[bytes++] = '\\';
12356 string_buffer[bytes++] = 'b';
12357 break;
12358 }
12359
12360 case 0x09: // horizontal tab
12361 {
12362 string_buffer[bytes++] = '\\';
12363 string_buffer[bytes++] = 't';
12364 break;
12365 }
12366
12367 case 0x0A: // newline
12368 {
12369 string_buffer[bytes++] = '\\';
12370 string_buffer[bytes++] = 'n';
12371 break;
12372 }
12373
12374 case 0x0C: // formfeed
12375 {
12376 string_buffer[bytes++] = '\\';
12377 string_buffer[bytes++] = 'f';
12378 break;
12379 }
12380
12381 case 0x0D: // carriage return
12382 {
12383 string_buffer[bytes++] = '\\';
12384 string_buffer[bytes++] = 'r';
12385 break;
12386 }
12387
12388 case 0x22: // quotation mark
12389 {
12390 string_buffer[bytes++] = '\\';
12391 string_buffer[bytes++] = '\"';
12392 break;
12393 }
12394
12395 case 0x5C: // reverse solidus
12396 {
12397 string_buffer[bytes++] = '\\';
12398 string_buffer[bytes++] = '\\';
12399 break;
12400 }
12401
12402 default:
12403 {
12404 // escape control characters (0x00..0x1F) or, if
12405 // ensure_ascii parameter is used, non-ASCII characters
12406 if ((codepoint <= 0x1F) or (ensure_ascii and (codepoint >= 0x7F)))
12407 {
12408 if (codepoint <= 0xFFFF)
12409 {
12410 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
12411 static_cast<std::uint16_t>(codepoint));
12412 bytes += 6;
12413 }
12414 else
12415 {
12416 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
12417 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
12418 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
12419 bytes += 12;
12420 }
12421 }
12422 else
12423 {
12424 // copy byte to buffer (all previous bytes
12425 // been copied have in default case above)
12426 string_buffer[bytes++] = s[i];
12427 }
12428 break;
12429 }
12430 }
12431
12432 // write buffer and reset index; there must be 13 bytes
12433 // left, as this is the maximal number of bytes to be
12434 // written ("\uxxxx\uxxxx\0") for one code point
12435 if (string_buffer.size() - bytes < 13)
12436 {
12437 o->write_characters(string_buffer.data(), bytes);
12438 bytes = 0;
12439 }
12440
12441 // remember the byte position of this accept
12442 bytes_after_last_accept = bytes;
12443 undumped_chars = 0;
12444 break;
12445 }
12446
12447 case UTF8_REJECT: // decode found invalid UTF-8 byte
12448 {
12449 switch (error_handler)
12450 {
12451 case error_handler_t::strict:
12452 {
12453 std::string sn(3, '\0');
12454 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
12455 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn));
12456 }
12457
12458 case error_handler_t::ignore:
12459 case error_handler_t::replace:
12460 {
12461 // in case we saw this character the first time, we
12462 // would like to read it again, because the byte
12463 // may be OK for itself, but just not OK for the
12464 // previous sequence
12465 if (undumped_chars > 0)
12466 {
12467 --i;
12468 }
12469
12470 // reset length buffer to the last accepted index;
12471 // thus removing/ignoring the invalid characters
12472 bytes = bytes_after_last_accept;
12473
12474 if (error_handler == error_handler_t::replace)
12475 {
12476 // add a replacement character
12477 if (ensure_ascii)
12478 {
12479 string_buffer[bytes++] = '\\';
12480 string_buffer[bytes++] = 'u';
12481 string_buffer[bytes++] = 'f';
12482 string_buffer[bytes++] = 'f';
12483 string_buffer[bytes++] = 'f';
12484 string_buffer[bytes++] = 'd';
12485 }
12486 else
12487 {
12488 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
12489 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
12490 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
12491 }
12492
12493 // write buffer and reset index; there must be 13 bytes
12494 // left, as this is the maximal number of bytes to be
12495 // written ("\uxxxx\uxxxx\0") for one code point
12496 if (string_buffer.size() - bytes < 13)
12497 {
12498 o->write_characters(string_buffer.data(), bytes);
12499 bytes = 0;
12500 }
12501
12502 bytes_after_last_accept = bytes;
12503 }
12504
12505 undumped_chars = 0;
12506
12507 // continue processing the string
12508 state = UTF8_ACCEPT;
12509 break;
12510 }
12511
12512 default: // LCOV_EXCL_LINE
12513 assert(false); // LCOV_EXCL_LINE
12514 }
12515 break;
12516 }
12517
12518 default: // decode found yet incomplete multi-byte code point
12519 {
12520 if (not ensure_ascii)
12521 {
12522 // code point will not be escaped - copy byte to buffer
12523 string_buffer[bytes++] = s[i];
12524 }
12525 ++undumped_chars;
12526 break;
12527 }
12528 }
12529 }
12530
12531 // we finished processing the string
12532 if (JSON_LIKELY(state == UTF8_ACCEPT))
12533 {
12534 // write buffer
12535 if (bytes > 0)
12536 {
12537 o->write_characters(string_buffer.data(), bytes);
12538 }
12539 }
12540 else
12541 {
12542 // we finish reading, but do not accept: string was incomplete
12543 switch (error_handler)
12544 {
12545 case error_handler_t::strict:
12546 {
12547 std::string sn(3, '\0');
12548 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
12549 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn));
12550 }
12551
12552 case error_handler_t::ignore:
12553 {
12554 // write all accepted bytes
12555 o->write_characters(string_buffer.data(), bytes_after_last_accept);
12556 break;
12557 }
12558
12559 case error_handler_t::replace:
12560 {
12561 // write all accepted bytes
12562 o->write_characters(string_buffer.data(), bytes_after_last_accept);
12563 // add a replacement character
12564 if (ensure_ascii)
12565 {
12566 o->write_characters("\\ufffd", 6);
12567 }
12568 else
12569 {
12570 o->write_characters("\xEF\xBF\xBD", 3);
12571 }
12572 break;
12573 }
12574
12575 default: // LCOV_EXCL_LINE
12576 assert(false); // LCOV_EXCL_LINE
12577 }
12578 }
12579 }
12580
12581 /*!
12582 @brief count digits
12583
12584 Count the number of decimal (base 10) digits for an input unsigned integer.
12585
12586 @param[in] x unsigned integer number to count its digits
12587 @return number of decimal digits
12588 */
count_digits(number_unsigned_t x)12589 inline unsigned int count_digits(number_unsigned_t x) noexcept
12590 {
12591 unsigned int n_digits = 1;
12592 for (;;)
12593 {
12594 if (x < 10)
12595 {
12596 return n_digits;
12597 }
12598 if (x < 100)
12599 {
12600 return n_digits + 1;
12601 }
12602 if (x < 1000)
12603 {
12604 return n_digits + 2;
12605 }
12606 if (x < 10000)
12607 {
12608 return n_digits + 3;
12609 }
12610 x = x / 10000u;
12611 n_digits += 4;
12612 }
12613 }
12614
12615 /*!
12616 @brief dump an integer
12617
12618 Dump a given integer to output stream @a o. Works internally with
12619 @a number_buffer.
12620
12621 @param[in] x integer number (signed or unsigned) to dump
12622 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
12623 */
12624 template<typename NumberType, detail::enable_if_t<
12625 std::is_same<NumberType, number_unsigned_t>::value or
12626 std::is_same<NumberType, number_integer_t>::value,
12627 int> = 0>
dump_integer(NumberType x)12628 void dump_integer(NumberType x)
12629 {
12630 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
12631 {
12632 {
12633 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
12634 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
12635 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
12636 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
12637 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
12638 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
12639 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
12640 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
12641 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
12642 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
12643 }
12644 };
12645
12646 // special case for "0"
12647 if (x == 0)
12648 {
12649 o->write_character('0');
12650 return;
12651 }
12652
12653 // use a pointer to fill the buffer
12654 auto buffer_ptr = number_buffer.begin();
12655
12656 const bool is_negative = std::is_same<NumberType, number_integer_t>::value and not(x >= 0); // see issue #755
12657 number_unsigned_t abs_value;
12658
12659 unsigned int n_chars;
12660
12661 if (is_negative)
12662 {
12663 *buffer_ptr = '-';
12664 abs_value = static_cast<number_unsigned_t>(std::abs(static_cast<std::intmax_t>(x)));
12665
12666 // account one more byte for the minus sign
12667 n_chars = 1 + count_digits(abs_value);
12668 }
12669 else
12670 {
12671 abs_value = static_cast<number_unsigned_t>(x);
12672 n_chars = count_digits(abs_value);
12673 }
12674
12675 // spare 1 byte for '\0'
12676 assert(n_chars < number_buffer.size() - 1);
12677
12678 // jump to the end to generate the string from backward
12679 // so we later avoid reversing the result
12680 buffer_ptr += n_chars;
12681
12682 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
12683 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
12684 while (abs_value >= 100)
12685 {
12686 const auto digits_index = static_cast<unsigned>((abs_value % 100));
12687 abs_value /= 100;
12688 *(--buffer_ptr) = digits_to_99[digits_index][1];
12689 *(--buffer_ptr) = digits_to_99[digits_index][0];
12690 }
12691
12692 if (abs_value >= 10)
12693 {
12694 const auto digits_index = static_cast<unsigned>(abs_value);
12695 *(--buffer_ptr) = digits_to_99[digits_index][1];
12696 *(--buffer_ptr) = digits_to_99[digits_index][0];
12697 }
12698 else
12699 {
12700 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
12701 }
12702
12703 o->write_characters(number_buffer.data(), n_chars);
12704 }
12705
12706 /*!
12707 @brief dump a floating-point number
12708
12709 Dump a given floating-point number to output stream @a o. Works internally
12710 with @a number_buffer.
12711
12712 @param[in] x floating-point number to dump
12713 */
dump_float(number_float_t x)12714 void dump_float(number_float_t x)
12715 {
12716 // NaN / inf
12717 if (not std::isfinite(x))
12718 {
12719 o->write_characters("null", 4);
12720 return;
12721 }
12722
12723 // If number_float_t is an IEEE-754 single or double precision number,
12724 // use the Grisu2 algorithm to produce short numbers which are
12725 // guaranteed to round-trip, using strtof and strtod, resp.
12726 //
12727 // NB: The test below works if <long double> == <double>.
12728 static constexpr bool is_ieee_single_or_double
12729 = (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
12730 (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);
12731
12732 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
12733 }
12734
dump_float(number_float_t x,std::true_type)12735 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
12736 {
12737 char* begin = number_buffer.data();
12738 char* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
12739
12740 o->write_characters(begin, static_cast<size_t>(end - begin));
12741 }
12742
dump_float(number_float_t x,std::false_type)12743 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
12744 {
12745 // get number of digits for a float -> text -> float round-trip
12746 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
12747
12748 // the actual conversion
12749 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
12750
12751 // negative value indicates an error
12752 assert(len > 0);
12753 // check if buffer was large enough
12754 assert(static_cast<std::size_t>(len) < number_buffer.size());
12755
12756 // erase thousands separator
12757 if (thousands_sep != '\0')
12758 {
12759 const auto end = std::remove(number_buffer.begin(),
12760 number_buffer.begin() + len, thousands_sep);
12761 std::fill(end, number_buffer.end(), '\0');
12762 assert((end - number_buffer.begin()) <= len);
12763 len = (end - number_buffer.begin());
12764 }
12765
12766 // convert decimal point to '.'
12767 if (decimal_point != '\0' and decimal_point != '.')
12768 {
12769 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
12770 if (dec_pos != number_buffer.end())
12771 {
12772 *dec_pos = '.';
12773 }
12774 }
12775
12776 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
12777
12778 // determine if need to append ".0"
12779 const bool value_is_int_like =
12780 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
12781 [](char c)
12782 {
12783 return c == '.' or c == 'e';
12784 });
12785
12786 if (value_is_int_like)
12787 {
12788 o->write_characters(".0", 2);
12789 }
12790 }
12791
12792 /*!
12793 @brief check whether a string is UTF-8 encoded
12794
12795 The function checks each byte of a string whether it is UTF-8 encoded. The
12796 result of the check is stored in the @a state parameter. The function must
12797 be called initially with state 0 (accept). State 1 means the string must
12798 be rejected, because the current byte is not allowed. If the string is
12799 completely processed, but the state is non-zero, the string ended
12800 prematurely; that is, the last byte indicated more bytes should have
12801 followed.
12802
12803 @param[in,out] state the state of the decoding
12804 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
12805 @param[in] byte next byte to decode
12806 @return new state
12807
12808 @note The function has been edited: a std::array is used.
12809
12810 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
12811 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
12812 */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)12813 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
12814 {
12815 static const std::array<std::uint8_t, 400> utf8d =
12816 {
12817 {
12818 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
12819 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
12820 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
12821 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
12822 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
12823 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
12824 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
12825 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
12826 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
12827 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
12828 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
12829 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
12830 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
12831 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
12832 }
12833 };
12834
12835 const std::uint8_t type = utf8d[byte];
12836
12837 codep = (state != UTF8_ACCEPT)
12838 ? (byte & 0x3fu) | (codep << 6u)
12839 : (0xFFu >> type) & (byte);
12840
12841 state = utf8d[256u + state * 16u + type];
12842 return state;
12843 }
12844
12845 private:
12846 /// the output of the serializer
12847 output_adapter_t<char> o = nullptr;
12848
12849 /// a (hopefully) large enough character buffer
12850 std::array<char, 64> number_buffer{{}};
12851
12852 /// the locale
12853 const std::lconv* loc = nullptr;
12854 /// the locale's thousand separator character
12855 const char thousands_sep = '\0';
12856 /// the locale's decimal point character
12857 const char decimal_point = '\0';
12858
12859 /// string buffer
12860 std::array<char, 512> string_buffer{{}};
12861
12862 /// the indentation character
12863 const char indent_char;
12864 /// the indentation string
12865 string_t indent_string;
12866
12867 /// error_handler how to react on decoding errors
12868 const error_handler_t error_handler;
12869 };
12870 } // namespace detail
12871 } // namespace nlohmann
12872
12873 // #include <nlohmann/detail/value_t.hpp>
12874
12875 // #include <nlohmann/json_fwd.hpp>
12876
12877
12878 /*!
12879 @brief namespace for Niels Lohmann
12880 @see https://github.com/nlohmann
12881 @since version 1.0.0
12882 */
12883 namespace nlohmann
12884 {
12885
12886 /*!
12887 @brief a class to store JSON values
12888
12889 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
12890 in @ref object_t)
12891 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
12892 in @ref array_t)
12893 @tparam StringType type for JSON strings and object keys (`std::string` by
12894 default; will be used in @ref string_t)
12895 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
12896 in @ref boolean_t)
12897 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
12898 default; will be used in @ref number_integer_t)
12899 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
12900 `uint64_t` by default; will be used in @ref number_unsigned_t)
12901 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
12902 default; will be used in @ref number_float_t)
12903 @tparam AllocatorType type of the allocator to use (`std::allocator` by
12904 default)
12905 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
12906 and `from_json()` (@ref adl_serializer by default)
12907
12908 @requirement The class satisfies the following concept requirements:
12909 - Basic
12910 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
12911 JSON values can be default constructed. The result will be a JSON null
12912 value.
12913 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
12914 A JSON value can be constructed from an rvalue argument.
12915 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
12916 A JSON value can be copy-constructed from an lvalue expression.
12917 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
12918 A JSON value van be assigned from an rvalue argument.
12919 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
12920 A JSON value can be copy-assigned from an lvalue expression.
12921 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
12922 JSON values can be destructed.
12923 - Layout
12924 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
12925 JSON values have
12926 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
12927 All non-static data members are private and standard layout types, the
12928 class has no virtual functions or (virtual) base classes.
12929 - Library-wide
12930 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
12931 JSON values can be compared with `==`, see @ref
12932 operator==(const_reference,const_reference).
12933 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
12934 JSON values can be compared with `<`, see @ref
12935 operator<(const_reference,const_reference).
12936 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
12937 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
12938 other compatible types, using unqualified function call @ref swap().
12939 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
12940 JSON values can be compared against `std::nullptr_t` objects which are used
12941 to model the `null` value.
12942 - Container
12943 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
12944 JSON values can be used like STL containers and provide iterator access.
12945 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
12946 JSON values can be used like STL containers and provide reverse iterator
12947 access.
12948
12949 @invariant The member variables @a m_value and @a m_type have the following
12950 relationship:
12951 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
12952 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
12953 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
12954 The invariants are checked by member function assert_invariant().
12955
12956 @internal
12957 @note ObjectType trick from http://stackoverflow.com/a/9860911
12958 @endinternal
12959
12960 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
12961 Format](http://rfc7159.net/rfc7159)
12962
12963 @since version 1.0.0
12964
12965 @nosubgrouping
12966 */
12967 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12968 class basic_json
12969 {
12970 private:
12971 template<detail::value_t> friend struct detail::external_constructor;
12972 friend ::nlohmann::json_pointer<basic_json>;
12973 friend ::nlohmann::detail::parser<basic_json>;
12974 friend ::nlohmann::detail::serializer<basic_json>;
12975 template<typename BasicJsonType>
12976 friend class ::nlohmann::detail::iter_impl;
12977 template<typename BasicJsonType, typename CharType>
12978 friend class ::nlohmann::detail::binary_writer;
12979 template<typename BasicJsonType, typename SAX>
12980 friend class ::nlohmann::detail::binary_reader;
12981 template<typename BasicJsonType>
12982 friend class ::nlohmann::detail::json_sax_dom_parser;
12983 template<typename BasicJsonType>
12984 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
12985
12986 /// workaround type for MSVC
12987 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
12988
12989 // convenience aliases for types residing in namespace detail;
12990 using lexer = ::nlohmann::detail::lexer<basic_json>;
12991 using parser = ::nlohmann::detail::parser<basic_json>;
12992
12993 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
12994 template<typename BasicJsonType>
12995 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
12996 template<typename BasicJsonType>
12997 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
12998 template<typename Iterator>
12999 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
13000 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
13001
13002 template<typename CharType>
13003 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
13004
13005 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
13006 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
13007
13008 using serializer = ::nlohmann::detail::serializer<basic_json>;
13009
13010 public:
13011 using value_t = detail::value_t;
13012 /// JSON Pointer, see @ref nlohmann::json_pointer
13013 using json_pointer = ::nlohmann::json_pointer<basic_json>;
13014 template<typename T, typename SFINAE>
13015 using json_serializer = JSONSerializer<T, SFINAE>;
13016 /// how to treat decoding errors
13017 using error_handler_t = detail::error_handler_t;
13018 /// helper type for initializer lists of basic_json values
13019 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
13020
13021 using input_format_t = detail::input_format_t;
13022 /// SAX interface type, see @ref nlohmann::json_sax
13023 using json_sax_t = json_sax<basic_json>;
13024
13025 ////////////////
13026 // exceptions //
13027 ////////////////
13028
13029 /// @name exceptions
13030 /// Classes to implement user-defined exceptions.
13031 /// @{
13032
13033 /// @copydoc detail::exception
13034 using exception = detail::exception;
13035 /// @copydoc detail::parse_error
13036 using parse_error = detail::parse_error;
13037 /// @copydoc detail::invalid_iterator
13038 using invalid_iterator = detail::invalid_iterator;
13039 /// @copydoc detail::type_error
13040 using type_error = detail::type_error;
13041 /// @copydoc detail::out_of_range
13042 using out_of_range = detail::out_of_range;
13043 /// @copydoc detail::other_error
13044 using other_error = detail::other_error;
13045
13046 /// @}
13047
13048
13049 /////////////////////
13050 // container types //
13051 /////////////////////
13052
13053 /// @name container types
13054 /// The canonic container types to use @ref basic_json like any other STL
13055 /// container.
13056 /// @{
13057
13058 /// the type of elements in a basic_json container
13059 using value_type = basic_json;
13060
13061 /// the type of an element reference
13062 using reference = value_type&;
13063 /// the type of an element const reference
13064 using const_reference = const value_type&;
13065
13066 /// a type to represent differences between iterators
13067 using difference_type = std::ptrdiff_t;
13068 /// a type to represent container sizes
13069 using size_type = std::size_t;
13070
13071 /// the allocator type
13072 using allocator_type = AllocatorType<basic_json>;
13073
13074 /// the type of an element pointer
13075 using pointer = typename std::allocator_traits<allocator_type>::pointer;
13076 /// the type of an element const pointer
13077 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
13078
13079 /// an iterator for a basic_json container
13080 using iterator = iter_impl<basic_json>;
13081 /// a const iterator for a basic_json container
13082 using const_iterator = iter_impl<const basic_json>;
13083 /// a reverse iterator for a basic_json container
13084 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
13085 /// a const reverse iterator for a basic_json container
13086 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
13087
13088 /// @}
13089
13090
13091 /*!
13092 @brief returns the allocator associated with the container
13093 */
get_allocator()13094 static allocator_type get_allocator()
13095 {
13096 return allocator_type();
13097 }
13098
13099 /*!
13100 @brief returns version information on the library
13101
13102 This function returns a JSON object with information about the library,
13103 including the version number and information on the platform and compiler.
13104
13105 @return JSON object holding version information
13106 key | description
13107 ----------- | ---------------
13108 `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).
13109 `copyright` | The copyright line for the library as string.
13110 `name` | The name of the library as string.
13111 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
13112 `url` | The URL of the project as string.
13113 `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).
13114
13115 @liveexample{The following code shows an example output of the `meta()`
13116 function.,meta}
13117
13118 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13119 changes to any JSON value.
13120
13121 @complexity Constant.
13122
13123 @since 2.1.0
13124 */
13125 JSON_NODISCARD
meta()13126 static basic_json meta()
13127 {
13128 basic_json result;
13129
13130 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
13131 result["name"] = "JSON for Modern C++";
13132 result["url"] = "https://github.com/nlohmann/json";
13133 result["version"]["string"] =
13134 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
13135 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
13136 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
13137 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
13138 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
13139 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
13140
13141 #ifdef _WIN32
13142 result["platform"] = "win32";
13143 #elif defined __linux__
13144 result["platform"] = "linux";
13145 #elif defined __APPLE__
13146 result["platform"] = "apple";
13147 #elif defined __unix__
13148 result["platform"] = "unix";
13149 #else
13150 result["platform"] = "unknown";
13151 #endif
13152
13153 #if defined(__ICC) || defined(__INTEL_COMPILER)
13154 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
13155 #elif defined(__clang__)
13156 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
13157 #elif defined(__GNUC__) || defined(__GNUG__)
13158 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
13159 #elif defined(__HP_cc) || defined(__HP_aCC)
13160 result["compiler"] = "hp"
13161 #elif defined(__IBMCPP__)
13162 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
13163 #elif defined(_MSC_VER)
13164 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
13165 #elif defined(__PGI)
13166 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
13167 #elif defined(__SUNPRO_CC)
13168 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
13169 #else
13170 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
13171 #endif
13172
13173 #ifdef __cplusplus
13174 result["compiler"]["c++"] = std::to_string(__cplusplus);
13175 #else
13176 result["compiler"]["c++"] = "unknown";
13177 #endif
13178 return result;
13179 }
13180
13181
13182 ///////////////////////////
13183 // JSON value data types //
13184 ///////////////////////////
13185
13186 /// @name JSON value data types
13187 /// The data types to store a JSON value. These types are derived from
13188 /// the template arguments passed to class @ref basic_json.
13189 /// @{
13190
13191 #if defined(JSON_HAS_CPP_14)
13192 // Use transparent comparator if possible, combined with perfect forwarding
13193 // on find() and count() calls prevents unnecessary string construction.
13194 using object_comparator_t = std::less<>;
13195 #else
13196 using object_comparator_t = std::less<StringType>;
13197 #endif
13198
13199 /*!
13200 @brief a type for an object
13201
13202 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
13203 > An object is an unordered collection of zero or more name/value pairs,
13204 > where a name is a string and a value is a string, number, boolean, null,
13205 > object, or array.
13206
13207 To store objects in C++, a type is defined by the template parameters
13208 described below.
13209
13210 @tparam ObjectType the container to store objects (e.g., `std::map` or
13211 `std::unordered_map`)
13212 @tparam StringType the type of the keys or names (e.g., `std::string`).
13213 The comparison function `std::less<StringType>` is used to order elements
13214 inside the container.
13215 @tparam AllocatorType the allocator to use for objects (e.g.,
13216 `std::allocator`)
13217
13218 #### Default type
13219
13220 With the default values for @a ObjectType (`std::map`), @a StringType
13221 (`std::string`), and @a AllocatorType (`std::allocator`), the default
13222 value for @a object_t is:
13223
13224 @code {.cpp}
13225 std::map<
13226 std::string, // key_type
13227 basic_json, // value_type
13228 std::less<std::string>, // key_compare
13229 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
13230 >
13231 @endcode
13232
13233 #### Behavior
13234
13235 The choice of @a object_t influences the behavior of the JSON class. With
13236 the default type, objects have the following behavior:
13237
13238 - When all names are unique, objects will be interoperable in the sense
13239 that all software implementations receiving that object will agree on
13240 the name-value mappings.
13241 - When the names within an object are not unique, it is unspecified which
13242 one of the values for a given key will be chosen. For instance,
13243 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
13244 `{"key": 2}`.
13245 - Internally, name/value pairs are stored in lexicographical order of the
13246 names. Objects will also be serialized (see @ref dump) in this order.
13247 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
13248 and serialized as `{"a": 2, "b": 1}`.
13249 - When comparing objects, the order of the name/value pairs is irrelevant.
13250 This makes objects interoperable in the sense that they will not be
13251 affected by these differences. For instance, `{"b": 1, "a": 2}` and
13252 `{"a": 2, "b": 1}` will be treated as equal.
13253
13254 #### Limits
13255
13256 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13257 > An implementation may set limits on the maximum depth of nesting.
13258
13259 In this class, the object's limit of nesting is not explicitly constrained.
13260 However, a maximum depth of nesting may be introduced by the compiler or
13261 runtime environment. A theoretical limit can be queried by calling the
13262 @ref max_size function of a JSON object.
13263
13264 #### Storage
13265
13266 Objects are stored as pointers in a @ref basic_json type. That is, for any
13267 access to object values, a pointer of type `object_t*` must be
13268 dereferenced.
13269
13270 @sa @ref array_t -- type for an array value
13271
13272 @since version 1.0.0
13273
13274 @note The order name/value pairs are added to the object is *not*
13275 preserved by the library. Therefore, iterating an object may return
13276 name/value pairs in a different order than they were originally stored. In
13277 fact, keys will be traversed in alphabetical order as `std::map` with
13278 `std::less` is used by default. Please note this behavior conforms to [RFC
13279 7159](http://rfc7159.net/rfc7159), because any order implements the
13280 specified "unordered" nature of JSON objects.
13281 */
13282 using object_t = ObjectType<StringType,
13283 basic_json,
13284 object_comparator_t,
13285 AllocatorType<std::pair<const StringType,
13286 basic_json>>>;
13287
13288 /*!
13289 @brief a type for an array
13290
13291 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
13292 > An array is an ordered sequence of zero or more values.
13293
13294 To store objects in C++, a type is defined by the template parameters
13295 explained below.
13296
13297 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
13298 `std::list`)
13299 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
13300
13301 #### Default type
13302
13303 With the default values for @a ArrayType (`std::vector`) and @a
13304 AllocatorType (`std::allocator`), the default value for @a array_t is:
13305
13306 @code {.cpp}
13307 std::vector<
13308 basic_json, // value_type
13309 std::allocator<basic_json> // allocator_type
13310 >
13311 @endcode
13312
13313 #### Limits
13314
13315 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13316 > An implementation may set limits on the maximum depth of nesting.
13317
13318 In this class, the array's limit of nesting is not explicitly constrained.
13319 However, a maximum depth of nesting may be introduced by the compiler or
13320 runtime environment. A theoretical limit can be queried by calling the
13321 @ref max_size function of a JSON array.
13322
13323 #### Storage
13324
13325 Arrays are stored as pointers in a @ref basic_json type. That is, for any
13326 access to array values, a pointer of type `array_t*` must be dereferenced.
13327
13328 @sa @ref object_t -- type for an object value
13329
13330 @since version 1.0.0
13331 */
13332 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
13333
13334 /*!
13335 @brief a type for a string
13336
13337 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
13338 > A string is a sequence of zero or more Unicode characters.
13339
13340 To store objects in C++, a type is defined by the template parameter
13341 described below. Unicode values are split by the JSON class into
13342 byte-sized characters during deserialization.
13343
13344 @tparam StringType the container to store strings (e.g., `std::string`).
13345 Note this container is used for keys/names in objects, see @ref object_t.
13346
13347 #### Default type
13348
13349 With the default values for @a StringType (`std::string`), the default
13350 value for @a string_t is:
13351
13352 @code {.cpp}
13353 std::string
13354 @endcode
13355
13356 #### Encoding
13357
13358 Strings are stored in UTF-8 encoding. Therefore, functions like
13359 `std::string::size()` or `std::string::length()` return the number of
13360 bytes in the string rather than the number of characters or glyphs.
13361
13362 #### String comparison
13363
13364 [RFC 7159](http://rfc7159.net/rfc7159) states:
13365 > Software implementations are typically required to test names of object
13366 > members for equality. Implementations that transform the textual
13367 > representation into sequences of Unicode code units and then perform the
13368 > comparison numerically, code unit by code unit, are interoperable in the
13369 > sense that implementations will agree in all cases on equality or
13370 > inequality of two strings. For example, implementations that compare
13371 > strings with escaped characters unconverted may incorrectly find that
13372 > `"a\\b"` and `"a\u005Cb"` are not equal.
13373
13374 This implementation is interoperable as it does compare strings code unit
13375 by code unit.
13376
13377 #### Storage
13378
13379 String values are stored as pointers in a @ref basic_json type. That is,
13380 for any access to string values, a pointer of type `string_t*` must be
13381 dereferenced.
13382
13383 @since version 1.0.0
13384 */
13385 using string_t = StringType;
13386
13387 /*!
13388 @brief a type for a boolean
13389
13390 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
13391 type which differentiates the two literals `true` and `false`.
13392
13393 To store objects in C++, a type is defined by the template parameter @a
13394 BooleanType which chooses the type to use.
13395
13396 #### Default type
13397
13398 With the default values for @a BooleanType (`bool`), the default value for
13399 @a boolean_t is:
13400
13401 @code {.cpp}
13402 bool
13403 @endcode
13404
13405 #### Storage
13406
13407 Boolean values are stored directly inside a @ref basic_json type.
13408
13409 @since version 1.0.0
13410 */
13411 using boolean_t = BooleanType;
13412
13413 /*!
13414 @brief a type for a number (integer)
13415
13416 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13417 > The representation of numbers is similar to that used in most
13418 > programming languages. A number is represented in base 10 using decimal
13419 > digits. It contains an integer component that may be prefixed with an
13420 > optional minus sign, which may be followed by a fraction part and/or an
13421 > exponent part. Leading zeros are not allowed. (...) Numeric values that
13422 > cannot be represented in the grammar below (such as Infinity and NaN)
13423 > are not permitted.
13424
13425 This description includes both integer and floating-point numbers.
13426 However, C++ allows more precise storage if it is known whether the number
13427 is a signed integer, an unsigned integer or a floating-point number.
13428 Therefore, three different types, @ref number_integer_t, @ref
13429 number_unsigned_t and @ref number_float_t are used.
13430
13431 To store integer numbers in C++, a type is defined by the template
13432 parameter @a NumberIntegerType which chooses the type to use.
13433
13434 #### Default type
13435
13436 With the default values for @a NumberIntegerType (`int64_t`), the default
13437 value for @a number_integer_t is:
13438
13439 @code {.cpp}
13440 int64_t
13441 @endcode
13442
13443 #### Default behavior
13444
13445 - The restrictions about leading zeros is not enforced in C++. Instead,
13446 leading zeros in integer literals lead to an interpretation as octal
13447 number. Internally, the value will be stored as decimal number. For
13448 instance, the C++ integer literal `010` will be serialized to `8`.
13449 During deserialization, leading zeros yield an error.
13450 - Not-a-number (NaN) values will be serialized to `null`.
13451
13452 #### Limits
13453
13454 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13455 > An implementation may set limits on the range and precision of numbers.
13456
13457 When the default type is used, the maximal integer number that can be
13458 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
13459 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
13460 that are out of range will yield over/underflow when used in a
13461 constructor. During deserialization, too large or small integer numbers
13462 will be automatically be stored as @ref number_unsigned_t or @ref
13463 number_float_t.
13464
13465 [RFC 7159](http://rfc7159.net/rfc7159) further states:
13466 > Note that when such software is used, numbers that are integers and are
13467 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
13468 > that implementations will agree exactly on their numeric values.
13469
13470 As this range is a subrange of the exactly supported range [INT64_MIN,
13471 INT64_MAX], this class's integer type is interoperable.
13472
13473 #### Storage
13474
13475 Integer number values are stored directly inside a @ref basic_json type.
13476
13477 @sa @ref number_float_t -- type for number values (floating-point)
13478
13479 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
13480
13481 @since version 1.0.0
13482 */
13483 using number_integer_t = NumberIntegerType;
13484
13485 /*!
13486 @brief a type for a number (unsigned)
13487
13488 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13489 > The representation of numbers is similar to that used in most
13490 > programming languages. A number is represented in base 10 using decimal
13491 > digits. It contains an integer component that may be prefixed with an
13492 > optional minus sign, which may be followed by a fraction part and/or an
13493 > exponent part. Leading zeros are not allowed. (...) Numeric values that
13494 > cannot be represented in the grammar below (such as Infinity and NaN)
13495 > are not permitted.
13496
13497 This description includes both integer and floating-point numbers.
13498 However, C++ allows more precise storage if it is known whether the number
13499 is a signed integer, an unsigned integer or a floating-point number.
13500 Therefore, three different types, @ref number_integer_t, @ref
13501 number_unsigned_t and @ref number_float_t are used.
13502
13503 To store unsigned integer numbers in C++, a type is defined by the
13504 template parameter @a NumberUnsignedType which chooses the type to use.
13505
13506 #### Default type
13507
13508 With the default values for @a NumberUnsignedType (`uint64_t`), the
13509 default value for @a number_unsigned_t is:
13510
13511 @code {.cpp}
13512 uint64_t
13513 @endcode
13514
13515 #### Default behavior
13516
13517 - The restrictions about leading zeros is not enforced in C++. Instead,
13518 leading zeros in integer literals lead to an interpretation as octal
13519 number. Internally, the value will be stored as decimal number. For
13520 instance, the C++ integer literal `010` will be serialized to `8`.
13521 During deserialization, leading zeros yield an error.
13522 - Not-a-number (NaN) values will be serialized to `null`.
13523
13524 #### Limits
13525
13526 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
13527 > An implementation may set limits on the range and precision of numbers.
13528
13529 When the default type is used, the maximal integer number that can be
13530 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
13531 number that can be stored is `0`. Integer numbers that are out of range
13532 will yield over/underflow when used in a constructor. During
13533 deserialization, too large or small integer numbers will be automatically
13534 be stored as @ref number_integer_t or @ref number_float_t.
13535
13536 [RFC 7159](http://rfc7159.net/rfc7159) further states:
13537 > Note that when such software is used, numbers that are integers and are
13538 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
13539 > that implementations will agree exactly on their numeric values.
13540
13541 As this range is a subrange (when considered in conjunction with the
13542 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
13543 this class's integer type is interoperable.
13544
13545 #### Storage
13546
13547 Integer number values are stored directly inside a @ref basic_json type.
13548
13549 @sa @ref number_float_t -- type for number values (floating-point)
13550 @sa @ref number_integer_t -- type for number values (integer)
13551
13552 @since version 2.0.0
13553 */
13554 using number_unsigned_t = NumberUnsignedType;
13555
13556 /*!
13557 @brief a type for a number (floating-point)
13558
13559 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
13560 > The representation of numbers is similar to that used in most
13561 > programming languages. A number is represented in base 10 using decimal
13562 > digits. It contains an integer component that may be prefixed with an
13563 > optional minus sign, which may be followed by a fraction part and/or an
13564 > exponent part. Leading zeros are not allowed. (...) Numeric values that
13565 > cannot be represented in the grammar below (such as Infinity and NaN)
13566 > are not permitted.
13567
13568 This description includes both integer and floating-point numbers.
13569 However, C++ allows more precise storage if it is known whether the number
13570 is a signed integer, an unsigned integer or a floating-point number.
13571 Therefore, three different types, @ref number_integer_t, @ref
13572 number_unsigned_t and @ref number_float_t are used.
13573
13574 To store floating-point numbers in C++, a type is defined by the template
13575 parameter @a NumberFloatType which chooses the type to use.
13576
13577 #### Default type
13578
13579 With the default values for @a NumberFloatType (`double`), the default
13580 value for @a number_float_t is:
13581
13582 @code {.cpp}
13583 double
13584 @endcode
13585
13586 #### Default behavior
13587
13588 - The restrictions about leading zeros is not enforced in C++. Instead,
13589 leading zeros in floating-point literals will be ignored. Internally,
13590 the value will be stored as decimal number. For instance, the C++
13591 floating-point literal `01.2` will be serialized to `1.2`. During
13592 deserialization, leading zeros yield an error.
13593 - Not-a-number (NaN) values will be serialized to `null`.
13594
13595 #### Limits
13596
13597 [RFC 7159](http://rfc7159.net/rfc7159) states:
13598 > This specification allows implementations to set limits on the range and
13599 > precision of numbers accepted. Since software that implements IEEE
13600 > 754-2008 binary64 (double precision) numbers is generally available and
13601 > widely used, good interoperability can be achieved by implementations
13602 > that expect no more precision or range than these provide, in the sense
13603 > that implementations will approximate JSON numbers within the expected
13604 > precision.
13605
13606 This implementation does exactly follow this approach, as it uses double
13607 precision floating-point numbers. Note values smaller than
13608 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
13609 will be stored as NaN internally and be serialized to `null`.
13610
13611 #### Storage
13612
13613 Floating-point number values are stored directly inside a @ref basic_json
13614 type.
13615
13616 @sa @ref number_integer_t -- type for number values (integer)
13617
13618 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
13619
13620 @since version 1.0.0
13621 */
13622 using number_float_t = NumberFloatType;
13623
13624 /// @}
13625
13626 private:
13627
13628 /// helper for exception-safe object creation
13629 template<typename T, typename... Args>
create(Args &&...args)13630 static T* create(Args&& ... args)
13631 {
13632 AllocatorType<T> alloc;
13633 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
13634
13635 auto deleter = [&](T * object)
13636 {
13637 AllocatorTraits::deallocate(alloc, object, 1);
13638 };
13639 std::unique_ptr<T, decltype(deleter)> object(AllocatorTraits::allocate(alloc, 1), deleter);
13640 AllocatorTraits::construct(alloc, object.get(), std::forward<Args>(args)...);
13641 assert(object != nullptr);
13642 return object.release();
13643 }
13644
13645 ////////////////////////
13646 // JSON value storage //
13647 ////////////////////////
13648
13649 /*!
13650 @brief a JSON value
13651
13652 The actual storage for a JSON value of the @ref basic_json class. This
13653 union combines the different storage types for the JSON value types
13654 defined in @ref value_t.
13655
13656 JSON type | value_t type | used type
13657 --------- | --------------- | ------------------------
13658 object | object | pointer to @ref object_t
13659 array | array | pointer to @ref array_t
13660 string | string | pointer to @ref string_t
13661 boolean | boolean | @ref boolean_t
13662 number | number_integer | @ref number_integer_t
13663 number | number_unsigned | @ref number_unsigned_t
13664 number | number_float | @ref number_float_t
13665 null | null | *no value is stored*
13666
13667 @note Variable-length types (objects, arrays, and strings) are stored as
13668 pointers. The size of the union should not exceed 64 bits if the default
13669 value types are used.
13670
13671 @since version 1.0.0
13672 */
13673 union json_value
13674 {
13675 /// object (stored with pointer to save storage)
13676 object_t* object;
13677 /// array (stored with pointer to save storage)
13678 array_t* array;
13679 /// string (stored with pointer to save storage)
13680 string_t* string;
13681 /// boolean
13682 boolean_t boolean;
13683 /// number (integer)
13684 number_integer_t number_integer;
13685 /// number (unsigned integer)
13686 number_unsigned_t number_unsigned;
13687 /// number (floating-point)
13688 number_float_t number_float;
13689
13690 /// default constructor (for null values)
13691 json_value() = default;
13692 /// constructor for booleans
json_value(boolean_t v)13693 json_value(boolean_t v) noexcept : boolean(v) {}
13694 /// constructor for numbers (integer)
json_value(number_integer_t v)13695 json_value(number_integer_t v) noexcept : number_integer(v) {}
13696 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)13697 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
13698 /// constructor for numbers (floating-point)
json_value(number_float_t v)13699 json_value(number_float_t v) noexcept : number_float(v) {}
13700 /// constructor for empty values of a given type
json_value(value_t t)13701 json_value(value_t t)
13702 {
13703 switch (t)
13704 {
13705 case value_t::object:
13706 {
13707 object = create<object_t>();
13708 break;
13709 }
13710
13711 case value_t::array:
13712 {
13713 array = create<array_t>();
13714 break;
13715 }
13716
13717 case value_t::string:
13718 {
13719 string = create<string_t>("");
13720 break;
13721 }
13722
13723 case value_t::boolean:
13724 {
13725 boolean = boolean_t(false);
13726 break;
13727 }
13728
13729 case value_t::number_integer:
13730 {
13731 number_integer = number_integer_t(0);
13732 break;
13733 }
13734
13735 case value_t::number_unsigned:
13736 {
13737 number_unsigned = number_unsigned_t(0);
13738 break;
13739 }
13740
13741 case value_t::number_float:
13742 {
13743 number_float = number_float_t(0.0);
13744 break;
13745 }
13746
13747 case value_t::null:
13748 {
13749 object = nullptr; // silence warning, see #821
13750 break;
13751 }
13752
13753 default:
13754 {
13755 object = nullptr; // silence warning, see #821
13756 if (JSON_UNLIKELY(t == value_t::null))
13757 {
13758 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.6.1")); // LCOV_EXCL_LINE
13759 }
13760 break;
13761 }
13762 }
13763 }
13764
13765 /// constructor for strings
json_value(const string_t & value)13766 json_value(const string_t& value)
13767 {
13768 string = create<string_t>(value);
13769 }
13770
13771 /// constructor for rvalue strings
json_value(string_t && value)13772 json_value(string_t&& value)
13773 {
13774 string = create<string_t>(std::move(value));
13775 }
13776
13777 /// constructor for objects
json_value(const object_t & value)13778 json_value(const object_t& value)
13779 {
13780 object = create<object_t>(value);
13781 }
13782
13783 /// constructor for rvalue objects
json_value(object_t && value)13784 json_value(object_t&& value)
13785 {
13786 object = create<object_t>(std::move(value));
13787 }
13788
13789 /// constructor for arrays
json_value(const array_t & value)13790 json_value(const array_t& value)
13791 {
13792 array = create<array_t>(value);
13793 }
13794
13795 /// constructor for rvalue arrays
json_value(array_t && value)13796 json_value(array_t&& value)
13797 {
13798 array = create<array_t>(std::move(value));
13799 }
13800
destroy(value_t t)13801 void destroy(value_t t) noexcept
13802 {
13803 switch (t)
13804 {
13805 case value_t::object:
13806 {
13807 AllocatorType<object_t> alloc;
13808 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
13809 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
13810 break;
13811 }
13812
13813 case value_t::array:
13814 {
13815 AllocatorType<array_t> alloc;
13816 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
13817 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
13818 break;
13819 }
13820
13821 case value_t::string:
13822 {
13823 AllocatorType<string_t> alloc;
13824 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
13825 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
13826 break;
13827 }
13828
13829 default:
13830 {
13831 break;
13832 }
13833 }
13834 }
13835 };
13836
13837 /*!
13838 @brief checks the class invariants
13839
13840 This function asserts the class invariants. It needs to be called at the
13841 end of every constructor to make sure that created objects respect the
13842 invariant. Furthermore, it has to be called each time the type of a JSON
13843 value is changed, because the invariant expresses a relationship between
13844 @a m_type and @a m_value.
13845 */
assert_invariant() const13846 void assert_invariant() const noexcept
13847 {
13848 assert(m_type != value_t::object or m_value.object != nullptr);
13849 assert(m_type != value_t::array or m_value.array != nullptr);
13850 assert(m_type != value_t::string or m_value.string != nullptr);
13851 }
13852
13853 public:
13854 //////////////////////////
13855 // JSON parser callback //
13856 //////////////////////////
13857
13858 /*!
13859 @brief parser event types
13860
13861 The parser callback distinguishes the following events:
13862 - `object_start`: the parser read `{` and started to process a JSON object
13863 - `key`: the parser read a key of a value in an object
13864 - `object_end`: the parser read `}` and finished processing a JSON object
13865 - `array_start`: the parser read `[` and started to process a JSON array
13866 - `array_end`: the parser read `]` and finished processing a JSON array
13867 - `value`: the parser finished reading a JSON value
13868
13869 @image html callback_events.png "Example when certain parse events are triggered"
13870
13871 @sa @ref parser_callback_t for more information and examples
13872 */
13873 using parse_event_t = typename parser::parse_event_t;
13874
13875 /*!
13876 @brief per-element parser callback type
13877
13878 With a parser callback function, the result of parsing a JSON text can be
13879 influenced. When passed to @ref parse, it is called on certain events
13880 (passed as @ref parse_event_t via parameter @a event) with a set recursion
13881 depth @a depth and context JSON value @a parsed. The return value of the
13882 callback function is a boolean indicating whether the element that emitted
13883 the callback shall be kept or not.
13884
13885 We distinguish six scenarios (determined by the event type) in which the
13886 callback function can be called. The following table describes the values
13887 of the parameters @a depth, @a event, and @a parsed.
13888
13889 parameter @a event | description | parameter @a depth | parameter @a parsed
13890 ------------------ | ----------- | ------------------ | -------------------
13891 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
13892 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
13893 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
13894 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
13895 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
13896 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
13897
13898 @image html callback_events.png "Example when certain parse events are triggered"
13899
13900 Discarding a value (i.e., returning `false`) has different effects
13901 depending on the context in which function was called:
13902
13903 - Discarded values in structured types are skipped. That is, the parser
13904 will behave as if the discarded value was never read.
13905 - In case a value outside a structured type is skipped, it is replaced
13906 with `null`. This case happens if the top-level element is skipped.
13907
13908 @param[in] depth the depth of the recursion during parsing
13909
13910 @param[in] event an event of type parse_event_t indicating the context in
13911 the callback function has been called
13912
13913 @param[in,out] parsed the current intermediate parse result; note that
13914 writing to this value has no effect for parse_event_t::key events
13915
13916 @return Whether the JSON value which called the function during parsing
13917 should be kept (`true`) or not (`false`). In the latter case, it is either
13918 skipped completely or replaced by an empty discarded object.
13919
13920 @sa @ref parse for examples
13921
13922 @since version 1.0.0
13923 */
13924 using parser_callback_t = typename parser::parser_callback_t;
13925
13926 //////////////////
13927 // constructors //
13928 //////////////////
13929
13930 /// @name constructors and destructors
13931 /// Constructors of class @ref basic_json, copy/move constructor, copy
13932 /// assignment, static functions creating objects, and the destructor.
13933 /// @{
13934
13935 /*!
13936 @brief create an empty value with a given type
13937
13938 Create an empty JSON value with a given type. The value will be default
13939 initialized with an empty value which depends on the type:
13940
13941 Value type | initial value
13942 ----------- | -------------
13943 null | `null`
13944 boolean | `false`
13945 string | `""`
13946 number | `0`
13947 object | `{}`
13948 array | `[]`
13949
13950 @param[in] v the type of the value to create
13951
13952 @complexity Constant.
13953
13954 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13955 changes to any JSON value.
13956
13957 @liveexample{The following code shows the constructor for different @ref
13958 value_t values,basic_json__value_t}
13959
13960 @sa @ref clear() -- restores the postcondition of this constructor
13961
13962 @since version 1.0.0
13963 */
basic_json(const value_t v)13964 basic_json(const value_t v)
13965 : m_type(v), m_value(v)
13966 {
13967 assert_invariant();
13968 }
13969
13970 /*!
13971 @brief create a null object
13972
13973 Create a `null` JSON value. It either takes a null pointer as parameter
13974 (explicitly creating `null`) or no parameter (implicitly creating `null`).
13975 The passed null pointer itself is not read -- it is only used to choose
13976 the right constructor.
13977
13978 @complexity Constant.
13979
13980 @exceptionsafety No-throw guarantee: this constructor never throws
13981 exceptions.
13982
13983 @liveexample{The following code shows the constructor with and without a
13984 null pointer parameter.,basic_json__nullptr_t}
13985
13986 @since version 1.0.0
13987 */
basic_json(std::nullptr_t=nullptr)13988 basic_json(std::nullptr_t = nullptr) noexcept
13989 : basic_json(value_t::null)
13990 {
13991 assert_invariant();
13992 }
13993
13994 /*!
13995 @brief create a JSON value
13996
13997 This is a "catch all" constructor for all compatible JSON types; that is,
13998 types for which a `to_json()` method exists. The constructor forwards the
13999 parameter @a val to that method (to `json_serializer<U>::to_json` method
14000 with `U = uncvref_t<CompatibleType>`, to be exact).
14001
14002 Template type @a CompatibleType includes, but is not limited to, the
14003 following types:
14004 - **arrays**: @ref array_t and all kinds of compatible containers such as
14005 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
14006 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
14007 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
14008 which a @ref basic_json value can be constructed.
14009 - **objects**: @ref object_t and all kinds of compatible associative
14010 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
14011 and `std::unordered_multimap` with a `key_type` compatible to
14012 @ref string_t and a `value_type` from which a @ref basic_json value can
14013 be constructed.
14014 - **strings**: @ref string_t, string literals, and all compatible string
14015 containers can be used.
14016 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
14017 @ref number_float_t, and all convertible number types such as `int`,
14018 `size_t`, `int64_t`, `float` or `double` can be used.
14019 - **boolean**: @ref boolean_t / `bool` can be used.
14020
14021 See the examples below.
14022
14023 @tparam CompatibleType a type such that:
14024 - @a CompatibleType is not derived from `std::istream`,
14025 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
14026 constructors),
14027 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
14028 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
14029 @ref json_pointer, @ref iterator, etc ...)
14030 - @ref @ref json_serializer<U> has a
14031 `to_json(basic_json_t&, CompatibleType&&)` method
14032
14033 @tparam U = `uncvref_t<CompatibleType>`
14034
14035 @param[in] val the value to be forwarded to the respective constructor
14036
14037 @complexity Usually linear in the size of the passed @a val, also
14038 depending on the implementation of the called `to_json()`
14039 method.
14040
14041 @exceptionsafety Depends on the called constructor. For types directly
14042 supported by the library (i.e., all types for which no `to_json()` function
14043 was provided), strong guarantee holds: if an exception is thrown, there are
14044 no changes to any JSON value.
14045
14046 @liveexample{The following code shows the constructor with several
14047 compatible types.,basic_json__CompatibleType}
14048
14049 @since version 2.1.0
14050 */
14051 template <typename CompatibleType,
14052 typename U = detail::uncvref_t<CompatibleType>,
14053 detail::enable_if_t<
14054 not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val)14055 basic_json(CompatibleType && val) noexcept(noexcept(
14056 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
14057 std::forward<CompatibleType>(val))))
14058 {
14059 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
14060 assert_invariant();
14061 }
14062
14063 /*!
14064 @brief create a JSON value from an existing one
14065
14066 This is a constructor for existing @ref basic_json types.
14067 It does not hijack copy/move constructors, since the parameter has different
14068 template arguments than the current ones.
14069
14070 The constructor tries to convert the internal @ref m_value of the parameter.
14071
14072 @tparam BasicJsonType a type such that:
14073 - @a BasicJsonType is a @ref basic_json type.
14074 - @a BasicJsonType has different template arguments than @ref basic_json_t.
14075
14076 @param[in] val the @ref basic_json value to be converted.
14077
14078 @complexity Usually linear in the size of the passed @a val, also
14079 depending on the implementation of the called `to_json()`
14080 method.
14081
14082 @exceptionsafety Depends on the called constructor. For types directly
14083 supported by the library (i.e., all types for which no `to_json()` function
14084 was provided), strong guarantee holds: if an exception is thrown, there are
14085 no changes to any JSON value.
14086
14087 @since version 3.2.0
14088 */
14089 template <typename BasicJsonType,
14090 detail::enable_if_t<
14091 detail::is_basic_json<BasicJsonType>::value and not std::is_same<basic_json, BasicJsonType>::value, int> = 0>
basic_json(const BasicJsonType & val)14092 basic_json(const BasicJsonType& val)
14093 {
14094 using other_boolean_t = typename BasicJsonType::boolean_t;
14095 using other_number_float_t = typename BasicJsonType::number_float_t;
14096 using other_number_integer_t = typename BasicJsonType::number_integer_t;
14097 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
14098 using other_string_t = typename BasicJsonType::string_t;
14099 using other_object_t = typename BasicJsonType::object_t;
14100 using other_array_t = typename BasicJsonType::array_t;
14101
14102 switch (val.type())
14103 {
14104 case value_t::boolean:
14105 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
14106 break;
14107 case value_t::number_float:
14108 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
14109 break;
14110 case value_t::number_integer:
14111 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
14112 break;
14113 case value_t::number_unsigned:
14114 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
14115 break;
14116 case value_t::string:
14117 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
14118 break;
14119 case value_t::object:
14120 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
14121 break;
14122 case value_t::array:
14123 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
14124 break;
14125 case value_t::null:
14126 *this = nullptr;
14127 break;
14128 case value_t::discarded:
14129 m_type = value_t::discarded;
14130 break;
14131 default: // LCOV_EXCL_LINE
14132 assert(false); // LCOV_EXCL_LINE
14133 }
14134 assert_invariant();
14135 }
14136
14137 /*!
14138 @brief create a container (array or object) from an initializer list
14139
14140 Creates a JSON value of type array or object from the passed initializer
14141 list @a init. In case @a type_deduction is `true` (default), the type of
14142 the JSON value to be created is deducted from the initializer list @a init
14143 according to the following rules:
14144
14145 1. If the list is empty, an empty JSON object value `{}` is created.
14146 2. If the list consists of pairs whose first element is a string, a JSON
14147 object value is created where the first elements of the pairs are
14148 treated as keys and the second elements are as values.
14149 3. In all other cases, an array is created.
14150
14151 The rules aim to create the best fit between a C++ initializer list and
14152 JSON values. The rationale is as follows:
14153
14154 1. The empty initializer list is written as `{}` which is exactly an empty
14155 JSON object.
14156 2. C++ has no way of describing mapped types other than to list a list of
14157 pairs. As JSON requires that keys must be of type string, rule 2 is the
14158 weakest constraint one can pose on initializer lists to interpret them
14159 as an object.
14160 3. In all other cases, the initializer list could not be interpreted as
14161 JSON object type, so interpreting it as JSON array type is safe.
14162
14163 With the rules described above, the following JSON values cannot be
14164 expressed by an initializer list:
14165
14166 - the empty array (`[]`): use @ref array(initializer_list_t)
14167 with an empty initializer list in this case
14168 - arrays whose elements satisfy rule 2: use @ref
14169 array(initializer_list_t) with the same initializer list
14170 in this case
14171
14172 @note When used without parentheses around an empty initializer list, @ref
14173 basic_json() is called instead of this function, yielding the JSON null
14174 value.
14175
14176 @param[in] init initializer list with JSON values
14177
14178 @param[in] type_deduction internal parameter; when set to `true`, the type
14179 of the JSON value is deducted from the initializer list @a init; when set
14180 to `false`, the type provided via @a manual_type is forced. This mode is
14181 used by the functions @ref array(initializer_list_t) and
14182 @ref object(initializer_list_t).
14183
14184 @param[in] manual_type internal parameter; when @a type_deduction is set
14185 to `false`, the created JSON value will use the provided type (only @ref
14186 value_t::array and @ref value_t::object are valid); when @a type_deduction
14187 is set to `true`, this parameter has no effect
14188
14189 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
14190 `value_t::object`, but @a init contains an element which is not a pair
14191 whose first element is a string. In this case, the constructor could not
14192 create an object. If @a type_deduction would have be `true`, an array
14193 would have been created. See @ref object(initializer_list_t)
14194 for an example.
14195
14196 @complexity Linear in the size of the initializer list @a init.
14197
14198 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14199 changes to any JSON value.
14200
14201 @liveexample{The example below shows how JSON values are created from
14202 initializer lists.,basic_json__list_init_t}
14203
14204 @sa @ref array(initializer_list_t) -- create a JSON array
14205 value from an initializer list
14206 @sa @ref object(initializer_list_t) -- create a JSON object
14207 value from an initializer list
14208
14209 @since version 1.0.0
14210 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)14211 basic_json(initializer_list_t init,
14212 bool type_deduction = true,
14213 value_t manual_type = value_t::array)
14214 {
14215 // check if each element is an array with two elements whose first
14216 // element is a string
14217 bool is_an_object = std::all_of(init.begin(), init.end(),
14218 [](const detail::json_ref<basic_json>& element_ref)
14219 {
14220 return element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string();
14221 });
14222
14223 // adjust type if type deduction is not wanted
14224 if (not type_deduction)
14225 {
14226 // if array is wanted, do not create an object though possible
14227 if (manual_type == value_t::array)
14228 {
14229 is_an_object = false;
14230 }
14231
14232 // if object is wanted but impossible, throw an exception
14233 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
14234 {
14235 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
14236 }
14237 }
14238
14239 if (is_an_object)
14240 {
14241 // the initializer list is a list of pairs -> create object
14242 m_type = value_t::object;
14243 m_value = value_t::object;
14244
14245 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
14246 {
14247 auto element = element_ref.moved_or_copied();
14248 m_value.object->emplace(
14249 std::move(*((*element.m_value.array)[0].m_value.string)),
14250 std::move((*element.m_value.array)[1]));
14251 });
14252 }
14253 else
14254 {
14255 // the initializer list describes an array -> create array
14256 m_type = value_t::array;
14257 m_value.array = create<array_t>(init.begin(), init.end());
14258 }
14259
14260 assert_invariant();
14261 }
14262
14263 /*!
14264 @brief explicitly create an array from an initializer list
14265
14266 Creates a JSON array value from a given initializer list. That is, given a
14267 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
14268 initializer list is empty, the empty array `[]` is created.
14269
14270 @note This function is only needed to express two edge cases that cannot
14271 be realized with the initializer list constructor (@ref
14272 basic_json(initializer_list_t, bool, value_t)). These cases
14273 are:
14274 1. creating an array whose elements are all pairs whose first element is a
14275 string -- in this case, the initializer list constructor would create an
14276 object, taking the first elements as keys
14277 2. creating an empty array -- passing the empty initializer list to the
14278 initializer list constructor yields an empty object
14279
14280 @param[in] init initializer list with JSON values to create an array from
14281 (optional)
14282
14283 @return JSON array value
14284
14285 @complexity Linear in the size of @a init.
14286
14287 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14288 changes to any JSON value.
14289
14290 @liveexample{The following code shows an example for the `array`
14291 function.,array}
14292
14293 @sa @ref basic_json(initializer_list_t, bool, value_t) --
14294 create a JSON value from an initializer list
14295 @sa @ref object(initializer_list_t) -- create a JSON object
14296 value from an initializer list
14297
14298 @since version 1.0.0
14299 */
14300 JSON_NODISCARD
array(initializer_list_t init={})14301 static basic_json array(initializer_list_t init = {})
14302 {
14303 return basic_json(init, false, value_t::array);
14304 }
14305
14306 /*!
14307 @brief explicitly create an object from an initializer list
14308
14309 Creates a JSON object value from a given initializer list. The initializer
14310 lists elements must be pairs, and their first elements must be strings. If
14311 the initializer list is empty, the empty object `{}` is created.
14312
14313 @note This function is only added for symmetry reasons. In contrast to the
14314 related function @ref array(initializer_list_t), there are
14315 no cases which can only be expressed by this function. That is, any
14316 initializer list @a init can also be passed to the initializer list
14317 constructor @ref basic_json(initializer_list_t, bool, value_t).
14318
14319 @param[in] init initializer list to create an object from (optional)
14320
14321 @return JSON object value
14322
14323 @throw type_error.301 if @a init is not a list of pairs whose first
14324 elements are strings. In this case, no object can be created. When such a
14325 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
14326 an array would have been created from the passed initializer list @a init.
14327 See example below.
14328
14329 @complexity Linear in the size of @a init.
14330
14331 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14332 changes to any JSON value.
14333
14334 @liveexample{The following code shows an example for the `object`
14335 function.,object}
14336
14337 @sa @ref basic_json(initializer_list_t, bool, value_t) --
14338 create a JSON value from an initializer list
14339 @sa @ref array(initializer_list_t) -- create a JSON array
14340 value from an initializer list
14341
14342 @since version 1.0.0
14343 */
14344 JSON_NODISCARD
object(initializer_list_t init={})14345 static basic_json object(initializer_list_t init = {})
14346 {
14347 return basic_json(init, false, value_t::object);
14348 }
14349
14350 /*!
14351 @brief construct an array with count copies of given value
14352
14353 Constructs a JSON array value by creating @a cnt copies of a passed value.
14354 In case @a cnt is `0`, an empty array is created.
14355
14356 @param[in] cnt the number of JSON copies of @a val to create
14357 @param[in] val the JSON value to copy
14358
14359 @post `std::distance(begin(),end()) == cnt` holds.
14360
14361 @complexity Linear in @a cnt.
14362
14363 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14364 changes to any JSON value.
14365
14366 @liveexample{The following code shows examples for the @ref
14367 basic_json(size_type\, const basic_json&)
14368 constructor.,basic_json__size_type_basic_json}
14369
14370 @since version 1.0.0
14371 */
basic_json(size_type cnt,const basic_json & val)14372 basic_json(size_type cnt, const basic_json& val)
14373 : m_type(value_t::array)
14374 {
14375 m_value.array = create<array_t>(cnt, val);
14376 assert_invariant();
14377 }
14378
14379 /*!
14380 @brief construct a JSON container given an iterator range
14381
14382 Constructs the JSON value with the contents of the range `[first, last)`.
14383 The semantics depends on the different types a JSON value can have:
14384 - In case of a null type, invalid_iterator.206 is thrown.
14385 - In case of other primitive types (number, boolean, or string), @a first
14386 must be `begin()` and @a last must be `end()`. In this case, the value is
14387 copied. Otherwise, invalid_iterator.204 is thrown.
14388 - In case of structured types (array, object), the constructor behaves as
14389 similar versions for `std::vector` or `std::map`; that is, a JSON array
14390 or object is constructed from the values in the range.
14391
14392 @tparam InputIT an input iterator type (@ref iterator or @ref
14393 const_iterator)
14394
14395 @param[in] first begin of the range to copy from (included)
14396 @param[in] last end of the range to copy from (excluded)
14397
14398 @pre Iterators @a first and @a last must be initialized. **This
14399 precondition is enforced with an assertion (see warning).** If
14400 assertions are switched off, a violation of this precondition yields
14401 undefined behavior.
14402
14403 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
14404 checked efficiently. Only certain edge cases are detected; see the
14405 description of the exceptions below. A violation of this precondition
14406 yields undefined behavior.
14407
14408 @warning A precondition is enforced with a runtime assertion that will
14409 result in calling `std::abort` if this precondition is not met.
14410 Assertions can be disabled by defining `NDEBUG` at compile time.
14411 See https://en.cppreference.com/w/cpp/error/assert for more
14412 information.
14413
14414 @throw invalid_iterator.201 if iterators @a first and @a last are not
14415 compatible (i.e., do not belong to the same JSON value). In this case,
14416 the range `[first, last)` is undefined.
14417 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
14418 primitive type (number, boolean, or string), but @a first does not point
14419 to the first element any more. In this case, the range `[first, last)` is
14420 undefined. See example code below.
14421 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
14422 null value. In this case, the range `[first, last)` is undefined.
14423
14424 @complexity Linear in distance between @a first and @a last.
14425
14426 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14427 changes to any JSON value.
14428
14429 @liveexample{The example below shows several ways to create JSON values by
14430 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
14431
14432 @since version 1.0.0
14433 */
14434 template<class InputIT, typename std::enable_if<
14435 std::is_same<InputIT, typename basic_json_t::iterator>::value or
14436 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)14437 basic_json(InputIT first, InputIT last)
14438 {
14439 assert(first.m_object != nullptr);
14440 assert(last.m_object != nullptr);
14441
14442 // make sure iterator fits the current value
14443 if (JSON_UNLIKELY(first.m_object != last.m_object))
14444 {
14445 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
14446 }
14447
14448 // copy type from first iterator
14449 m_type = first.m_object->m_type;
14450
14451 // check if iterator range is complete for primitive values
14452 switch (m_type)
14453 {
14454 case value_t::boolean:
14455 case value_t::number_float:
14456 case value_t::number_integer:
14457 case value_t::number_unsigned:
14458 case value_t::string:
14459 {
14460 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
14461 or not last.m_it.primitive_iterator.is_end()))
14462 {
14463 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
14464 }
14465 break;
14466 }
14467
14468 default:
14469 break;
14470 }
14471
14472 switch (m_type)
14473 {
14474 case value_t::number_integer:
14475 {
14476 m_value.number_integer = first.m_object->m_value.number_integer;
14477 break;
14478 }
14479
14480 case value_t::number_unsigned:
14481 {
14482 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
14483 break;
14484 }
14485
14486 case value_t::number_float:
14487 {
14488 m_value.number_float = first.m_object->m_value.number_float;
14489 break;
14490 }
14491
14492 case value_t::boolean:
14493 {
14494 m_value.boolean = first.m_object->m_value.boolean;
14495 break;
14496 }
14497
14498 case value_t::string:
14499 {
14500 m_value = *first.m_object->m_value.string;
14501 break;
14502 }
14503
14504 case value_t::object:
14505 {
14506 m_value.object = create<object_t>(first.m_it.object_iterator,
14507 last.m_it.object_iterator);
14508 break;
14509 }
14510
14511 case value_t::array:
14512 {
14513 m_value.array = create<array_t>(first.m_it.array_iterator,
14514 last.m_it.array_iterator);
14515 break;
14516 }
14517
14518 default:
14519 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
14520 std::string(first.m_object->type_name())));
14521 }
14522
14523 assert_invariant();
14524 }
14525
14526
14527 ///////////////////////////////////////
14528 // other constructors and destructor //
14529 ///////////////////////////////////////
14530
14531 /// @private
basic_json(const detail::json_ref<basic_json> & ref)14532 basic_json(const detail::json_ref<basic_json>& ref)
14533 : basic_json(ref.moved_or_copied())
14534 {}
14535
14536 /*!
14537 @brief copy constructor
14538
14539 Creates a copy of a given JSON value.
14540
14541 @param[in] other the JSON value to copy
14542
14543 @post `*this == other`
14544
14545 @complexity Linear in the size of @a other.
14546
14547 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14548 changes to any JSON value.
14549
14550 @requirement This function helps `basic_json` satisfying the
14551 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14552 requirements:
14553 - The complexity is linear.
14554 - As postcondition, it holds: `other == basic_json(other)`.
14555
14556 @liveexample{The following code shows an example for the copy
14557 constructor.,basic_json__basic_json}
14558
14559 @since version 1.0.0
14560 */
basic_json(const basic_json & other)14561 basic_json(const basic_json& other)
14562 : m_type(other.m_type)
14563 {
14564 // check of passed value is valid
14565 other.assert_invariant();
14566
14567 switch (m_type)
14568 {
14569 case value_t::object:
14570 {
14571 m_value = *other.m_value.object;
14572 break;
14573 }
14574
14575 case value_t::array:
14576 {
14577 m_value = *other.m_value.array;
14578 break;
14579 }
14580
14581 case value_t::string:
14582 {
14583 m_value = *other.m_value.string;
14584 break;
14585 }
14586
14587 case value_t::boolean:
14588 {
14589 m_value = other.m_value.boolean;
14590 break;
14591 }
14592
14593 case value_t::number_integer:
14594 {
14595 m_value = other.m_value.number_integer;
14596 break;
14597 }
14598
14599 case value_t::number_unsigned:
14600 {
14601 m_value = other.m_value.number_unsigned;
14602 break;
14603 }
14604
14605 case value_t::number_float:
14606 {
14607 m_value = other.m_value.number_float;
14608 break;
14609 }
14610
14611 default:
14612 break;
14613 }
14614
14615 assert_invariant();
14616 }
14617
14618 /*!
14619 @brief move constructor
14620
14621 Move constructor. Constructs a JSON value with the contents of the given
14622 value @a other using move semantics. It "steals" the resources from @a
14623 other and leaves it as JSON null value.
14624
14625 @param[in,out] other value to move to this object
14626
14627 @post `*this` has the same value as @a other before the call.
14628 @post @a other is a JSON null value.
14629
14630 @complexity Constant.
14631
14632 @exceptionsafety No-throw guarantee: this constructor never throws
14633 exceptions.
14634
14635 @requirement This function helps `basic_json` satisfying the
14636 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
14637 requirements.
14638
14639 @liveexample{The code below shows the move constructor explicitly called
14640 via std::move.,basic_json__moveconstructor}
14641
14642 @since version 1.0.0
14643 */
basic_json(basic_json && other)14644 basic_json(basic_json&& other) noexcept
14645 : m_type(std::move(other.m_type)),
14646 m_value(std::move(other.m_value))
14647 {
14648 // check that passed value is valid
14649 other.assert_invariant();
14650
14651 // invalidate payload
14652 other.m_type = value_t::null;
14653 other.m_value = {};
14654
14655 assert_invariant();
14656 }
14657
14658 /*!
14659 @brief copy assignment
14660
14661 Copy assignment operator. Copies a JSON value via the "copy and swap"
14662 strategy: It is expressed in terms of the copy constructor, destructor,
14663 and the `swap()` member function.
14664
14665 @param[in] other value to copy from
14666
14667 @complexity Linear.
14668
14669 @requirement This function helps `basic_json` satisfying the
14670 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14671 requirements:
14672 - The complexity is linear.
14673
14674 @liveexample{The code below shows and example for the copy assignment. It
14675 creates a copy of value `a` which is then swapped with `b`. Finally\, the
14676 copy of `a` (which is the null value after the swap) is
14677 destroyed.,basic_json__copyassignment}
14678
14679 @since version 1.0.0
14680 */
operator =(basic_json other)14681 basic_json& operator=(basic_json other) noexcept (
14682 std::is_nothrow_move_constructible<value_t>::value and
14683 std::is_nothrow_move_assignable<value_t>::value and
14684 std::is_nothrow_move_constructible<json_value>::value and
14685 std::is_nothrow_move_assignable<json_value>::value
14686 )
14687 {
14688 // check that passed value is valid
14689 other.assert_invariant();
14690
14691 using std::swap;
14692 swap(m_type, other.m_type);
14693 swap(m_value, other.m_value);
14694
14695 assert_invariant();
14696 return *this;
14697 }
14698
14699 /*!
14700 @brief destructor
14701
14702 Destroys the JSON value and frees all allocated memory.
14703
14704 @complexity Linear.
14705
14706 @requirement This function helps `basic_json` satisfying the
14707 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
14708 requirements:
14709 - The complexity is linear.
14710 - All stored elements are destroyed and all memory is freed.
14711
14712 @since version 1.0.0
14713 */
~basic_json()14714 ~basic_json() noexcept
14715 {
14716 assert_invariant();
14717 m_value.destroy(m_type);
14718 }
14719
14720 /// @}
14721
14722 public:
14723 ///////////////////////
14724 // object inspection //
14725 ///////////////////////
14726
14727 /// @name object inspection
14728 /// Functions to inspect the type of a JSON value.
14729 /// @{
14730
14731 /*!
14732 @brief serialization
14733
14734 Serialization function for JSON values. The function tries to mimic
14735 Python's `json.dumps()` function, and currently supports its @a indent
14736 and @a ensure_ascii parameters.
14737
14738 @param[in] indent If indent is nonnegative, then array elements and object
14739 members will be pretty-printed with that indent level. An indent level of
14740 `0` will only insert newlines. `-1` (the default) selects the most compact
14741 representation.
14742 @param[in] indent_char The character to use for indentation if @a indent is
14743 greater than `0`. The default is ` ` (space).
14744 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
14745 in the output are escaped with `\uXXXX` sequences, and the result consists
14746 of ASCII characters only.
14747 @param[in] error_handler how to react on decoding errors; there are three
14748 possible values: `strict` (throws and exception in case a decoding error
14749 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
14750 and `ignore` (ignore invalid UTF-8 sequences during serialization).
14751
14752 @return string containing the serialization of the JSON value
14753
14754 @throw type_error.316 if a string stored inside the JSON value is not
14755 UTF-8 encoded
14756
14757 @complexity Linear.
14758
14759 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
14760 changes in the JSON value.
14761
14762 @liveexample{The following example shows the effect of different @a indent\,
14763 @a indent_char\, and @a ensure_ascii parameters to the result of the
14764 serialization.,dump}
14765
14766 @see https://docs.python.org/2/library/json.html#json.dump
14767
14768 @since version 1.0.0; indentation character @a indent_char, option
14769 @a ensure_ascii and exceptions added in version 3.0.0; error
14770 handlers added in version 3.4.0.
14771 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const14772 string_t dump(const int indent = -1,
14773 const char indent_char = ' ',
14774 const bool ensure_ascii = false,
14775 const error_handler_t error_handler = error_handler_t::strict) const
14776 {
14777 string_t result;
14778 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
14779
14780 if (indent >= 0)
14781 {
14782 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
14783 }
14784 else
14785 {
14786 s.dump(*this, false, ensure_ascii, 0);
14787 }
14788
14789 return result;
14790 }
14791
14792 /*!
14793 @brief return the type of the JSON value (explicit)
14794
14795 Return the type of the JSON value as a value from the @ref value_t
14796 enumeration.
14797
14798 @return the type of the JSON value
14799 Value type | return value
14800 ------------------------- | -------------------------
14801 null | value_t::null
14802 boolean | value_t::boolean
14803 string | value_t::string
14804 number (integer) | value_t::number_integer
14805 number (unsigned integer) | value_t::number_unsigned
14806 number (floating-point) | value_t::number_float
14807 object | value_t::object
14808 array | value_t::array
14809 discarded | value_t::discarded
14810
14811 @complexity Constant.
14812
14813 @exceptionsafety No-throw guarantee: this member function never throws
14814 exceptions.
14815
14816 @liveexample{The following code exemplifies `type()` for all JSON
14817 types.,type}
14818
14819 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
14820 @sa @ref type_name() -- return the type as string
14821
14822 @since version 1.0.0
14823 */
type() const14824 constexpr value_t type() const noexcept
14825 {
14826 return m_type;
14827 }
14828
14829 /*!
14830 @brief return whether type is primitive
14831
14832 This function returns true if and only if the JSON type is primitive
14833 (string, number, boolean, or null).
14834
14835 @return `true` if type is primitive (string, number, boolean, or null),
14836 `false` otherwise.
14837
14838 @complexity Constant.
14839
14840 @exceptionsafety No-throw guarantee: this member function never throws
14841 exceptions.
14842
14843 @liveexample{The following code exemplifies `is_primitive()` for all JSON
14844 types.,is_primitive}
14845
14846 @sa @ref is_structured() -- returns whether JSON value is structured
14847 @sa @ref is_null() -- returns whether JSON value is `null`
14848 @sa @ref is_string() -- returns whether JSON value is a string
14849 @sa @ref is_boolean() -- returns whether JSON value is a boolean
14850 @sa @ref is_number() -- returns whether JSON value is a number
14851
14852 @since version 1.0.0
14853 */
is_primitive() const14854 constexpr bool is_primitive() const noexcept
14855 {
14856 return is_null() or is_string() or is_boolean() or is_number();
14857 }
14858
14859 /*!
14860 @brief return whether type is structured
14861
14862 This function returns true if and only if the JSON type is structured
14863 (array or object).
14864
14865 @return `true` if type is structured (array or object), `false` otherwise.
14866
14867 @complexity Constant.
14868
14869 @exceptionsafety No-throw guarantee: this member function never throws
14870 exceptions.
14871
14872 @liveexample{The following code exemplifies `is_structured()` for all JSON
14873 types.,is_structured}
14874
14875 @sa @ref is_primitive() -- returns whether value is primitive
14876 @sa @ref is_array() -- returns whether value is an array
14877 @sa @ref is_object() -- returns whether value is an object
14878
14879 @since version 1.0.0
14880 */
is_structured() const14881 constexpr bool is_structured() const noexcept
14882 {
14883 return is_array() or is_object();
14884 }
14885
14886 /*!
14887 @brief return whether value is null
14888
14889 This function returns true if and only if the JSON value is null.
14890
14891 @return `true` if type is null, `false` otherwise.
14892
14893 @complexity Constant.
14894
14895 @exceptionsafety No-throw guarantee: this member function never throws
14896 exceptions.
14897
14898 @liveexample{The following code exemplifies `is_null()` for all JSON
14899 types.,is_null}
14900
14901 @since version 1.0.0
14902 */
is_null() const14903 constexpr bool is_null() const noexcept
14904 {
14905 return m_type == value_t::null;
14906 }
14907
14908 /*!
14909 @brief return whether value is a boolean
14910
14911 This function returns true if and only if the JSON value is a boolean.
14912
14913 @return `true` if type is boolean, `false` otherwise.
14914
14915 @complexity Constant.
14916
14917 @exceptionsafety No-throw guarantee: this member function never throws
14918 exceptions.
14919
14920 @liveexample{The following code exemplifies `is_boolean()` for all JSON
14921 types.,is_boolean}
14922
14923 @since version 1.0.0
14924 */
is_boolean() const14925 constexpr bool is_boolean() const noexcept
14926 {
14927 return m_type == value_t::boolean;
14928 }
14929
14930 /*!
14931 @brief return whether value is a number
14932
14933 This function returns true if and only if the JSON value is a number. This
14934 includes both integer (signed and unsigned) and floating-point values.
14935
14936 @return `true` if type is number (regardless whether integer, unsigned
14937 integer or floating-type), `false` otherwise.
14938
14939 @complexity Constant.
14940
14941 @exceptionsafety No-throw guarantee: this member function never throws
14942 exceptions.
14943
14944 @liveexample{The following code exemplifies `is_number()` for all JSON
14945 types.,is_number}
14946
14947 @sa @ref is_number_integer() -- check if value is an integer or unsigned
14948 integer number
14949 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14950 number
14951 @sa @ref is_number_float() -- check if value is a floating-point number
14952
14953 @since version 1.0.0
14954 */
is_number() const14955 constexpr bool is_number() const noexcept
14956 {
14957 return is_number_integer() or is_number_float();
14958 }
14959
14960 /*!
14961 @brief return whether value is an integer number
14962
14963 This function returns true if and only if the JSON value is a signed or
14964 unsigned integer number. This excludes floating-point values.
14965
14966 @return `true` if type is an integer or unsigned integer number, `false`
14967 otherwise.
14968
14969 @complexity Constant.
14970
14971 @exceptionsafety No-throw guarantee: this member function never throws
14972 exceptions.
14973
14974 @liveexample{The following code exemplifies `is_number_integer()` for all
14975 JSON types.,is_number_integer}
14976
14977 @sa @ref is_number() -- check if value is a number
14978 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
14979 number
14980 @sa @ref is_number_float() -- check if value is a floating-point number
14981
14982 @since version 1.0.0
14983 */
is_number_integer() const14984 constexpr bool is_number_integer() const noexcept
14985 {
14986 return m_type == value_t::number_integer or m_type == value_t::number_unsigned;
14987 }
14988
14989 /*!
14990 @brief return whether value is an unsigned integer number
14991
14992 This function returns true if and only if the JSON value is an unsigned
14993 integer number. This excludes floating-point and signed integer values.
14994
14995 @return `true` if type is an unsigned integer number, `false` otherwise.
14996
14997 @complexity Constant.
14998
14999 @exceptionsafety No-throw guarantee: this member function never throws
15000 exceptions.
15001
15002 @liveexample{The following code exemplifies `is_number_unsigned()` for all
15003 JSON types.,is_number_unsigned}
15004
15005 @sa @ref is_number() -- check if value is a number
15006 @sa @ref is_number_integer() -- check if value is an integer or unsigned
15007 integer number
15008 @sa @ref is_number_float() -- check if value is a floating-point number
15009
15010 @since version 2.0.0
15011 */
is_number_unsigned() const15012 constexpr bool is_number_unsigned() const noexcept
15013 {
15014 return m_type == value_t::number_unsigned;
15015 }
15016
15017 /*!
15018 @brief return whether value is a floating-point number
15019
15020 This function returns true if and only if the JSON value is a
15021 floating-point number. This excludes signed and unsigned integer values.
15022
15023 @return `true` if type is a floating-point number, `false` otherwise.
15024
15025 @complexity Constant.
15026
15027 @exceptionsafety No-throw guarantee: this member function never throws
15028 exceptions.
15029
15030 @liveexample{The following code exemplifies `is_number_float()` for all
15031 JSON types.,is_number_float}
15032
15033 @sa @ref is_number() -- check if value is number
15034 @sa @ref is_number_integer() -- check if value is an integer number
15035 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
15036 number
15037
15038 @since version 1.0.0
15039 */
is_number_float() const15040 constexpr bool is_number_float() const noexcept
15041 {
15042 return m_type == value_t::number_float;
15043 }
15044
15045 /*!
15046 @brief return whether value is an object
15047
15048 This function returns true if and only if the JSON value is an object.
15049
15050 @return `true` if type is object, `false` otherwise.
15051
15052 @complexity Constant.
15053
15054 @exceptionsafety No-throw guarantee: this member function never throws
15055 exceptions.
15056
15057 @liveexample{The following code exemplifies `is_object()` for all JSON
15058 types.,is_object}
15059
15060 @since version 1.0.0
15061 */
is_object() const15062 constexpr bool is_object() const noexcept
15063 {
15064 return m_type == value_t::object;
15065 }
15066
15067 /*!
15068 @brief return whether value is an array
15069
15070 This function returns true if and only if the JSON value is an array.
15071
15072 @return `true` if type is array, `false` otherwise.
15073
15074 @complexity Constant.
15075
15076 @exceptionsafety No-throw guarantee: this member function never throws
15077 exceptions.
15078
15079 @liveexample{The following code exemplifies `is_array()` for all JSON
15080 types.,is_array}
15081
15082 @since version 1.0.0
15083 */
is_array() const15084 constexpr bool is_array() const noexcept
15085 {
15086 return m_type == value_t::array;
15087 }
15088
15089 /*!
15090 @brief return whether value is a string
15091
15092 This function returns true if and only if the JSON value is a string.
15093
15094 @return `true` if type is string, `false` otherwise.
15095
15096 @complexity Constant.
15097
15098 @exceptionsafety No-throw guarantee: this member function never throws
15099 exceptions.
15100
15101 @liveexample{The following code exemplifies `is_string()` for all JSON
15102 types.,is_string}
15103
15104 @since version 1.0.0
15105 */
is_string() const15106 constexpr bool is_string() const noexcept
15107 {
15108 return m_type == value_t::string;
15109 }
15110
15111 /*!
15112 @brief return whether value is discarded
15113
15114 This function returns true if and only if the JSON value was discarded
15115 during parsing with a callback function (see @ref parser_callback_t).
15116
15117 @note This function will always be `false` for JSON values after parsing.
15118 That is, discarded values can only occur during parsing, but will be
15119 removed when inside a structured value or replaced by null in other cases.
15120
15121 @return `true` if type is discarded, `false` otherwise.
15122
15123 @complexity Constant.
15124
15125 @exceptionsafety No-throw guarantee: this member function never throws
15126 exceptions.
15127
15128 @liveexample{The following code exemplifies `is_discarded()` for all JSON
15129 types.,is_discarded}
15130
15131 @since version 1.0.0
15132 */
is_discarded() const15133 constexpr bool is_discarded() const noexcept
15134 {
15135 return m_type == value_t::discarded;
15136 }
15137
15138 /*!
15139 @brief return the type of the JSON value (implicit)
15140
15141 Implicitly return the type of the JSON value as a value from the @ref
15142 value_t enumeration.
15143
15144 @return the type of the JSON value
15145
15146 @complexity Constant.
15147
15148 @exceptionsafety No-throw guarantee: this member function never throws
15149 exceptions.
15150
15151 @liveexample{The following code exemplifies the @ref value_t operator for
15152 all JSON types.,operator__value_t}
15153
15154 @sa @ref type() -- return the type of the JSON value (explicit)
15155 @sa @ref type_name() -- return the type as string
15156
15157 @since version 1.0.0
15158 */
operator value_t() const15159 constexpr operator value_t() const noexcept
15160 {
15161 return m_type;
15162 }
15163
15164 /// @}
15165
15166 private:
15167 //////////////////
15168 // value access //
15169 //////////////////
15170
15171 /// get a boolean (explicit)
get_impl(boolean_t *) const15172 boolean_t get_impl(boolean_t* /*unused*/) const
15173 {
15174 if (JSON_LIKELY(is_boolean()))
15175 {
15176 return m_value.boolean;
15177 }
15178
15179 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
15180 }
15181
15182 /// get a pointer to the value (object)
get_impl_ptr(object_t *)15183 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
15184 {
15185 return is_object() ? m_value.object : nullptr;
15186 }
15187
15188 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const15189 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
15190 {
15191 return is_object() ? m_value.object : nullptr;
15192 }
15193
15194 /// get a pointer to the value (array)
get_impl_ptr(array_t *)15195 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
15196 {
15197 return is_array() ? m_value.array : nullptr;
15198 }
15199
15200 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const15201 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
15202 {
15203 return is_array() ? m_value.array : nullptr;
15204 }
15205
15206 /// get a pointer to the value (string)
get_impl_ptr(string_t *)15207 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
15208 {
15209 return is_string() ? m_value.string : nullptr;
15210 }
15211
15212 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const15213 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
15214 {
15215 return is_string() ? m_value.string : nullptr;
15216 }
15217
15218 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)15219 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
15220 {
15221 return is_boolean() ? &m_value.boolean : nullptr;
15222 }
15223
15224 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const15225 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
15226 {
15227 return is_boolean() ? &m_value.boolean : nullptr;
15228 }
15229
15230 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)15231 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
15232 {
15233 return is_number_integer() ? &m_value.number_integer : nullptr;
15234 }
15235
15236 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const15237 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
15238 {
15239 return is_number_integer() ? &m_value.number_integer : nullptr;
15240 }
15241
15242 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)15243 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
15244 {
15245 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15246 }
15247
15248 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const15249 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
15250 {
15251 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
15252 }
15253
15254 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)15255 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
15256 {
15257 return is_number_float() ? &m_value.number_float : nullptr;
15258 }
15259
15260 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const15261 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
15262 {
15263 return is_number_float() ? &m_value.number_float : nullptr;
15264 }
15265
15266 /*!
15267 @brief helper function to implement get_ref()
15268
15269 This function helps to implement get_ref() without code duplication for
15270 const and non-const overloads
15271
15272 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
15273
15274 @throw type_error.303 if ReferenceType does not match underlying value
15275 type of the current JSON
15276 */
15277 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)15278 static ReferenceType get_ref_impl(ThisType& obj)
15279 {
15280 // delegate the call to get_ptr<>()
15281 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
15282
15283 if (JSON_LIKELY(ptr != nullptr))
15284 {
15285 return *ptr;
15286 }
15287
15288 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
15289 }
15290
15291 public:
15292 /// @name value access
15293 /// Direct access to the stored value of a JSON value.
15294 /// @{
15295
15296 /*!
15297 @brief get special-case overload
15298
15299 This overloads avoids a lot of template boilerplate, it can be seen as the
15300 identity method
15301
15302 @tparam BasicJsonType == @ref basic_json
15303
15304 @return a copy of *this
15305
15306 @complexity Constant.
15307
15308 @since version 2.1.0
15309 */
15310 template<typename BasicJsonType, detail::enable_if_t<
15311 std::is_same<typename std::remove_const<BasicJsonType>::type, basic_json_t>::value,
15312 int> = 0>
get() const15313 basic_json get() const
15314 {
15315 return *this;
15316 }
15317
15318 /*!
15319 @brief get special-case overload
15320
15321 This overloads converts the current @ref basic_json in a different
15322 @ref basic_json type
15323
15324 @tparam BasicJsonType == @ref basic_json
15325
15326 @return a copy of *this, converted into @tparam BasicJsonType
15327
15328 @complexity Depending on the implementation of the called `from_json()`
15329 method.
15330
15331 @since version 3.2.0
15332 */
15333 template<typename BasicJsonType, detail::enable_if_t<
15334 not std::is_same<BasicJsonType, basic_json>::value and
15335 detail::is_basic_json<BasicJsonType>::value, int> = 0>
15336 BasicJsonType get() const
15337 {
15338 return *this;
15339 }
15340
15341 /*!
15342 @brief get a value (explicit)
15343
15344 Explicit type conversion between the JSON value and a compatible value
15345 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
15346 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
15347 The value is converted by calling the @ref json_serializer<ValueType>
15348 `from_json()` method.
15349
15350 The function is equivalent to executing
15351 @code {.cpp}
15352 ValueType ret;
15353 JSONSerializer<ValueType>::from_json(*this, ret);
15354 return ret;
15355 @endcode
15356
15357 This overloads is chosen if:
15358 - @a ValueType is not @ref basic_json,
15359 - @ref json_serializer<ValueType> has a `from_json()` method of the form
15360 `void from_json(const basic_json&, ValueType&)`, and
15361 - @ref json_serializer<ValueType> does not have a `from_json()` method of
15362 the form `ValueType from_json(const basic_json&)`
15363
15364 @tparam ValueTypeCV the provided value type
15365 @tparam ValueType the returned value type
15366
15367 @return copy of the JSON value, converted to @a ValueType
15368
15369 @throw what @ref json_serializer<ValueType> `from_json()` method throws
15370
15371 @liveexample{The example below shows several conversions from JSON values
15372 to other types. There a few things to note: (1) Floating-point numbers can
15373 be converted to integers\, (2) A JSON array can be converted to a standard
15374 `std::vector<short>`\, (3) A JSON object can be converted to C++
15375 associative containers such as `std::unordered_map<std::string\,
15376 json>`.,get__ValueType_const}
15377
15378 @since version 2.1.0
15379 */
15380 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
15381 detail::enable_if_t <
15382 not detail::is_basic_json<ValueType>::value and
15383 detail::has_from_json<basic_json_t, ValueType>::value and
15384 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15385 int> = 0>
15386 ValueType get() const noexcept(noexcept(
15387 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
15388 {
15389 // we cannot static_assert on ValueTypeCV being non-const, because
15390 // there is support for get<const basic_json_t>(), which is why we
15391 // still need the uncvref
15392 static_assert(not std::is_reference<ValueTypeCV>::value,
15393 "get() cannot be used with reference types, you might want to use get_ref()");
15394 static_assert(std::is_default_constructible<ValueType>::value,
15395 "types must be DefaultConstructible when used with get()");
15396
15397 ValueType ret;
15398 JSONSerializer<ValueType>::from_json(*this, ret);
15399 return ret;
15400 }
15401
15402 /*!
15403 @brief get a value (explicit); special case
15404
15405 Explicit type conversion between the JSON value and a compatible value
15406 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
15407 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
15408 The value is converted by calling the @ref json_serializer<ValueType>
15409 `from_json()` method.
15410
15411 The function is equivalent to executing
15412 @code {.cpp}
15413 return JSONSerializer<ValueTypeCV>::from_json(*this);
15414 @endcode
15415
15416 This overloads is chosen if:
15417 - @a ValueType is not @ref basic_json and
15418 - @ref json_serializer<ValueType> has a `from_json()` method of the form
15419 `ValueType from_json(const basic_json&)`
15420
15421 @note If @ref json_serializer<ValueType> has both overloads of
15422 `from_json()`, this one is chosen.
15423
15424 @tparam ValueTypeCV the provided value type
15425 @tparam ValueType the returned value type
15426
15427 @return copy of the JSON value, converted to @a ValueType
15428
15429 @throw what @ref json_serializer<ValueType> `from_json()` method throws
15430
15431 @since version 2.1.0
15432 */
15433 template<typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>,
15434 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
15435 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
15436 int> = 0>
15437 ValueType get() const noexcept(noexcept(
15438 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
15439 {
15440 static_assert(not std::is_reference<ValueTypeCV>::value,
15441 "get() cannot be used with reference types, you might want to use get_ref()");
15442 return JSONSerializer<ValueTypeCV>::from_json(*this);
15443 }
15444
15445 /*!
15446 @brief get a value (explicit)
15447
15448 Explicit type conversion between the JSON value and a compatible value.
15449 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
15450 `from_json()` method.
15451
15452 The function is equivalent to executing
15453 @code {.cpp}
15454 ValueType v;
15455 JSONSerializer<ValueType>::from_json(*this, v);
15456 @endcode
15457
15458 This overloads is chosen if:
15459 - @a ValueType is not @ref basic_json,
15460 - @ref json_serializer<ValueType> has a `from_json()` method of the form
15461 `void from_json(const basic_json&, ValueType&)`, and
15462
15463 @tparam ValueType the input parameter type.
15464
15465 @return the input parameter, allowing chaining calls.
15466
15467 @throw what @ref json_serializer<ValueType> `from_json()` method throws
15468
15469 @liveexample{The example below shows several conversions from JSON values
15470 to other types. There a few things to note: (1) Floating-point numbers can
15471 be converted to integers\, (2) A JSON array can be converted to a standard
15472 `std::vector<short>`\, (3) A JSON object can be converted to C++
15473 associative containers such as `std::unordered_map<std::string\,
15474 json>`.,get_to}
15475
15476 @since version 3.3.0
15477 */
15478 template<typename ValueType,
15479 detail::enable_if_t <
15480 not detail::is_basic_json<ValueType>::value and
15481 detail::has_from_json<basic_json_t, ValueType>::value,
15482 int> = 0>
15483 ValueType & get_to(ValueType& v) const noexcept(noexcept(
15484 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
15485 {
15486 JSONSerializer<ValueType>::from_json(*this, v);
15487 return v;
15488 }
15489
15490 template <
15491 typename T, std::size_t N,
15492 typename Array = T (&)[N],
15493 detail::enable_if_t <
15494 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
15495 Array get_to(T (&v)[N]) const
15496 noexcept(noexcept(JSONSerializer<Array>::from_json(
15497 std::declval<const basic_json_t&>(), v)))
15498 {
15499 JSONSerializer<Array>::from_json(*this, v);
15500 return v;
15501 }
15502
15503
15504 /*!
15505 @brief get a pointer value (implicit)
15506
15507 Implicit pointer access to the internally stored JSON value. No copies are
15508 made.
15509
15510 @warning Writing data to the pointee of the result yields an undefined
15511 state.
15512
15513 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
15514 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
15515 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
15516 assertion.
15517
15518 @return pointer to the internally stored JSON value if the requested
15519 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
15520
15521 @complexity Constant.
15522
15523 @liveexample{The example below shows how pointers to internal values of a
15524 JSON value can be requested. Note that no type conversions are made and a
15525 `nullptr` is returned if the value and the requested pointer type does not
15526 match.,get_ptr}
15527
15528 @since version 1.0.0
15529 */
15530 template<typename PointerType, typename std::enable_if<
15531 std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()15532 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15533 {
15534 // delegate the call to get_impl_ptr<>()
15535 return get_impl_ptr(static_cast<PointerType>(nullptr));
15536 }
15537
15538 /*!
15539 @brief get a pointer value (implicit)
15540 @copydoc get_ptr()
15541 */
15542 template<typename PointerType, typename std::enable_if<
15543 std::is_pointer<PointerType>::value and
15544 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const15545 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
15546 {
15547 // delegate the call to get_impl_ptr<>() const
15548 return get_impl_ptr(static_cast<PointerType>(nullptr));
15549 }
15550
15551 /*!
15552 @brief get a pointer value (explicit)
15553
15554 Explicit pointer access to the internally stored JSON value. No copies are
15555 made.
15556
15557 @warning The pointer becomes invalid if the underlying JSON object
15558 changes.
15559
15560 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
15561 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
15562 @ref number_unsigned_t, or @ref number_float_t.
15563
15564 @return pointer to the internally stored JSON value if the requested
15565 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
15566
15567 @complexity Constant.
15568
15569 @liveexample{The example below shows how pointers to internal values of a
15570 JSON value can be requested. Note that no type conversions are made and a
15571 `nullptr` is returned if the value and the requested pointer type does not
15572 match.,get__PointerType}
15573
15574 @sa @ref get_ptr() for explicit pointer-member access
15575
15576 @since version 1.0.0
15577 */
15578 template<typename PointerType, typename std::enable_if<
15579 std::is_pointer<PointerType>::value, int>::type = 0>
get()15580 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
15581 {
15582 // delegate the call to get_ptr
15583 return get_ptr<PointerType>();
15584 }
15585
15586 /*!
15587 @brief get a pointer value (explicit)
15588 @copydoc get()
15589 */
15590 template<typename PointerType, typename std::enable_if<
15591 std::is_pointer<PointerType>::value, int>::type = 0>
get() const15592 constexpr auto get() const noexcept -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
15593 {
15594 // delegate the call to get_ptr
15595 return get_ptr<PointerType>();
15596 }
15597
15598 /*!
15599 @brief get a reference value (implicit)
15600
15601 Implicit reference access to the internally stored JSON value. No copies
15602 are made.
15603
15604 @warning Writing data to the referee of the result yields an undefined
15605 state.
15606
15607 @tparam ReferenceType reference type; must be a reference to @ref array_t,
15608 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
15609 @ref number_float_t. Enforced by static assertion.
15610
15611 @return reference to the internally stored JSON value if the requested
15612 reference type @a ReferenceType fits to the JSON value; throws
15613 type_error.303 otherwise
15614
15615 @throw type_error.303 in case passed type @a ReferenceType is incompatible
15616 with the stored JSON value; see example below
15617
15618 @complexity Constant.
15619
15620 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
15621
15622 @since version 1.1.0
15623 */
15624 template<typename ReferenceType, typename std::enable_if<
15625 std::is_reference<ReferenceType>::value, int>::type = 0>
15626 ReferenceType get_ref()
15627 {
15628 // delegate call to get_ref_impl
15629 return get_ref_impl<ReferenceType>(*this);
15630 }
15631
15632 /*!
15633 @brief get a reference value (implicit)
15634 @copydoc get_ref()
15635 */
15636 template<typename ReferenceType, typename std::enable_if<
15637 std::is_reference<ReferenceType>::value and
15638 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
15639 ReferenceType get_ref() const
15640 {
15641 // delegate call to get_ref_impl
15642 return get_ref_impl<ReferenceType>(*this);
15643 }
15644
15645 /*!
15646 @brief get a value (implicit)
15647
15648 Implicit type conversion between the JSON value and a compatible value.
15649 The call is realized by calling @ref get() const.
15650
15651 @tparam ValueType non-pointer type compatible to the JSON value, for
15652 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
15653 `std::vector` types for JSON arrays. The character type of @ref string_t
15654 as well as an initializer list of this type is excluded to avoid
15655 ambiguities as these types implicitly convert to `std::string`.
15656
15657 @return copy of the JSON value, converted to type @a ValueType
15658
15659 @throw type_error.302 in case passed type @a ValueType is incompatible
15660 to the JSON value type (e.g., the JSON value is of type boolean, but a
15661 string is requested); see example below
15662
15663 @complexity Linear in the size of the JSON value.
15664
15665 @liveexample{The example below shows several conversions from JSON values
15666 to other types. There a few things to note: (1) Floating-point numbers can
15667 be converted to integers\, (2) A JSON array can be converted to a standard
15668 `std::vector<short>`\, (3) A JSON object can be converted to C++
15669 associative containers such as `std::unordered_map<std::string\,
15670 json>`.,operator__ValueType}
15671
15672 @since version 1.0.0
15673 */
15674 template < typename ValueType, typename std::enable_if <
15675 not std::is_pointer<ValueType>::value and
15676 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
15677 not std::is_same<ValueType, typename string_t::value_type>::value and
15678 not detail::is_basic_json<ValueType>::value
15679
15680 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
15681 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
15682 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) and _MSC_VER <= 1914))
15683 and not std::is_same<ValueType, typename std::string_view>::value
15684 #endif
15685 #endif
15686 and detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
15687 , int >::type = 0 >
operator ValueType() const15688 operator ValueType() const
15689 {
15690 // delegate the call to get<>() const
15691 return get<ValueType>();
15692 }
15693
15694 /// @}
15695
15696
15697 ////////////////////
15698 // element access //
15699 ////////////////////
15700
15701 /// @name element access
15702 /// Access to the JSON value.
15703 /// @{
15704
15705 /*!
15706 @brief access specified array element with bounds checking
15707
15708 Returns a reference to the element at specified location @a idx, with
15709 bounds checking.
15710
15711 @param[in] idx index of the element to access
15712
15713 @return reference to the element at index @a idx
15714
15715 @throw type_error.304 if the JSON value is not an array; in this case,
15716 calling `at` with an index makes no sense. See example below.
15717 @throw out_of_range.401 if the index @a idx is out of range of the array;
15718 that is, `idx >= size()`. See example below.
15719
15720 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15721 changes in the JSON value.
15722
15723 @complexity Constant.
15724
15725 @since version 1.0.0
15726
15727 @liveexample{The example below shows how array elements can be read and
15728 written using `at()`. It also demonstrates the different exceptions that
15729 can be thrown.,at__size_type}
15730 */
at(size_type idx)15731 reference at(size_type idx)
15732 {
15733 // at only works for arrays
15734 if (JSON_LIKELY(is_array()))
15735 {
15736 JSON_TRY
15737 {
15738 return m_value.array->at(idx);
15739 }
15740 JSON_CATCH (std::out_of_range&)
15741 {
15742 // create better exception explanation
15743 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
15744 }
15745 }
15746 else
15747 {
15748 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15749 }
15750 }
15751
15752 /*!
15753 @brief access specified array element with bounds checking
15754
15755 Returns a const reference to the element at specified location @a idx,
15756 with bounds checking.
15757
15758 @param[in] idx index of the element to access
15759
15760 @return const reference to the element at index @a idx
15761
15762 @throw type_error.304 if the JSON value is not an array; in this case,
15763 calling `at` with an index makes no sense. See example below.
15764 @throw out_of_range.401 if the index @a idx is out of range of the array;
15765 that is, `idx >= size()`. See example below.
15766
15767 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15768 changes in the JSON value.
15769
15770 @complexity Constant.
15771
15772 @since version 1.0.0
15773
15774 @liveexample{The example below shows how array elements can be read using
15775 `at()`. It also demonstrates the different exceptions that can be thrown.,
15776 at__size_type_const}
15777 */
at(size_type idx) const15778 const_reference at(size_type idx) const
15779 {
15780 // at only works for arrays
15781 if (JSON_LIKELY(is_array()))
15782 {
15783 JSON_TRY
15784 {
15785 return m_value.array->at(idx);
15786 }
15787 JSON_CATCH (std::out_of_range&)
15788 {
15789 // create better exception explanation
15790 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
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 reference to the element at with specified key @a key, with
15803 bounds checking.
15804
15805 @param[in] key key of the element to access
15806
15807 @return 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 and
15826 written using `at()`. It also demonstrates the different exceptions that
15827 can be thrown.,at__object_t_key_type}
15828 */
at(const typename object_t::key_type & key)15829 reference at(const typename object_t::key_type& key)
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 object element with bounds checking
15852
15853 Returns a const reference to the element at with specified key @a key,
15854 with bounds checking.
15855
15856 @param[in] key key of the element to access
15857
15858 @return const reference to the element at key @a key
15859
15860 @throw type_error.304 if the JSON value is not an object; in this case,
15861 calling `at` with a key makes no sense. See example below.
15862 @throw out_of_range.403 if the key @a key is is not stored in the object;
15863 that is, `find(key) == end()`. See example below.
15864
15865 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
15866 changes in the JSON value.
15867
15868 @complexity Logarithmic in the size of the container.
15869
15870 @sa @ref operator[](const typename object_t::key_type&) for unchecked
15871 access by reference
15872 @sa @ref value() for access by value with a default value
15873
15874 @since version 1.0.0
15875
15876 @liveexample{The example below shows how object elements can be read using
15877 `at()`. It also demonstrates the different exceptions that can be thrown.,
15878 at__object_t_key_type_const}
15879 */
at(const typename object_t::key_type & key) const15880 const_reference at(const typename object_t::key_type& key) const
15881 {
15882 // at only works for objects
15883 if (JSON_LIKELY(is_object()))
15884 {
15885 JSON_TRY
15886 {
15887 return m_value.object->at(key);
15888 }
15889 JSON_CATCH (std::out_of_range&)
15890 {
15891 // create better exception explanation
15892 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
15893 }
15894 }
15895 else
15896 {
15897 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
15898 }
15899 }
15900
15901 /*!
15902 @brief access specified array element
15903
15904 Returns a reference to the element at specified location @a idx.
15905
15906 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
15907 then the array is silently filled up with `null` values to make `idx` a
15908 valid reference to the last stored element.
15909
15910 @param[in] idx index of the element to access
15911
15912 @return reference to the element at index @a idx
15913
15914 @throw type_error.305 if the JSON value is not an array or null; in that
15915 cases, using the [] operator with an index makes no sense.
15916
15917 @complexity Constant if @a idx is in the range of the array. Otherwise
15918 linear in `idx - size()`.
15919
15920 @liveexample{The example below shows how array elements can be read and
15921 written using `[]` operator. Note the addition of `null`
15922 values.,operatorarray__size_type}
15923
15924 @since version 1.0.0
15925 */
operator [](size_type idx)15926 reference operator[](size_type idx)
15927 {
15928 // implicitly convert null value to an empty array
15929 if (is_null())
15930 {
15931 m_type = value_t::array;
15932 m_value.array = create<array_t>();
15933 assert_invariant();
15934 }
15935
15936 // operator[] only works for arrays
15937 if (JSON_LIKELY(is_array()))
15938 {
15939 // fill up array with null values if given idx is outside range
15940 if (idx >= m_value.array->size())
15941 {
15942 m_value.array->insert(m_value.array->end(),
15943 idx - m_value.array->size() + 1,
15944 basic_json());
15945 }
15946
15947 return m_value.array->operator[](idx);
15948 }
15949
15950 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15951 }
15952
15953 /*!
15954 @brief access specified array element
15955
15956 Returns a const reference to the element at specified location @a idx.
15957
15958 @param[in] idx index of the element to access
15959
15960 @return const reference to the element at index @a idx
15961
15962 @throw type_error.305 if the JSON value is not an array; in that case,
15963 using the [] operator with an index makes no sense.
15964
15965 @complexity Constant.
15966
15967 @liveexample{The example below shows how array elements can be read using
15968 the `[]` operator.,operatorarray__size_type_const}
15969
15970 @since version 1.0.0
15971 */
operator [](size_type idx) const15972 const_reference operator[](size_type idx) const
15973 {
15974 // const operator[] only works for arrays
15975 if (JSON_LIKELY(is_array()))
15976 {
15977 return m_value.array->operator[](idx);
15978 }
15979
15980 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name())));
15981 }
15982
15983 /*!
15984 @brief access specified object element
15985
15986 Returns a reference to the element at with specified key @a key.
15987
15988 @note If @a key is not found in the object, then it is silently added to
15989 the object and filled with a `null` value to make `key` a valid reference.
15990 In case the value was `null` before, it is converted to an object.
15991
15992 @param[in] key key of the element to access
15993
15994 @return reference to the element at key @a key
15995
15996 @throw type_error.305 if the JSON value is not an object or null; in that
15997 cases, using the [] operator with a key makes no sense.
15998
15999 @complexity Logarithmic in the size of the container.
16000
16001 @liveexample{The example below shows how object elements can be read and
16002 written using the `[]` operator.,operatorarray__key_type}
16003
16004 @sa @ref at(const typename object_t::key_type&) for access by reference
16005 with range checking
16006 @sa @ref value() for access by value with a default value
16007
16008 @since version 1.0.0
16009 */
operator [](const typename object_t::key_type & key)16010 reference operator[](const typename object_t::key_type& key)
16011 {
16012 // implicitly convert null value to an empty object
16013 if (is_null())
16014 {
16015 m_type = value_t::object;
16016 m_value.object = create<object_t>();
16017 assert_invariant();
16018 }
16019
16020 // operator[] only works for objects
16021 if (JSON_LIKELY(is_object()))
16022 {
16023 return m_value.object->operator[](key);
16024 }
16025
16026 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16027 }
16028
16029 /*!
16030 @brief read-only access specified object element
16031
16032 Returns a const reference to the element at with specified key @a key. No
16033 bounds checking is performed.
16034
16035 @warning If the element with key @a key does not exist, the behavior is
16036 undefined.
16037
16038 @param[in] key key of the element to access
16039
16040 @return const reference to the element at key @a key
16041
16042 @pre The element with key @a key must exist. **This precondition is
16043 enforced with an assertion.**
16044
16045 @throw type_error.305 if the JSON value is not an object; in that case,
16046 using the [] operator with a key makes no sense.
16047
16048 @complexity Logarithmic in the size of the container.
16049
16050 @liveexample{The example below shows how object elements can be read using
16051 the `[]` operator.,operatorarray__key_type_const}
16052
16053 @sa @ref at(const typename object_t::key_type&) for access by reference
16054 with range checking
16055 @sa @ref value() for access by value with a default value
16056
16057 @since version 1.0.0
16058 */
operator [](const typename object_t::key_type & key) const16059 const_reference operator[](const typename object_t::key_type& key) const
16060 {
16061 // const operator[] only works for objects
16062 if (JSON_LIKELY(is_object()))
16063 {
16064 assert(m_value.object->find(key) != m_value.object->end());
16065 return m_value.object->find(key)->second;
16066 }
16067
16068 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16069 }
16070
16071 /*!
16072 @brief access specified object element
16073
16074 Returns a reference to the element at with specified key @a key.
16075
16076 @note If @a key is not found in the object, then it is silently added to
16077 the object and filled with a `null` value to make `key` a valid reference.
16078 In case the value was `null` before, it is converted to an object.
16079
16080 @param[in] key key of the element to access
16081
16082 @return reference to the element at key @a key
16083
16084 @throw type_error.305 if the JSON value is not an object or null; in that
16085 cases, using the [] operator with a key makes no sense.
16086
16087 @complexity Logarithmic in the size of the container.
16088
16089 @liveexample{The example below shows how object elements can be read and
16090 written using the `[]` operator.,operatorarray__key_type}
16091
16092 @sa @ref at(const typename object_t::key_type&) for access by reference
16093 with range checking
16094 @sa @ref value() for access by value with a default value
16095
16096 @since version 1.1.0
16097 */
16098 template<typename T>
operator [](T * key)16099 reference operator[](T* key)
16100 {
16101 // implicitly convert null to object
16102 if (is_null())
16103 {
16104 m_type = value_t::object;
16105 m_value = value_t::object;
16106 assert_invariant();
16107 }
16108
16109 // at only works for objects
16110 if (JSON_LIKELY(is_object()))
16111 {
16112 return m_value.object->operator[](key);
16113 }
16114
16115 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16116 }
16117
16118 /*!
16119 @brief read-only access specified object element
16120
16121 Returns a const reference to the element at with specified key @a key. No
16122 bounds checking is performed.
16123
16124 @warning If the element with key @a key does not exist, the behavior is
16125 undefined.
16126
16127 @param[in] key key of the element to access
16128
16129 @return const reference to the element at key @a key
16130
16131 @pre The element with key @a key must exist. **This precondition is
16132 enforced with an assertion.**
16133
16134 @throw type_error.305 if the JSON value is not an object; in that case,
16135 using the [] operator with a key makes no sense.
16136
16137 @complexity Logarithmic in the size of the container.
16138
16139 @liveexample{The example below shows how object elements can be read using
16140 the `[]` operator.,operatorarray__key_type_const}
16141
16142 @sa @ref at(const typename object_t::key_type&) for access by reference
16143 with range checking
16144 @sa @ref value() for access by value with a default value
16145
16146 @since version 1.1.0
16147 */
16148 template<typename T>
operator [](T * key) const16149 const_reference operator[](T* key) const
16150 {
16151 // at only works for objects
16152 if (JSON_LIKELY(is_object()))
16153 {
16154 assert(m_value.object->find(key) != m_value.object->end());
16155 return m_value.object->find(key)->second;
16156 }
16157
16158 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name())));
16159 }
16160
16161 /*!
16162 @brief access specified object element with default value
16163
16164 Returns either a copy of an object's element at the specified key @a key
16165 or a given default value if no element with key @a key exists.
16166
16167 The function is basically equivalent to executing
16168 @code {.cpp}
16169 try {
16170 return at(key);
16171 } catch(out_of_range) {
16172 return default_value;
16173 }
16174 @endcode
16175
16176 @note Unlike @ref at(const typename object_t::key_type&), this function
16177 does not throw if the given key @a key was not found.
16178
16179 @note Unlike @ref operator[](const typename object_t::key_type& key), this
16180 function does not implicitly add an element to the position defined by @a
16181 key. This function is furthermore also applicable to const objects.
16182
16183 @param[in] key key of the element to access
16184 @param[in] default_value the value to return if @a key is not found
16185
16186 @tparam ValueType type compatible to JSON values, for instance `int` for
16187 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
16188 JSON arrays. Note the type of the expected value at @a key and the default
16189 value @a default_value must be compatible.
16190
16191 @return copy of the element at key @a key or @a default_value if @a key
16192 is not found
16193
16194 @throw type_error.306 if the JSON value is not an object; in that case,
16195 using `value()` with a key makes no sense.
16196
16197 @complexity Logarithmic in the size of the container.
16198
16199 @liveexample{The example below shows how object elements can be queried
16200 with a default value.,basic_json__value}
16201
16202 @sa @ref at(const typename object_t::key_type&) for access by reference
16203 with range checking
16204 @sa @ref operator[](const typename object_t::key_type&) for unchecked
16205 access by reference
16206
16207 @since version 1.0.0
16208 */
16209 template<class ValueType, typename std::enable_if<
16210 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
16211 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
16212 {
16213 // at only works for objects
16214 if (JSON_LIKELY(is_object()))
16215 {
16216 // if key is found, return value and given default value otherwise
16217 const auto it = find(key);
16218 if (it != end())
16219 {
16220 return *it;
16221 }
16222
16223 return default_value;
16224 }
16225
16226 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
16227 }
16228
16229 /*!
16230 @brief overload for a default value of type const char*
16231 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
16232 */
value(const typename object_t::key_type & key,const char * default_value) const16233 string_t value(const typename object_t::key_type& key, const char* default_value) const
16234 {
16235 return value(key, string_t(default_value));
16236 }
16237
16238 /*!
16239 @brief access specified object element via JSON Pointer with default value
16240
16241 Returns either a copy of an object's element at the specified key @a key
16242 or a given default value if no element with key @a key exists.
16243
16244 The function is basically equivalent to executing
16245 @code {.cpp}
16246 try {
16247 return at(ptr);
16248 } catch(out_of_range) {
16249 return default_value;
16250 }
16251 @endcode
16252
16253 @note Unlike @ref at(const json_pointer&), this function does not throw
16254 if the given key @a key was not found.
16255
16256 @param[in] ptr a JSON pointer to the element to access
16257 @param[in] default_value the value to return if @a ptr found no value
16258
16259 @tparam ValueType type compatible to JSON values, for instance `int` for
16260 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
16261 JSON arrays. Note the type of the expected value at @a key and the default
16262 value @a default_value must be compatible.
16263
16264 @return copy of the element at key @a key or @a default_value if @a key
16265 is not found
16266
16267 @throw type_error.306 if the JSON value is not an object; in that case,
16268 using `value()` with a key makes no sense.
16269
16270 @complexity Logarithmic in the size of the container.
16271
16272 @liveexample{The example below shows how object elements can be queried
16273 with a default value.,basic_json__value_ptr}
16274
16275 @sa @ref operator[](const json_pointer&) for unchecked access by reference
16276
16277 @since version 2.0.2
16278 */
16279 template<class ValueType, typename std::enable_if<
16280 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
16281 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
16282 {
16283 // at only works for objects
16284 if (JSON_LIKELY(is_object()))
16285 {
16286 // if pointer resolves a value, return it or use default value
16287 JSON_TRY
16288 {
16289 return ptr.get_checked(this);
16290 }
16291 JSON_INTERNAL_CATCH (out_of_range&)
16292 {
16293 return default_value;
16294 }
16295 }
16296
16297 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
16298 }
16299
16300 /*!
16301 @brief overload for a default value of type const char*
16302 @copydoc basic_json::value(const json_pointer&, ValueType) const
16303 */
value(const json_pointer & ptr,const char * default_value) const16304 string_t value(const json_pointer& ptr, const char* default_value) const
16305 {
16306 return value(ptr, string_t(default_value));
16307 }
16308
16309 /*!
16310 @brief access the first element
16311
16312 Returns a reference to the first element in the container. For a JSON
16313 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
16314
16315 @return In case of a structured type (array or object), a reference to the
16316 first element is returned. In case of number, string, or boolean values, a
16317 reference to the value is returned.
16318
16319 @complexity Constant.
16320
16321 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
16322 or an empty array or object (undefined behavior, **guarded by
16323 assertions**).
16324 @post The JSON value remains unchanged.
16325
16326 @throw invalid_iterator.214 when called on `null` value
16327
16328 @liveexample{The following code shows an example for `front()`.,front}
16329
16330 @sa @ref back() -- access the last element
16331
16332 @since version 1.0.0
16333 */
front()16334 reference front()
16335 {
16336 return *begin();
16337 }
16338
16339 /*!
16340 @copydoc basic_json::front()
16341 */
front() const16342 const_reference front() const
16343 {
16344 return *cbegin();
16345 }
16346
16347 /*!
16348 @brief access the last element
16349
16350 Returns a reference to the last element in the container. For a JSON
16351 container `c`, the expression `c.back()` is equivalent to
16352 @code {.cpp}
16353 auto tmp = c.end();
16354 --tmp;
16355 return *tmp;
16356 @endcode
16357
16358 @return In case of a structured type (array or object), a reference to the
16359 last element is returned. In case of number, string, or boolean values, a
16360 reference to the value is returned.
16361
16362 @complexity Constant.
16363
16364 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
16365 or an empty array or object (undefined behavior, **guarded by
16366 assertions**).
16367 @post The JSON value remains unchanged.
16368
16369 @throw invalid_iterator.214 when called on a `null` value. See example
16370 below.
16371
16372 @liveexample{The following code shows an example for `back()`.,back}
16373
16374 @sa @ref front() -- access the first element
16375
16376 @since version 1.0.0
16377 */
back()16378 reference back()
16379 {
16380 auto tmp = end();
16381 --tmp;
16382 return *tmp;
16383 }
16384
16385 /*!
16386 @copydoc basic_json::back()
16387 */
back() const16388 const_reference back() const
16389 {
16390 auto tmp = cend();
16391 --tmp;
16392 return *tmp;
16393 }
16394
16395 /*!
16396 @brief remove element given an iterator
16397
16398 Removes the element specified by iterator @a pos. The iterator @a pos must
16399 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
16400 but is not dereferenceable) cannot be used as a value for @a pos.
16401
16402 If called on a primitive type other than `null`, the resulting JSON value
16403 will be `null`.
16404
16405 @param[in] pos iterator to the element to remove
16406 @return Iterator following the last removed element. If the iterator @a
16407 pos refers to the last element, the `end()` iterator is returned.
16408
16409 @tparam IteratorType an @ref iterator or @ref const_iterator
16410
16411 @post Invalidates iterators and references at or after the point of the
16412 erase, including the `end()` iterator.
16413
16414 @throw type_error.307 if called on a `null` value; example: `"cannot use
16415 erase() with null"`
16416 @throw invalid_iterator.202 if called on an iterator which does not belong
16417 to the current JSON value; example: `"iterator does not fit current
16418 value"`
16419 @throw invalid_iterator.205 if called on a primitive type with invalid
16420 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
16421 out of range"`
16422
16423 @complexity The complexity depends on the type:
16424 - objects: amortized constant
16425 - arrays: linear in distance between @a pos and the end of the container
16426 - strings: linear in the length of the string
16427 - other types: constant
16428
16429 @liveexample{The example shows the result of `erase()` for different JSON
16430 types.,erase__IteratorType}
16431
16432 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16433 the given range
16434 @sa @ref erase(const typename object_t::key_type&) -- removes the element
16435 from an object at the given key
16436 @sa @ref erase(const size_type) -- removes the element from an array at
16437 the given index
16438
16439 @since version 1.0.0
16440 */
16441 template<class IteratorType, typename std::enable_if<
16442 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16443 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
16444 = 0>
16445 IteratorType erase(IteratorType pos)
16446 {
16447 // make sure iterator fits the current value
16448 if (JSON_UNLIKELY(this != pos.m_object))
16449 {
16450 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
16451 }
16452
16453 IteratorType result = end();
16454
16455 switch (m_type)
16456 {
16457 case value_t::boolean:
16458 case value_t::number_float:
16459 case value_t::number_integer:
16460 case value_t::number_unsigned:
16461 case value_t::string:
16462 {
16463 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
16464 {
16465 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
16466 }
16467
16468 if (is_string())
16469 {
16470 AllocatorType<string_t> alloc;
16471 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16472 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16473 m_value.string = nullptr;
16474 }
16475
16476 m_type = value_t::null;
16477 assert_invariant();
16478 break;
16479 }
16480
16481 case value_t::object:
16482 {
16483 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
16484 break;
16485 }
16486
16487 case value_t::array:
16488 {
16489 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
16490 break;
16491 }
16492
16493 default:
16494 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16495 }
16496
16497 return result;
16498 }
16499
16500 /*!
16501 @brief remove elements given an iterator range
16502
16503 Removes the element specified by the range `[first; last)`. The iterator
16504 @a first does not need to be dereferenceable if `first == last`: erasing
16505 an empty range is a no-op.
16506
16507 If called on a primitive type other than `null`, the resulting JSON value
16508 will be `null`.
16509
16510 @param[in] first iterator to the beginning of the range to remove
16511 @param[in] last iterator past the end of the range to remove
16512 @return Iterator following the last removed element. If the iterator @a
16513 second refers to the last element, the `end()` iterator is returned.
16514
16515 @tparam IteratorType an @ref iterator or @ref const_iterator
16516
16517 @post Invalidates iterators and references at or after the point of the
16518 erase, including the `end()` iterator.
16519
16520 @throw type_error.307 if called on a `null` value; example: `"cannot use
16521 erase() with null"`
16522 @throw invalid_iterator.203 if called on iterators which does not belong
16523 to the current JSON value; example: `"iterators do not fit current value"`
16524 @throw invalid_iterator.204 if called on a primitive type with invalid
16525 iterators (i.e., if `first != begin()` and `last != end()`); example:
16526 `"iterators out of range"`
16527
16528 @complexity The complexity depends on the type:
16529 - objects: `log(size()) + std::distance(first, last)`
16530 - arrays: linear in the distance between @a first and @a last, plus linear
16531 in the distance between @a last and end of the container
16532 - strings: linear in the length of the string
16533 - other types: constant
16534
16535 @liveexample{The example shows the result of `erase()` for different JSON
16536 types.,erase__IteratorType_IteratorType}
16537
16538 @sa @ref erase(IteratorType) -- removes the element at a given position
16539 @sa @ref erase(const typename object_t::key_type&) -- removes the element
16540 from an object at the given key
16541 @sa @ref erase(const size_type) -- removes the element from an array at
16542 the given index
16543
16544 @since version 1.0.0
16545 */
16546 template<class IteratorType, typename std::enable_if<
16547 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
16548 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
16549 = 0>
16550 IteratorType erase(IteratorType first, IteratorType last)
16551 {
16552 // make sure iterator fits the current value
16553 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
16554 {
16555 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
16556 }
16557
16558 IteratorType result = end();
16559
16560 switch (m_type)
16561 {
16562 case value_t::boolean:
16563 case value_t::number_float:
16564 case value_t::number_integer:
16565 case value_t::number_unsigned:
16566 case value_t::string:
16567 {
16568 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
16569 or not last.m_it.primitive_iterator.is_end()))
16570 {
16571 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
16572 }
16573
16574 if (is_string())
16575 {
16576 AllocatorType<string_t> alloc;
16577 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
16578 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
16579 m_value.string = nullptr;
16580 }
16581
16582 m_type = value_t::null;
16583 assert_invariant();
16584 break;
16585 }
16586
16587 case value_t::object:
16588 {
16589 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
16590 last.m_it.object_iterator);
16591 break;
16592 }
16593
16594 case value_t::array:
16595 {
16596 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
16597 last.m_it.array_iterator);
16598 break;
16599 }
16600
16601 default:
16602 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16603 }
16604
16605 return result;
16606 }
16607
16608 /*!
16609 @brief remove element from a JSON object given a key
16610
16611 Removes elements from a JSON object with the key value @a key.
16612
16613 @param[in] key value of the elements to remove
16614
16615 @return Number of elements removed. If @a ObjectType is the default
16616 `std::map` type, the return value will always be `0` (@a key was not
16617 found) or `1` (@a key was found).
16618
16619 @post References and iterators to the erased elements are invalidated.
16620 Other references and iterators are not affected.
16621
16622 @throw type_error.307 when called on a type other than JSON object;
16623 example: `"cannot use erase() with null"`
16624
16625 @complexity `log(size()) + count(key)`
16626
16627 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
16628
16629 @sa @ref erase(IteratorType) -- removes the element at a given position
16630 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16631 the given range
16632 @sa @ref erase(const size_type) -- removes the element from an array at
16633 the given index
16634
16635 @since version 1.0.0
16636 */
erase(const typename object_t::key_type & key)16637 size_type erase(const typename object_t::key_type& key)
16638 {
16639 // this erase only works for objects
16640 if (JSON_LIKELY(is_object()))
16641 {
16642 return m_value.object->erase(key);
16643 }
16644
16645 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16646 }
16647
16648 /*!
16649 @brief remove element from a JSON array given an index
16650
16651 Removes element from a JSON array at the index @a idx.
16652
16653 @param[in] idx index of the element to remove
16654
16655 @throw type_error.307 when called on a type other than JSON object;
16656 example: `"cannot use erase() with null"`
16657 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
16658 is out of range"`
16659
16660 @complexity Linear in distance between @a idx and the end of the container.
16661
16662 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
16663
16664 @sa @ref erase(IteratorType) -- removes the element at a given position
16665 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
16666 the given range
16667 @sa @ref erase(const typename object_t::key_type&) -- removes the element
16668 from an object at the given key
16669
16670 @since version 1.0.0
16671 */
erase(const size_type idx)16672 void erase(const size_type idx)
16673 {
16674 // this erase only works for arrays
16675 if (JSON_LIKELY(is_array()))
16676 {
16677 if (JSON_UNLIKELY(idx >= size()))
16678 {
16679 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
16680 }
16681
16682 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
16683 }
16684 else
16685 {
16686 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
16687 }
16688 }
16689
16690 /// @}
16691
16692
16693 ////////////
16694 // lookup //
16695 ////////////
16696
16697 /// @name lookup
16698 /// @{
16699
16700 /*!
16701 @brief find an element in a JSON object
16702
16703 Finds an element in a JSON object with key equivalent to @a key. If the
16704 element is not found or the JSON value is not an object, end() is
16705 returned.
16706
16707 @note This method always returns @ref end() when executed on a JSON type
16708 that is not an object.
16709
16710 @param[in] key key value of the element to search for.
16711
16712 @return Iterator to an element with key equivalent to @a key. If no such
16713 element is found or the JSON value is not an object, past-the-end (see
16714 @ref end()) iterator is returned.
16715
16716 @complexity Logarithmic in the size of the JSON object.
16717
16718 @liveexample{The example shows how `find()` is used.,find__key_type}
16719
16720 @sa @ref contains(KeyT&&) const -- checks whether a key exists
16721
16722 @since version 1.0.0
16723 */
16724 template<typename KeyT>
find(KeyT && key)16725 iterator find(KeyT&& key)
16726 {
16727 auto result = end();
16728
16729 if (is_object())
16730 {
16731 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16732 }
16733
16734 return result;
16735 }
16736
16737 /*!
16738 @brief find an element in a JSON object
16739 @copydoc find(KeyT&&)
16740 */
16741 template<typename KeyT>
find(KeyT && key) const16742 const_iterator find(KeyT&& key) const
16743 {
16744 auto result = cend();
16745
16746 if (is_object())
16747 {
16748 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
16749 }
16750
16751 return result;
16752 }
16753
16754 /*!
16755 @brief returns the number of occurrences of a key in a JSON object
16756
16757 Returns the number of elements with key @a key. If ObjectType is the
16758 default `std::map` type, the return value will always be `0` (@a key was
16759 not found) or `1` (@a key was found).
16760
16761 @note This method always returns `0` when executed on a JSON type that is
16762 not an object.
16763
16764 @param[in] key key value of the element to count
16765
16766 @return Number of elements with key @a key. If the JSON value is not an
16767 object, the return value will be `0`.
16768
16769 @complexity Logarithmic in the size of the JSON object.
16770
16771 @liveexample{The example shows how `count()` is used.,count}
16772
16773 @since version 1.0.0
16774 */
16775 template<typename KeyT>
count(KeyT && key) const16776 size_type count(KeyT&& key) const
16777 {
16778 // return 0 for all nonobject types
16779 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
16780 }
16781
16782 /*!
16783 @brief check the existence of an element in a JSON object
16784
16785 Check whether an element exists in a JSON object with key equivalent to
16786 @a key. If the element is not found or the JSON value is not an object,
16787 false is returned.
16788
16789 @note This method always returns false when executed on a JSON type
16790 that is not an object.
16791
16792 @param[in] key key value to check its existence.
16793
16794 @return true if an element with specified @a key exists. If no such
16795 element with such key is found or the JSON value is not an object,
16796 false is returned.
16797
16798 @complexity Logarithmic in the size of the JSON object.
16799
16800 @liveexample{The following code shows an example for `contains()`.,contains}
16801
16802 @sa @ref find(KeyT&&) -- returns an iterator to an object element
16803
16804 @since version 3.6.0
16805 */
16806 template<typename KeyT>
contains(KeyT && key) const16807 bool contains(KeyT&& key) const
16808 {
16809 return is_object() and m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
16810 }
16811
16812 /// @}
16813
16814
16815 ///////////////
16816 // iterators //
16817 ///////////////
16818
16819 /// @name iterators
16820 /// @{
16821
16822 /*!
16823 @brief returns an iterator to the first element
16824
16825 Returns an iterator to the first element.
16826
16827 @image html range-begin-end.svg "Illustration from cppreference.com"
16828
16829 @return iterator to the first element
16830
16831 @complexity Constant.
16832
16833 @requirement This function helps `basic_json` satisfying the
16834 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16835 requirements:
16836 - The complexity is constant.
16837
16838 @liveexample{The following code shows an example for `begin()`.,begin}
16839
16840 @sa @ref cbegin() -- returns a const iterator to the beginning
16841 @sa @ref end() -- returns an iterator to the end
16842 @sa @ref cend() -- returns a const iterator to the end
16843
16844 @since version 1.0.0
16845 */
begin()16846 iterator begin() noexcept
16847 {
16848 iterator result(this);
16849 result.set_begin();
16850 return result;
16851 }
16852
16853 /*!
16854 @copydoc basic_json::cbegin()
16855 */
begin() const16856 const_iterator begin() const noexcept
16857 {
16858 return cbegin();
16859 }
16860
16861 /*!
16862 @brief returns a const iterator to the first element
16863
16864 Returns a const iterator to the first element.
16865
16866 @image html range-begin-end.svg "Illustration from cppreference.com"
16867
16868 @return const iterator to the first element
16869
16870 @complexity Constant.
16871
16872 @requirement This function helps `basic_json` satisfying the
16873 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16874 requirements:
16875 - The complexity is constant.
16876 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
16877
16878 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
16879
16880 @sa @ref begin() -- returns an iterator to the beginning
16881 @sa @ref end() -- returns an iterator to the end
16882 @sa @ref cend() -- returns a const iterator to the end
16883
16884 @since version 1.0.0
16885 */
cbegin() const16886 const_iterator cbegin() const noexcept
16887 {
16888 const_iterator result(this);
16889 result.set_begin();
16890 return result;
16891 }
16892
16893 /*!
16894 @brief returns an iterator to one past the last element
16895
16896 Returns an iterator to one past the last element.
16897
16898 @image html range-begin-end.svg "Illustration from cppreference.com"
16899
16900 @return iterator one past the last element
16901
16902 @complexity Constant.
16903
16904 @requirement This function helps `basic_json` satisfying the
16905 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16906 requirements:
16907 - The complexity is constant.
16908
16909 @liveexample{The following code shows an example for `end()`.,end}
16910
16911 @sa @ref cend() -- returns a const iterator to the end
16912 @sa @ref begin() -- returns an iterator to the beginning
16913 @sa @ref cbegin() -- returns a const iterator to the beginning
16914
16915 @since version 1.0.0
16916 */
end()16917 iterator end() noexcept
16918 {
16919 iterator result(this);
16920 result.set_end();
16921 return result;
16922 }
16923
16924 /*!
16925 @copydoc basic_json::cend()
16926 */
end() const16927 const_iterator end() const noexcept
16928 {
16929 return cend();
16930 }
16931
16932 /*!
16933 @brief returns a const iterator to one past the last element
16934
16935 Returns a const iterator to one past the last element.
16936
16937 @image html range-begin-end.svg "Illustration from cppreference.com"
16938
16939 @return const iterator one past the last element
16940
16941 @complexity Constant.
16942
16943 @requirement This function helps `basic_json` satisfying the
16944 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
16945 requirements:
16946 - The complexity is constant.
16947 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
16948
16949 @liveexample{The following code shows an example for `cend()`.,cend}
16950
16951 @sa @ref end() -- returns an iterator to the end
16952 @sa @ref begin() -- returns an iterator to the beginning
16953 @sa @ref cbegin() -- returns a const iterator to the beginning
16954
16955 @since version 1.0.0
16956 */
cend() const16957 const_iterator cend() const noexcept
16958 {
16959 const_iterator result(this);
16960 result.set_end();
16961 return result;
16962 }
16963
16964 /*!
16965 @brief returns an iterator to the reverse-beginning
16966
16967 Returns an iterator to the reverse-beginning; that is, the last element.
16968
16969 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
16970
16971 @complexity Constant.
16972
16973 @requirement This function helps `basic_json` satisfying the
16974 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
16975 requirements:
16976 - The complexity is constant.
16977 - Has the semantics of `reverse_iterator(end())`.
16978
16979 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
16980
16981 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
16982 @sa @ref rend() -- returns a reverse iterator to the end
16983 @sa @ref crend() -- returns a const reverse iterator to the end
16984
16985 @since version 1.0.0
16986 */
rbegin()16987 reverse_iterator rbegin() noexcept
16988 {
16989 return reverse_iterator(end());
16990 }
16991
16992 /*!
16993 @copydoc basic_json::crbegin()
16994 */
rbegin() const16995 const_reverse_iterator rbegin() const noexcept
16996 {
16997 return crbegin();
16998 }
16999
17000 /*!
17001 @brief returns an iterator to the reverse-end
17002
17003 Returns an iterator to the reverse-end; that is, one before the first
17004 element.
17005
17006 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
17007
17008 @complexity Constant.
17009
17010 @requirement This function helps `basic_json` satisfying the
17011 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
17012 requirements:
17013 - The complexity is constant.
17014 - Has the semantics of `reverse_iterator(begin())`.
17015
17016 @liveexample{The following code shows an example for `rend()`.,rend}
17017
17018 @sa @ref crend() -- returns a const reverse iterator to the end
17019 @sa @ref rbegin() -- returns a reverse iterator to the beginning
17020 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
17021
17022 @since version 1.0.0
17023 */
rend()17024 reverse_iterator rend() noexcept
17025 {
17026 return reverse_iterator(begin());
17027 }
17028
17029 /*!
17030 @copydoc basic_json::crend()
17031 */
rend() const17032 const_reverse_iterator rend() const noexcept
17033 {
17034 return crend();
17035 }
17036
17037 /*!
17038 @brief returns a const reverse iterator to the last element
17039
17040 Returns a const iterator to the reverse-beginning; that is, the last
17041 element.
17042
17043 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
17044
17045 @complexity Constant.
17046
17047 @requirement This function helps `basic_json` satisfying the
17048 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
17049 requirements:
17050 - The complexity is constant.
17051 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
17052
17053 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
17054
17055 @sa @ref rbegin() -- returns a reverse iterator to the beginning
17056 @sa @ref rend() -- returns a reverse iterator to the end
17057 @sa @ref crend() -- returns a const reverse iterator to the end
17058
17059 @since version 1.0.0
17060 */
crbegin() const17061 const_reverse_iterator crbegin() const noexcept
17062 {
17063 return const_reverse_iterator(cend());
17064 }
17065
17066 /*!
17067 @brief returns a const reverse iterator to one before the first
17068
17069 Returns a const reverse iterator to the reverse-end; that is, one before
17070 the first element.
17071
17072 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
17073
17074 @complexity Constant.
17075
17076 @requirement This function helps `basic_json` satisfying the
17077 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
17078 requirements:
17079 - The complexity is constant.
17080 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
17081
17082 @liveexample{The following code shows an example for `crend()`.,crend}
17083
17084 @sa @ref rend() -- returns a reverse iterator to the end
17085 @sa @ref rbegin() -- returns a reverse iterator to the beginning
17086 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
17087
17088 @since version 1.0.0
17089 */
crend() const17090 const_reverse_iterator crend() const noexcept
17091 {
17092 return const_reverse_iterator(cbegin());
17093 }
17094
17095 public:
17096 /*!
17097 @brief wrapper to access iterator member functions in range-based for
17098
17099 This function allows to access @ref iterator::key() and @ref
17100 iterator::value() during range-based for loops. In these loops, a
17101 reference to the JSON values is returned, so there is no access to the
17102 underlying iterator.
17103
17104 For loop without iterator_wrapper:
17105
17106 @code{cpp}
17107 for (auto it = j_object.begin(); it != j_object.end(); ++it)
17108 {
17109 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17110 }
17111 @endcode
17112
17113 Range-based for loop without iterator proxy:
17114
17115 @code{cpp}
17116 for (auto it : j_object)
17117 {
17118 // "it" is of type json::reference and has no key() member
17119 std::cout << "value: " << it << '\n';
17120 }
17121 @endcode
17122
17123 Range-based for loop with iterator proxy:
17124
17125 @code{cpp}
17126 for (auto it : json::iterator_wrapper(j_object))
17127 {
17128 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17129 }
17130 @endcode
17131
17132 @note When iterating over an array, `key()` will return the index of the
17133 element as string (see example).
17134
17135 @param[in] ref reference to a JSON value
17136 @return iteration proxy object wrapping @a ref with an interface to use in
17137 range-based for loops
17138
17139 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
17140
17141 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17142 changes in the JSON value.
17143
17144 @complexity Constant.
17145
17146 @note The name of this function is not yet final and may change in the
17147 future.
17148
17149 @deprecated This stream operator is deprecated and will be removed in
17150 future 4.0.0 of the library. Please use @ref items() instead;
17151 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
17152 */
17153 JSON_DEPRECATED
iterator_wrapper(reference ref)17154 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
17155 {
17156 return ref.items();
17157 }
17158
17159 /*!
17160 @copydoc iterator_wrapper(reference)
17161 */
17162 JSON_DEPRECATED
iterator_wrapper(const_reference ref)17163 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
17164 {
17165 return ref.items();
17166 }
17167
17168 /*!
17169 @brief helper to access iterator member functions in range-based for
17170
17171 This function allows to access @ref iterator::key() and @ref
17172 iterator::value() during range-based for loops. In these loops, a
17173 reference to the JSON values is returned, so there is no access to the
17174 underlying iterator.
17175
17176 For loop without `items()` function:
17177
17178 @code{cpp}
17179 for (auto it = j_object.begin(); it != j_object.end(); ++it)
17180 {
17181 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
17182 }
17183 @endcode
17184
17185 Range-based for loop without `items()` function:
17186
17187 @code{cpp}
17188 for (auto it : j_object)
17189 {
17190 // "it" is of type json::reference and has no key() member
17191 std::cout << "value: " << it << '\n';
17192 }
17193 @endcode
17194
17195 Range-based for loop with `items()` function:
17196
17197 @code{cpp}
17198 for (auto& el : j_object.items())
17199 {
17200 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
17201 }
17202 @endcode
17203
17204 The `items()` function also allows to use
17205 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
17206 (C++17):
17207
17208 @code{cpp}
17209 for (auto& [key, val] : j_object.items())
17210 {
17211 std::cout << "key: " << key << ", value:" << val << '\n';
17212 }
17213 @endcode
17214
17215 @note When iterating over an array, `key()` will return the index of the
17216 element as string (see example). For primitive types (e.g., numbers),
17217 `key()` returns an empty string.
17218
17219 @return iteration proxy object wrapping @a ref with an interface to use in
17220 range-based for loops
17221
17222 @liveexample{The following code shows how the function is used.,items}
17223
17224 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17225 changes in the JSON value.
17226
17227 @complexity Constant.
17228
17229 @since version 3.1.0, structured bindings support since 3.5.0.
17230 */
items()17231 iteration_proxy<iterator> items() noexcept
17232 {
17233 return iteration_proxy<iterator>(*this);
17234 }
17235
17236 /*!
17237 @copydoc items()
17238 */
items() const17239 iteration_proxy<const_iterator> items() const noexcept
17240 {
17241 return iteration_proxy<const_iterator>(*this);
17242 }
17243
17244 /// @}
17245
17246
17247 //////////////
17248 // capacity //
17249 //////////////
17250
17251 /// @name capacity
17252 /// @{
17253
17254 /*!
17255 @brief checks whether the container is empty.
17256
17257 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
17258
17259 @return The return value depends on the different types and is
17260 defined as follows:
17261 Value type | return value
17262 ----------- | -------------
17263 null | `true`
17264 boolean | `false`
17265 string | `false`
17266 number | `false`
17267 object | result of function `object_t::empty()`
17268 array | result of function `array_t::empty()`
17269
17270 @liveexample{The following code uses `empty()` to check if a JSON
17271 object contains any elements.,empty}
17272
17273 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17274 the Container concept; that is, their `empty()` functions have constant
17275 complexity.
17276
17277 @iterators No changes.
17278
17279 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17280
17281 @note This function does not return whether a string stored as JSON value
17282 is empty - it returns whether the JSON container itself is empty which is
17283 false in the case of a string.
17284
17285 @requirement This function helps `basic_json` satisfying the
17286 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17287 requirements:
17288 - The complexity is constant.
17289 - Has the semantics of `begin() == end()`.
17290
17291 @sa @ref size() -- returns the number of elements
17292
17293 @since version 1.0.0
17294 */
empty() const17295 bool empty() const noexcept
17296 {
17297 switch (m_type)
17298 {
17299 case value_t::null:
17300 {
17301 // null values are empty
17302 return true;
17303 }
17304
17305 case value_t::array:
17306 {
17307 // delegate call to array_t::empty()
17308 return m_value.array->empty();
17309 }
17310
17311 case value_t::object:
17312 {
17313 // delegate call to object_t::empty()
17314 return m_value.object->empty();
17315 }
17316
17317 default:
17318 {
17319 // all other types are nonempty
17320 return false;
17321 }
17322 }
17323 }
17324
17325 /*!
17326 @brief returns the number of elements
17327
17328 Returns the number of elements in a JSON value.
17329
17330 @return The return value depends on the different types and is
17331 defined as follows:
17332 Value type | return value
17333 ----------- | -------------
17334 null | `0`
17335 boolean | `1`
17336 string | `1`
17337 number | `1`
17338 object | result of function object_t::size()
17339 array | result of function array_t::size()
17340
17341 @liveexample{The following code calls `size()` on the different value
17342 types.,size}
17343
17344 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17345 the Container concept; that is, their size() functions have constant
17346 complexity.
17347
17348 @iterators No changes.
17349
17350 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17351
17352 @note This function does not return the length of a string stored as JSON
17353 value - it returns the number of elements in the JSON value which is 1 in
17354 the case of a string.
17355
17356 @requirement This function helps `basic_json` satisfying the
17357 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17358 requirements:
17359 - The complexity is constant.
17360 - Has the semantics of `std::distance(begin(), end())`.
17361
17362 @sa @ref empty() -- checks whether the container is empty
17363 @sa @ref max_size() -- returns the maximal number of elements
17364
17365 @since version 1.0.0
17366 */
size() const17367 size_type size() const noexcept
17368 {
17369 switch (m_type)
17370 {
17371 case value_t::null:
17372 {
17373 // null values are empty
17374 return 0;
17375 }
17376
17377 case value_t::array:
17378 {
17379 // delegate call to array_t::size()
17380 return m_value.array->size();
17381 }
17382
17383 case value_t::object:
17384 {
17385 // delegate call to object_t::size()
17386 return m_value.object->size();
17387 }
17388
17389 default:
17390 {
17391 // all other types have size 1
17392 return 1;
17393 }
17394 }
17395 }
17396
17397 /*!
17398 @brief returns the maximum possible number of elements
17399
17400 Returns the maximum number of elements a JSON value is able to hold due to
17401 system or library implementation limitations, i.e. `std::distance(begin(),
17402 end())` for the JSON value.
17403
17404 @return The return value depends on the different types and is
17405 defined as follows:
17406 Value type | return value
17407 ----------- | -------------
17408 null | `0` (same as `size()`)
17409 boolean | `1` (same as `size()`)
17410 string | `1` (same as `size()`)
17411 number | `1` (same as `size()`)
17412 object | result of function `object_t::max_size()`
17413 array | result of function `array_t::max_size()`
17414
17415 @liveexample{The following code calls `max_size()` on the different value
17416 types. Note the output is implementation specific.,max_size}
17417
17418 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
17419 the Container concept; that is, their `max_size()` functions have constant
17420 complexity.
17421
17422 @iterators No changes.
17423
17424 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17425
17426 @requirement This function helps `basic_json` satisfying the
17427 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
17428 requirements:
17429 - The complexity is constant.
17430 - Has the semantics of returning `b.size()` where `b` is the largest
17431 possible JSON value.
17432
17433 @sa @ref size() -- returns the number of elements
17434
17435 @since version 1.0.0
17436 */
max_size() const17437 size_type max_size() const noexcept
17438 {
17439 switch (m_type)
17440 {
17441 case value_t::array:
17442 {
17443 // delegate call to array_t::max_size()
17444 return m_value.array->max_size();
17445 }
17446
17447 case value_t::object:
17448 {
17449 // delegate call to object_t::max_size()
17450 return m_value.object->max_size();
17451 }
17452
17453 default:
17454 {
17455 // all other types have max_size() == size()
17456 return size();
17457 }
17458 }
17459 }
17460
17461 /// @}
17462
17463
17464 ///////////////
17465 // modifiers //
17466 ///////////////
17467
17468 /// @name modifiers
17469 /// @{
17470
17471 /*!
17472 @brief clears the contents
17473
17474 Clears the content of a JSON value and resets it to the default value as
17475 if @ref basic_json(value_t) would have been called with the current value
17476 type from @ref type():
17477
17478 Value type | initial value
17479 ----------- | -------------
17480 null | `null`
17481 boolean | `false`
17482 string | `""`
17483 number | `0`
17484 object | `{}`
17485 array | `[]`
17486
17487 @post Has the same effect as calling
17488 @code {.cpp}
17489 *this = basic_json(type());
17490 @endcode
17491
17492 @liveexample{The example below shows the effect of `clear()` to different
17493 JSON types.,clear}
17494
17495 @complexity Linear in the size of the JSON value.
17496
17497 @iterators All iterators, pointers and references related to this container
17498 are invalidated.
17499
17500 @exceptionsafety No-throw guarantee: this function never throws exceptions.
17501
17502 @sa @ref basic_json(value_t) -- constructor that creates an object with the
17503 same value than calling `clear()`
17504
17505 @since version 1.0.0
17506 */
clear()17507 void clear() noexcept
17508 {
17509 switch (m_type)
17510 {
17511 case value_t::number_integer:
17512 {
17513 m_value.number_integer = 0;
17514 break;
17515 }
17516
17517 case value_t::number_unsigned:
17518 {
17519 m_value.number_unsigned = 0;
17520 break;
17521 }
17522
17523 case value_t::number_float:
17524 {
17525 m_value.number_float = 0.0;
17526 break;
17527 }
17528
17529 case value_t::boolean:
17530 {
17531 m_value.boolean = false;
17532 break;
17533 }
17534
17535 case value_t::string:
17536 {
17537 m_value.string->clear();
17538 break;
17539 }
17540
17541 case value_t::array:
17542 {
17543 m_value.array->clear();
17544 break;
17545 }
17546
17547 case value_t::object:
17548 {
17549 m_value.object->clear();
17550 break;
17551 }
17552
17553 default:
17554 break;
17555 }
17556 }
17557
17558 /*!
17559 @brief add an object to an array
17560
17561 Appends the given element @a val to the end of the JSON value. If the
17562 function is called on a JSON null value, an empty array is created before
17563 appending @a val.
17564
17565 @param[in] val the value to add to the JSON array
17566
17567 @throw type_error.308 when called on a type other than JSON array or
17568 null; example: `"cannot use push_back() with number"`
17569
17570 @complexity Amortized constant.
17571
17572 @liveexample{The example shows how `push_back()` and `+=` can be used to
17573 add elements to a JSON array. Note how the `null` value was silently
17574 converted to a JSON array.,push_back}
17575
17576 @since version 1.0.0
17577 */
push_back(basic_json && val)17578 void push_back(basic_json&& val)
17579 {
17580 // push_back only works for null objects or arrays
17581 if (JSON_UNLIKELY(not(is_null() or is_array())))
17582 {
17583 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17584 }
17585
17586 // transform null object into an array
17587 if (is_null())
17588 {
17589 m_type = value_t::array;
17590 m_value = value_t::array;
17591 assert_invariant();
17592 }
17593
17594 // add element to array (move semantics)
17595 m_value.array->push_back(std::move(val));
17596 // invalidate object: mark it null so we do not call the destructor
17597 // cppcheck-suppress accessMoved
17598 val.m_type = value_t::null;
17599 }
17600
17601 /*!
17602 @brief add an object to an array
17603 @copydoc push_back(basic_json&&)
17604 */
operator +=(basic_json && val)17605 reference operator+=(basic_json&& val)
17606 {
17607 push_back(std::move(val));
17608 return *this;
17609 }
17610
17611 /*!
17612 @brief add an object to an array
17613 @copydoc push_back(basic_json&&)
17614 */
push_back(const basic_json & val)17615 void push_back(const basic_json& val)
17616 {
17617 // push_back only works for null objects or arrays
17618 if (JSON_UNLIKELY(not(is_null() or is_array())))
17619 {
17620 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17621 }
17622
17623 // transform null object into an array
17624 if (is_null())
17625 {
17626 m_type = value_t::array;
17627 m_value = value_t::array;
17628 assert_invariant();
17629 }
17630
17631 // add element to array
17632 m_value.array->push_back(val);
17633 }
17634
17635 /*!
17636 @brief add an object to an array
17637 @copydoc push_back(basic_json&&)
17638 */
operator +=(const basic_json & val)17639 reference operator+=(const basic_json& val)
17640 {
17641 push_back(val);
17642 return *this;
17643 }
17644
17645 /*!
17646 @brief add an object to an object
17647
17648 Inserts the given element @a val to the JSON object. If the function is
17649 called on a JSON null value, an empty object is created before inserting
17650 @a val.
17651
17652 @param[in] val the value to add to the JSON object
17653
17654 @throw type_error.308 when called on a type other than JSON object or
17655 null; example: `"cannot use push_back() with number"`
17656
17657 @complexity Logarithmic in the size of the container, O(log(`size()`)).
17658
17659 @liveexample{The example shows how `push_back()` and `+=` can be used to
17660 add elements to a JSON object. Note how the `null` value was silently
17661 converted to a JSON object.,push_back__object_t__value}
17662
17663 @since version 1.0.0
17664 */
push_back(const typename object_t::value_type & val)17665 void push_back(const typename object_t::value_type& val)
17666 {
17667 // push_back only works for null objects or objects
17668 if (JSON_UNLIKELY(not(is_null() or is_object())))
17669 {
17670 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
17671 }
17672
17673 // transform null object into an object
17674 if (is_null())
17675 {
17676 m_type = value_t::object;
17677 m_value = value_t::object;
17678 assert_invariant();
17679 }
17680
17681 // add element to array
17682 m_value.object->insert(val);
17683 }
17684
17685 /*!
17686 @brief add an object to an object
17687 @copydoc push_back(const typename object_t::value_type&)
17688 */
operator +=(const typename object_t::value_type & val)17689 reference operator+=(const typename object_t::value_type& val)
17690 {
17691 push_back(val);
17692 return *this;
17693 }
17694
17695 /*!
17696 @brief add an object to an object
17697
17698 This function allows to use `push_back` with an initializer list. In case
17699
17700 1. the current value is an object,
17701 2. the initializer list @a init contains only two elements, and
17702 3. the first element of @a init is a string,
17703
17704 @a init is converted into an object element and added using
17705 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
17706 is converted to a JSON value and added using @ref push_back(basic_json&&).
17707
17708 @param[in] init an initializer list
17709
17710 @complexity Linear in the size of the initializer list @a init.
17711
17712 @note This function is required to resolve an ambiguous overload error,
17713 because pairs like `{"key", "value"}` can be both interpreted as
17714 `object_t::value_type` or `std::initializer_list<basic_json>`, see
17715 https://github.com/nlohmann/json/issues/235 for more information.
17716
17717 @liveexample{The example shows how initializer lists are treated as
17718 objects when possible.,push_back__initializer_list}
17719 */
push_back(initializer_list_t init)17720 void push_back(initializer_list_t init)
17721 {
17722 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
17723 {
17724 basic_json&& key = init.begin()->moved_or_copied();
17725 push_back(typename object_t::value_type(
17726 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
17727 }
17728 else
17729 {
17730 push_back(basic_json(init));
17731 }
17732 }
17733
17734 /*!
17735 @brief add an object to an object
17736 @copydoc push_back(initializer_list_t)
17737 */
operator +=(initializer_list_t init)17738 reference operator+=(initializer_list_t init)
17739 {
17740 push_back(init);
17741 return *this;
17742 }
17743
17744 /*!
17745 @brief add an object to an array
17746
17747 Creates a JSON value from the passed parameters @a args to the end of the
17748 JSON value. If the function is called on a JSON null value, an empty array
17749 is created before appending the value created from @a args.
17750
17751 @param[in] args arguments to forward to a constructor of @ref basic_json
17752 @tparam Args compatible types to create a @ref basic_json object
17753
17754 @throw type_error.311 when called on a type other than JSON array or
17755 null; example: `"cannot use emplace_back() with number"`
17756
17757 @complexity Amortized constant.
17758
17759 @liveexample{The example shows how `push_back()` can be used to add
17760 elements to a JSON array. Note how the `null` value was silently converted
17761 to a JSON array.,emplace_back}
17762
17763 @since version 2.0.8
17764 */
17765 template<class... Args>
emplace_back(Args &&...args)17766 void emplace_back(Args&& ... args)
17767 {
17768 // emplace_back only works for null objects or arrays
17769 if (JSON_UNLIKELY(not(is_null() or is_array())))
17770 {
17771 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
17772 }
17773
17774 // transform null object into an array
17775 if (is_null())
17776 {
17777 m_type = value_t::array;
17778 m_value = value_t::array;
17779 assert_invariant();
17780 }
17781
17782 // add element to array (perfect forwarding)
17783 m_value.array->emplace_back(std::forward<Args>(args)...);
17784 }
17785
17786 /*!
17787 @brief add an object to an object if key does not exist
17788
17789 Inserts a new element into a JSON object constructed in-place with the
17790 given @a args if there is no element with the key in the container. If the
17791 function is called on a JSON null value, an empty object is created before
17792 appending the value created from @a args.
17793
17794 @param[in] args arguments to forward to a constructor of @ref basic_json
17795 @tparam Args compatible types to create a @ref basic_json object
17796
17797 @return a pair consisting of an iterator to the inserted element, or the
17798 already-existing element if no insertion happened, and a bool
17799 denoting whether the insertion took place.
17800
17801 @throw type_error.311 when called on a type other than JSON object or
17802 null; example: `"cannot use emplace() with number"`
17803
17804 @complexity Logarithmic in the size of the container, O(log(`size()`)).
17805
17806 @liveexample{The example shows how `emplace()` can be used to add elements
17807 to a JSON object. Note how the `null` value was silently converted to a
17808 JSON object. Further note how no value is added if there was already one
17809 value stored with the same key.,emplace}
17810
17811 @since version 2.0.8
17812 */
17813 template<class... Args>
emplace(Args &&...args)17814 std::pair<iterator, bool> emplace(Args&& ... args)
17815 {
17816 // emplace only works for null objects or arrays
17817 if (JSON_UNLIKELY(not(is_null() or is_object())))
17818 {
17819 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
17820 }
17821
17822 // transform null object into an object
17823 if (is_null())
17824 {
17825 m_type = value_t::object;
17826 m_value = value_t::object;
17827 assert_invariant();
17828 }
17829
17830 // add element to array (perfect forwarding)
17831 auto res = m_value.object->emplace(std::forward<Args>(args)...);
17832 // create result iterator and set iterator to the result of emplace
17833 auto it = begin();
17834 it.m_it.object_iterator = res.first;
17835
17836 // return pair of iterator and boolean
17837 return {it, res.second};
17838 }
17839
17840 /// Helper for insertion of an iterator
17841 /// @note: This uses std::distance to support GCC 4.8,
17842 /// see https://github.com/nlohmann/json/pull/1257
17843 template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)17844 iterator insert_iterator(const_iterator pos, Args&& ... args)
17845 {
17846 iterator result(this);
17847 assert(m_value.array != nullptr);
17848
17849 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
17850 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
17851 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
17852
17853 // This could have been written as:
17854 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
17855 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
17856
17857 return result;
17858 }
17859
17860 /*!
17861 @brief inserts element
17862
17863 Inserts element @a val before iterator @a pos.
17864
17865 @param[in] pos iterator before which the content will be inserted; may be
17866 the end() iterator
17867 @param[in] val element to insert
17868 @return iterator pointing to the inserted @a val.
17869
17870 @throw type_error.309 if called on JSON values other than arrays;
17871 example: `"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 Constant plus linear in the distance between @a pos and end of
17876 the container.
17877
17878 @liveexample{The example shows how `insert()` is used.,insert}
17879
17880 @since version 1.0.0
17881 */
insert(const_iterator pos,const basic_json & val)17882 iterator insert(const_iterator pos, 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, val);
17895 }
17896
17897 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17898 }
17899
17900 /*!
17901 @brief inserts element
17902 @copydoc insert(const_iterator, const basic_json&)
17903 */
insert(const_iterator pos,basic_json && val)17904 iterator insert(const_iterator pos, basic_json&& val)
17905 {
17906 return insert(pos, val);
17907 }
17908
17909 /*!
17910 @brief inserts elements
17911
17912 Inserts @a cnt copies of @a val before iterator @a pos.
17913
17914 @param[in] pos iterator before which the content will be inserted; may be
17915 the end() iterator
17916 @param[in] cnt number of copies of @a val to insert
17917 @param[in] val element to insert
17918 @return iterator pointing to the first element inserted, or @a pos if
17919 `cnt==0`
17920
17921 @throw type_error.309 if called on JSON values other than arrays; example:
17922 `"cannot use insert() with string"`
17923 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17924 example: `"iterator does not fit current value"`
17925
17926 @complexity Linear in @a cnt plus linear in the distance between @a pos
17927 and end of the container.
17928
17929 @liveexample{The example shows how `insert()` is used.,insert__count}
17930
17931 @since version 1.0.0
17932 */
insert(const_iterator pos,size_type cnt,const basic_json & val)17933 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
17934 {
17935 // insert only works for arrays
17936 if (JSON_LIKELY(is_array()))
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 // insert to array and return iterator
17945 return insert_iterator(pos, cnt, val);
17946 }
17947
17948 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17949 }
17950
17951 /*!
17952 @brief inserts elements
17953
17954 Inserts elements from range `[first, last)` before iterator @a pos.
17955
17956 @param[in] pos iterator before which the content will be inserted; may be
17957 the end() iterator
17958 @param[in] first begin of the range of elements to insert
17959 @param[in] last end of the range of elements to insert
17960
17961 @throw type_error.309 if called on JSON values other than arrays; example:
17962 `"cannot use insert() with string"`
17963 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
17964 example: `"iterator does not fit current value"`
17965 @throw invalid_iterator.210 if @a first and @a last do not belong to the
17966 same JSON value; example: `"iterators do not fit"`
17967 @throw invalid_iterator.211 if @a first or @a last are iterators into
17968 container for which insert is called; example: `"passed iterators may not
17969 belong to container"`
17970
17971 @return iterator pointing to the first element inserted, or @a pos if
17972 `first==last`
17973
17974 @complexity Linear in `std::distance(first, last)` plus linear in the
17975 distance between @a pos and end of the container.
17976
17977 @liveexample{The example shows how `insert()` is used.,insert__range}
17978
17979 @since version 1.0.0
17980 */
insert(const_iterator pos,const_iterator first,const_iterator last)17981 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
17982 {
17983 // insert only works for arrays
17984 if (JSON_UNLIKELY(not is_array()))
17985 {
17986 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
17987 }
17988
17989 // check if iterator pos fits to this JSON value
17990 if (JSON_UNLIKELY(pos.m_object != this))
17991 {
17992 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
17993 }
17994
17995 // check if range iterators belong to the same JSON object
17996 if (JSON_UNLIKELY(first.m_object != last.m_object))
17997 {
17998 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
17999 }
18000
18001 if (JSON_UNLIKELY(first.m_object == this))
18002 {
18003 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
18004 }
18005
18006 // insert to array and return iterator
18007 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
18008 }
18009
18010 /*!
18011 @brief inserts elements
18012
18013 Inserts elements from initializer list @a ilist before iterator @a pos.
18014
18015 @param[in] pos iterator before which the content will be inserted; may be
18016 the end() iterator
18017 @param[in] ilist initializer list to insert the values from
18018
18019 @throw type_error.309 if called on JSON values other than arrays; example:
18020 `"cannot use insert() with string"`
18021 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
18022 example: `"iterator does not fit current value"`
18023
18024 @return iterator pointing to the first element inserted, or @a pos if
18025 `ilist` is empty
18026
18027 @complexity Linear in `ilist.size()` plus linear in the distance between
18028 @a pos and end of the container.
18029
18030 @liveexample{The example shows how `insert()` is used.,insert__ilist}
18031
18032 @since version 1.0.0
18033 */
insert(const_iterator pos,initializer_list_t ilist)18034 iterator insert(const_iterator pos, initializer_list_t ilist)
18035 {
18036 // insert only works for arrays
18037 if (JSON_UNLIKELY(not is_array()))
18038 {
18039 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
18040 }
18041
18042 // check if iterator pos fits to this JSON value
18043 if (JSON_UNLIKELY(pos.m_object != this))
18044 {
18045 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
18046 }
18047
18048 // insert to array and return iterator
18049 return insert_iterator(pos, ilist.begin(), ilist.end());
18050 }
18051
18052 /*!
18053 @brief inserts elements
18054
18055 Inserts elements from range `[first, last)`.
18056
18057 @param[in] first begin of the range of elements to insert
18058 @param[in] last end of the range of elements to insert
18059
18060 @throw type_error.309 if called on JSON values other than objects; example:
18061 `"cannot use insert() with string"`
18062 @throw invalid_iterator.202 if iterator @a first or @a last does does not
18063 point to an object; example: `"iterators first and last must point to
18064 objects"`
18065 @throw invalid_iterator.210 if @a first and @a last do not belong to the
18066 same JSON value; example: `"iterators do not fit"`
18067
18068 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
18069 of elements to insert.
18070
18071 @liveexample{The example shows how `insert()` is used.,insert__range_object}
18072
18073 @since version 3.0.0
18074 */
insert(const_iterator first,const_iterator last)18075 void insert(const_iterator first, const_iterator last)
18076 {
18077 // insert only works for objects
18078 if (JSON_UNLIKELY(not is_object()))
18079 {
18080 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
18081 }
18082
18083 // check if range iterators belong to the same JSON object
18084 if (JSON_UNLIKELY(first.m_object != last.m_object))
18085 {
18086 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
18087 }
18088
18089 // passed iterators must belong to objects
18090 if (JSON_UNLIKELY(not first.m_object->is_object()))
18091 {
18092 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
18093 }
18094
18095 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
18096 }
18097
18098 /*!
18099 @brief updates a JSON object from another object, overwriting existing keys
18100
18101 Inserts all values from JSON object @a j and overwrites existing keys.
18102
18103 @param[in] j JSON object to read values from
18104
18105 @throw type_error.312 if called on JSON values other than objects; example:
18106 `"cannot use update() with string"`
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.,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_reference j)18117 void update(const_reference j)
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 if (JSON_UNLIKELY(not j.is_object()))
18132 {
18133 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
18134 }
18135
18136 for (auto it = j.cbegin(); it != j.cend(); ++it)
18137 {
18138 m_value.object->operator[](it.key()) = it.value();
18139 }
18140 }
18141
18142 /*!
18143 @brief updates a JSON object from another object, overwriting existing keys
18144
18145 Inserts all values from from range `[first, last)` and overwrites existing
18146 keys.
18147
18148 @param[in] first begin of the range of elements to insert
18149 @param[in] last end of the range of elements to insert
18150
18151 @throw type_error.312 if called on JSON values other than objects; example:
18152 `"cannot use update() with string"`
18153 @throw invalid_iterator.202 if iterator @a first or @a last does does not
18154 point to an object; example: `"iterators first and last must point to
18155 objects"`
18156 @throw invalid_iterator.210 if @a first and @a last do not belong to the
18157 same JSON value; example: `"iterators do not fit"`
18158
18159 @complexity O(N*log(size() + N)), where N is the number of elements to
18160 insert.
18161
18162 @liveexample{The example shows how `update()` is used__range.,update}
18163
18164 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
18165
18166 @since version 3.0.0
18167 */
update(const_iterator first,const_iterator last)18168 void update(const_iterator first, const_iterator last)
18169 {
18170 // implicitly convert null value to an empty object
18171 if (is_null())
18172 {
18173 m_type = value_t::object;
18174 m_value.object = create<object_t>();
18175 assert_invariant();
18176 }
18177
18178 if (JSON_UNLIKELY(not is_object()))
18179 {
18180 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
18181 }
18182
18183 // check if range iterators belong to the same JSON object
18184 if (JSON_UNLIKELY(first.m_object != last.m_object))
18185 {
18186 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
18187 }
18188
18189 // passed iterators must belong to objects
18190 if (JSON_UNLIKELY(not first.m_object->is_object()
18191 or not last.m_object->is_object()))
18192 {
18193 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
18194 }
18195
18196 for (auto it = first; it != last; ++it)
18197 {
18198 m_value.object->operator[](it.key()) = it.value();
18199 }
18200 }
18201
18202 /*!
18203 @brief exchanges the values
18204
18205 Exchanges the contents of the JSON value with those of @a other. Does not
18206 invoke any move, copy, or swap operations on individual elements. All
18207 iterators and references remain valid. The past-the-end iterator is
18208 invalidated.
18209
18210 @param[in,out] other JSON value to exchange the contents with
18211
18212 @complexity Constant.
18213
18214 @liveexample{The example below shows how JSON values can be swapped with
18215 `swap()`.,swap__reference}
18216
18217 @since version 1.0.0
18218 */
swap(reference other)18219 void swap(reference other) noexcept (
18220 std::is_nothrow_move_constructible<value_t>::value and
18221 std::is_nothrow_move_assignable<value_t>::value and
18222 std::is_nothrow_move_constructible<json_value>::value and
18223 std::is_nothrow_move_assignable<json_value>::value
18224 )
18225 {
18226 std::swap(m_type, other.m_type);
18227 std::swap(m_value, other.m_value);
18228 assert_invariant();
18229 }
18230
18231 /*!
18232 @brief exchanges the values
18233
18234 Exchanges the contents of a JSON array with those of @a other. Does not
18235 invoke any move, copy, or swap operations on individual elements. All
18236 iterators and references remain valid. The past-the-end iterator is
18237 invalidated.
18238
18239 @param[in,out] other array to exchange the contents with
18240
18241 @throw type_error.310 when JSON value is not an array; example: `"cannot
18242 use swap() with string"`
18243
18244 @complexity Constant.
18245
18246 @liveexample{The example below shows how arrays can be swapped with
18247 `swap()`.,swap__array_t}
18248
18249 @since version 1.0.0
18250 */
swap(array_t & other)18251 void swap(array_t& other)
18252 {
18253 // swap only works for arrays
18254 if (JSON_LIKELY(is_array()))
18255 {
18256 std::swap(*(m_value.array), other);
18257 }
18258 else
18259 {
18260 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18261 }
18262 }
18263
18264 /*!
18265 @brief exchanges the values
18266
18267 Exchanges the contents of a JSON object with those of @a other. Does not
18268 invoke any move, copy, or swap operations on individual elements. All
18269 iterators and references remain valid. The past-the-end iterator is
18270 invalidated.
18271
18272 @param[in,out] other object to exchange the contents with
18273
18274 @throw type_error.310 when JSON value is not an object; example:
18275 `"cannot use swap() with string"`
18276
18277 @complexity Constant.
18278
18279 @liveexample{The example below shows how objects can be swapped with
18280 `swap()`.,swap__object_t}
18281
18282 @since version 1.0.0
18283 */
swap(object_t & other)18284 void swap(object_t& other)
18285 {
18286 // swap only works for objects
18287 if (JSON_LIKELY(is_object()))
18288 {
18289 std::swap(*(m_value.object), other);
18290 }
18291 else
18292 {
18293 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18294 }
18295 }
18296
18297 /*!
18298 @brief exchanges the values
18299
18300 Exchanges the contents of a JSON string with those of @a other. Does not
18301 invoke any move, copy, or swap operations on individual elements. All
18302 iterators and references remain valid. The past-the-end iterator is
18303 invalidated.
18304
18305 @param[in,out] other string to exchange the contents with
18306
18307 @throw type_error.310 when JSON value is not a string; example: `"cannot
18308 use swap() with boolean"`
18309
18310 @complexity Constant.
18311
18312 @liveexample{The example below shows how strings can be swapped with
18313 `swap()`.,swap__string_t}
18314
18315 @since version 1.0.0
18316 */
swap(string_t & other)18317 void swap(string_t& other)
18318 {
18319 // swap only works for strings
18320 if (JSON_LIKELY(is_string()))
18321 {
18322 std::swap(*(m_value.string), other);
18323 }
18324 else
18325 {
18326 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
18327 }
18328 }
18329
18330 /// @}
18331
18332 public:
18333 //////////////////////////////////////////
18334 // lexicographical comparison operators //
18335 //////////////////////////////////////////
18336
18337 /// @name lexicographical comparison operators
18338 /// @{
18339
18340 /*!
18341 @brief comparison: equal
18342
18343 Compares two JSON values for equality according to the following rules:
18344 - Two JSON values are equal if (1) they are from the same type and (2)
18345 their stored values are the same according to their respective
18346 `operator==`.
18347 - Integer and floating-point numbers are automatically converted before
18348 comparison. Note than two NaN values are always treated as unequal.
18349 - Two JSON null values are equal.
18350
18351 @note Floating-point inside JSON values numbers are compared with
18352 `json::number_float_t::operator==` which is `double::operator==` by
18353 default. To compare floating-point while respecting an epsilon, an alternative
18354 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
18355 could be used, for instance
18356 @code {.cpp}
18357 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
18358 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
18359 {
18360 return std::abs(a - b) <= epsilon;
18361 }
18362 @endcode
18363
18364 @note NaN values never compare equal to themselves or to other NaN values.
18365
18366 @param[in] lhs first JSON value to consider
18367 @param[in] rhs second JSON value to consider
18368 @return whether the values @a lhs and @a rhs are equal
18369
18370 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18371
18372 @complexity Linear.
18373
18374 @liveexample{The example demonstrates comparing several JSON
18375 types.,operator__equal}
18376
18377 @since version 1.0.0
18378 */
operator ==(const_reference lhs,const_reference rhs)18379 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
18380 {
18381 const auto lhs_type = lhs.type();
18382 const auto rhs_type = rhs.type();
18383
18384 if (lhs_type == rhs_type)
18385 {
18386 switch (lhs_type)
18387 {
18388 case value_t::array:
18389 return *lhs.m_value.array == *rhs.m_value.array;
18390
18391 case value_t::object:
18392 return *lhs.m_value.object == *rhs.m_value.object;
18393
18394 case value_t::null:
18395 return true;
18396
18397 case value_t::string:
18398 return *lhs.m_value.string == *rhs.m_value.string;
18399
18400 case value_t::boolean:
18401 return lhs.m_value.boolean == rhs.m_value.boolean;
18402
18403 case value_t::number_integer:
18404 return lhs.m_value.number_integer == rhs.m_value.number_integer;
18405
18406 case value_t::number_unsigned:
18407 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
18408
18409 case value_t::number_float:
18410 return lhs.m_value.number_float == rhs.m_value.number_float;
18411
18412 default:
18413 return false;
18414 }
18415 }
18416 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18417 {
18418 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
18419 }
18420 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18421 {
18422 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
18423 }
18424 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18425 {
18426 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
18427 }
18428 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18429 {
18430 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
18431 }
18432 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18433 {
18434 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
18435 }
18436 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18437 {
18438 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18439 }
18440
18441 return false;
18442 }
18443
18444 /*!
18445 @brief comparison: equal
18446 @copydoc operator==(const_reference, const_reference)
18447 */
18448 template<typename ScalarType, typename std::enable_if<
18449 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)18450 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
18451 {
18452 return lhs == basic_json(rhs);
18453 }
18454
18455 /*!
18456 @brief comparison: equal
18457 @copydoc operator==(const_reference, const_reference)
18458 */
18459 template<typename ScalarType, typename std::enable_if<
18460 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)18461 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
18462 {
18463 return basic_json(lhs) == rhs;
18464 }
18465
18466 /*!
18467 @brief comparison: not equal
18468
18469 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
18470
18471 @param[in] lhs first JSON value to consider
18472 @param[in] rhs second JSON value to consider
18473 @return whether the values @a lhs and @a rhs are not equal
18474
18475 @complexity Linear.
18476
18477 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18478
18479 @liveexample{The example demonstrates comparing several JSON
18480 types.,operator__notequal}
18481
18482 @since version 1.0.0
18483 */
operator !=(const_reference lhs,const_reference rhs)18484 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
18485 {
18486 return not (lhs == rhs);
18487 }
18488
18489 /*!
18490 @brief comparison: not equal
18491 @copydoc operator!=(const_reference, const_reference)
18492 */
18493 template<typename ScalarType, typename std::enable_if<
18494 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)18495 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
18496 {
18497 return lhs != basic_json(rhs);
18498 }
18499
18500 /*!
18501 @brief comparison: not equal
18502 @copydoc operator!=(const_reference, const_reference)
18503 */
18504 template<typename ScalarType, typename std::enable_if<
18505 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)18506 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
18507 {
18508 return basic_json(lhs) != rhs;
18509 }
18510
18511 /*!
18512 @brief comparison: less than
18513
18514 Compares whether one JSON value @a lhs is less than another JSON value @a
18515 rhs according to the following rules:
18516 - If @a lhs and @a rhs have the same type, the values are compared using
18517 the default `<` operator.
18518 - Integer and floating-point numbers are automatically converted before
18519 comparison
18520 - In case @a lhs and @a rhs have different types, the values are ignored
18521 and the order of the types is considered, see
18522 @ref operator<(const value_t, const value_t).
18523
18524 @param[in] lhs first JSON value to consider
18525 @param[in] rhs second JSON value to consider
18526 @return whether @a lhs is less than @a rhs
18527
18528 @complexity Linear.
18529
18530 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18531
18532 @liveexample{The example demonstrates comparing several JSON
18533 types.,operator__less}
18534
18535 @since version 1.0.0
18536 */
operator <(const_reference lhs,const_reference rhs)18537 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
18538 {
18539 const auto lhs_type = lhs.type();
18540 const auto rhs_type = rhs.type();
18541
18542 if (lhs_type == rhs_type)
18543 {
18544 switch (lhs_type)
18545 {
18546 case value_t::array:
18547 // note parentheses are necessary, see
18548 // https://github.com/nlohmann/json/issues/1530
18549 return (*lhs.m_value.array) < (*rhs.m_value.array);
18550
18551 case value_t::object:
18552 return *lhs.m_value.object < *rhs.m_value.object;
18553
18554 case value_t::null:
18555 return false;
18556
18557 case value_t::string:
18558 return *lhs.m_value.string < *rhs.m_value.string;
18559
18560 case value_t::boolean:
18561 return lhs.m_value.boolean < rhs.m_value.boolean;
18562
18563 case value_t::number_integer:
18564 return lhs.m_value.number_integer < rhs.m_value.number_integer;
18565
18566 case value_t::number_unsigned:
18567 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
18568
18569 case value_t::number_float:
18570 return lhs.m_value.number_float < rhs.m_value.number_float;
18571
18572 default:
18573 return false;
18574 }
18575 }
18576 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
18577 {
18578 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
18579 }
18580 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
18581 {
18582 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
18583 }
18584 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
18585 {
18586 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
18587 }
18588 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
18589 {
18590 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
18591 }
18592 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
18593 {
18594 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
18595 }
18596 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
18597 {
18598 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
18599 }
18600
18601 // We only reach this line if we cannot compare values. In that case,
18602 // we compare types. Note we have to call the operator explicitly,
18603 // because MSVC has problems otherwise.
18604 return operator<(lhs_type, rhs_type);
18605 }
18606
18607 /*!
18608 @brief comparison: less than
18609 @copydoc operator<(const_reference, const_reference)
18610 */
18611 template<typename ScalarType, typename std::enable_if<
18612 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)18613 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
18614 {
18615 return lhs < basic_json(rhs);
18616 }
18617
18618 /*!
18619 @brief comparison: less than
18620 @copydoc operator<(const_reference, const_reference)
18621 */
18622 template<typename ScalarType, typename std::enable_if<
18623 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)18624 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
18625 {
18626 return basic_json(lhs) < rhs;
18627 }
18628
18629 /*!
18630 @brief comparison: less than or equal
18631
18632 Compares whether one JSON value @a lhs is less than or equal to another
18633 JSON value by calculating `not (rhs < lhs)`.
18634
18635 @param[in] lhs first JSON value to consider
18636 @param[in] rhs second JSON value to consider
18637 @return whether @a lhs is less than or equal to @a rhs
18638
18639 @complexity Linear.
18640
18641 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18642
18643 @liveexample{The example demonstrates comparing several JSON
18644 types.,operator__greater}
18645
18646 @since version 1.0.0
18647 */
operator <=(const_reference lhs,const_reference rhs)18648 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
18649 {
18650 return not (rhs < lhs);
18651 }
18652
18653 /*!
18654 @brief comparison: less than or equal
18655 @copydoc operator<=(const_reference, const_reference)
18656 */
18657 template<typename ScalarType, typename std::enable_if<
18658 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)18659 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
18660 {
18661 return lhs <= basic_json(rhs);
18662 }
18663
18664 /*!
18665 @brief comparison: less than or equal
18666 @copydoc operator<=(const_reference, const_reference)
18667 */
18668 template<typename ScalarType, typename std::enable_if<
18669 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)18670 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
18671 {
18672 return basic_json(lhs) <= rhs;
18673 }
18674
18675 /*!
18676 @brief comparison: greater than
18677
18678 Compares whether one JSON value @a lhs is greater than another
18679 JSON value by calculating `not (lhs <= rhs)`.
18680
18681 @param[in] lhs first JSON value to consider
18682 @param[in] rhs second JSON value to consider
18683 @return whether @a lhs is greater than to @a rhs
18684
18685 @complexity Linear.
18686
18687 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18688
18689 @liveexample{The example demonstrates comparing several JSON
18690 types.,operator__lessequal}
18691
18692 @since version 1.0.0
18693 */
operator >(const_reference lhs,const_reference rhs)18694 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
18695 {
18696 return not (lhs <= rhs);
18697 }
18698
18699 /*!
18700 @brief comparison: greater than
18701 @copydoc operator>(const_reference, const_reference)
18702 */
18703 template<typename ScalarType, typename std::enable_if<
18704 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)18705 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
18706 {
18707 return lhs > basic_json(rhs);
18708 }
18709
18710 /*!
18711 @brief comparison: greater than
18712 @copydoc operator>(const_reference, const_reference)
18713 */
18714 template<typename ScalarType, typename std::enable_if<
18715 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)18716 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
18717 {
18718 return basic_json(lhs) > rhs;
18719 }
18720
18721 /*!
18722 @brief comparison: greater than or equal
18723
18724 Compares whether one JSON value @a lhs is greater than or equal to another
18725 JSON value by calculating `not (lhs < rhs)`.
18726
18727 @param[in] lhs first JSON value to consider
18728 @param[in] rhs second JSON value to consider
18729 @return whether @a lhs is greater than or equal to @a rhs
18730
18731 @complexity Linear.
18732
18733 @exceptionsafety No-throw guarantee: this function never throws exceptions.
18734
18735 @liveexample{The example demonstrates comparing several JSON
18736 types.,operator__greaterequal}
18737
18738 @since version 1.0.0
18739 */
operator >=(const_reference lhs,const_reference rhs)18740 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
18741 {
18742 return not (lhs < rhs);
18743 }
18744
18745 /*!
18746 @brief comparison: greater than or equal
18747 @copydoc operator>=(const_reference, const_reference)
18748 */
18749 template<typename ScalarType, typename std::enable_if<
18750 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)18751 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
18752 {
18753 return lhs >= basic_json(rhs);
18754 }
18755
18756 /*!
18757 @brief comparison: greater than or equal
18758 @copydoc operator>=(const_reference, const_reference)
18759 */
18760 template<typename ScalarType, typename std::enable_if<
18761 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)18762 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
18763 {
18764 return basic_json(lhs) >= rhs;
18765 }
18766
18767 /// @}
18768
18769 ///////////////////
18770 // serialization //
18771 ///////////////////
18772
18773 /// @name serialization
18774 /// @{
18775
18776 /*!
18777 @brief serialize to stream
18778
18779 Serialize the given JSON value @a j to the output stream @a o. The JSON
18780 value will be serialized using the @ref dump member function.
18781
18782 - The indentation of the output can be controlled with the member variable
18783 `width` of the output stream @a o. For instance, using the manipulator
18784 `std::setw(4)` on @a o sets the indentation level to `4` and the
18785 serialization result is the same as calling `dump(4)`.
18786
18787 - The indentation character can be controlled with the member variable
18788 `fill` of the output stream @a o. For instance, the manipulator
18789 `std::setfill('\\t')` sets indentation to use a tab character rather than
18790 the default space character.
18791
18792 @param[in,out] o stream to serialize to
18793 @param[in] j JSON value to serialize
18794
18795 @return the stream @a o
18796
18797 @throw type_error.316 if a string stored inside the JSON value is not
18798 UTF-8 encoded
18799
18800 @complexity Linear.
18801
18802 @liveexample{The example below shows the serialization with different
18803 parameters to `width` to adjust the indentation level.,operator_serialize}
18804
18805 @since version 1.0.0; indentation character added in version 3.0.0
18806 */
operator <<(std::ostream & o,const basic_json & j)18807 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
18808 {
18809 // read width member and use it as indentation parameter if nonzero
18810 const bool pretty_print = o.width() > 0;
18811 const auto indentation = pretty_print ? o.width() : 0;
18812
18813 // reset width to 0 for subsequent calls to this stream
18814 o.width(0);
18815
18816 // do the actual serialization
18817 serializer s(detail::output_adapter<char>(o), o.fill());
18818 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
18819 return o;
18820 }
18821
18822 /*!
18823 @brief serialize to stream
18824 @deprecated This stream operator is deprecated and will be removed in
18825 future 4.0.0 of the library. Please use
18826 @ref operator<<(std::ostream&, const basic_json&)
18827 instead; that is, replace calls like `j >> o;` with `o << j;`.
18828 @since version 1.0.0; deprecated since version 3.0.0
18829 */
18830 JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)18831 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
18832 {
18833 return o << j;
18834 }
18835
18836 /// @}
18837
18838
18839 /////////////////////
18840 // deserialization //
18841 /////////////////////
18842
18843 /// @name deserialization
18844 /// @{
18845
18846 /*!
18847 @brief deserialize from a compatible input
18848
18849 This function reads from a compatible input. Examples are:
18850 - an array of 1-byte values
18851 - strings with character/literal type with size of 1 byte
18852 - input streams
18853 - container with contiguous storage of 1-byte values. Compatible container
18854 types include `std::vector`, `std::string`, `std::array`,
18855 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
18856 arrays can be used with `std::begin()`/`std::end()`. User-defined
18857 containers can be used as long as they implement random-access iterators
18858 and a contiguous storage.
18859
18860 @pre Each element of the container has a size of 1 byte. Violating this
18861 precondition yields undefined behavior. **This precondition is enforced
18862 with a static assertion.**
18863
18864 @pre The container storage is contiguous. Violating this precondition
18865 yields undefined behavior. **This precondition is enforced with an
18866 assertion.**
18867
18868 @warning There is no way to enforce all preconditions at compile-time. If
18869 the function is called with a noncompliant container and with
18870 assertions switched off, the behavior is undefined and will most
18871 likely yield segmentation violation.
18872
18873 @param[in] i input to read from
18874 @param[in] cb a parser callback function of type @ref parser_callback_t
18875 which is used to control the deserialization by filtering unwanted values
18876 (optional)
18877 @param[in] allow_exceptions whether to throw exceptions in case of a
18878 parse error (optional, true by default)
18879
18880 @return deserialized JSON value; in case of a parse error and
18881 @a allow_exceptions set to `false`, the return value will be
18882 value_t::discarded.
18883
18884 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
18885 of input; expected string literal""`
18886 @throw parse_error.102 if to_unicode fails or surrogate error
18887 @throw parse_error.103 if to_unicode fails
18888
18889 @complexity Linear in the length of the input. The parser is a predictive
18890 LL(1) parser. The complexity can be higher if the parser callback function
18891 @a cb has a super-linear complexity.
18892
18893 @note A UTF-8 byte order mark is silently ignored.
18894
18895 @liveexample{The example below demonstrates the `parse()` function reading
18896 from an array.,parse__array__parser_callback_t}
18897
18898 @liveexample{The example below demonstrates the `parse()` function with
18899 and without callback function.,parse__string__parser_callback_t}
18900
18901 @liveexample{The example below demonstrates the `parse()` function with
18902 and without callback function.,parse__istream__parser_callback_t}
18903
18904 @liveexample{The example below demonstrates the `parse()` function reading
18905 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
18906
18907 @since version 2.0.3 (contiguous containers)
18908 */
18909 JSON_NODISCARD
parse(detail::input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)18910 static basic_json parse(detail::input_adapter&& i,
18911 const parser_callback_t cb = nullptr,
18912 const bool allow_exceptions = true)
18913 {
18914 basic_json result;
18915 parser(i, cb, allow_exceptions).parse(true, result);
18916 return result;
18917 }
18918
accept(detail::input_adapter && i)18919 static bool accept(detail::input_adapter&& i)
18920 {
18921 return parser(i).accept(true);
18922 }
18923
18924 /*!
18925 @brief generate SAX events
18926
18927 The SAX event lister must follow the interface of @ref json_sax.
18928
18929 This function reads from a compatible input. Examples are:
18930 - an array of 1-byte values
18931 - strings with character/literal type with size of 1 byte
18932 - input streams
18933 - container with contiguous storage of 1-byte values. Compatible container
18934 types include `std::vector`, `std::string`, `std::array`,
18935 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
18936 arrays can be used with `std::begin()`/`std::end()`. User-defined
18937 containers can be used as long as they implement random-access iterators
18938 and a contiguous storage.
18939
18940 @pre Each element of the container has a size of 1 byte. Violating this
18941 precondition yields undefined behavior. **This precondition is enforced
18942 with a static assertion.**
18943
18944 @pre The container storage is contiguous. Violating this precondition
18945 yields undefined behavior. **This precondition is enforced with an
18946 assertion.**
18947
18948 @warning There is no way to enforce all preconditions at compile-time. If
18949 the function is called with a noncompliant container and with
18950 assertions switched off, the behavior is undefined and will most
18951 likely yield segmentation violation.
18952
18953 @param[in] i input to read from
18954 @param[in,out] sax SAX event listener
18955 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
18956 @param[in] strict whether the input has to be consumed completely
18957
18958 @return return value of the last processed SAX event
18959
18960 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
18961 of input; expected string literal""`
18962 @throw parse_error.102 if to_unicode fails or surrogate error
18963 @throw parse_error.103 if to_unicode fails
18964
18965 @complexity Linear in the length of the input. The parser is a predictive
18966 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
18967 a super-linear complexity.
18968
18969 @note A UTF-8 byte order mark is silently ignored.
18970
18971 @liveexample{The example below demonstrates the `sax_parse()` function
18972 reading from string and processing the events with a user-defined SAX
18973 event consumer.,sax_parse}
18974
18975 @since version 3.2.0
18976 */
18977 template <typename SAX>
sax_parse(detail::input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true)18978 static bool sax_parse(detail::input_adapter&& i, SAX* sax,
18979 input_format_t format = input_format_t::json,
18980 const bool strict = true)
18981 {
18982 assert(sax);
18983 return format == input_format_t::json
18984 ? parser(std::move(i)).sax_parse(sax, strict)
18985 : detail::binary_reader<basic_json, SAX>(std::move(i)).sax_parse(format, sax, strict);
18986 }
18987
18988 /*!
18989 @brief deserialize from an iterator range with contiguous storage
18990
18991 This function reads from an iterator range of a container with contiguous
18992 storage of 1-byte values. Compatible container types include
18993 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
18994 `std::initializer_list`. Furthermore, C-style arrays can be used with
18995 `std::begin()`/`std::end()`. User-defined containers can be used as long
18996 as they implement random-access iterators and a contiguous storage.
18997
18998 @pre The iterator range is contiguous. Violating this precondition yields
18999 undefined behavior. **This precondition is enforced with an assertion.**
19000 @pre Each element in the range has a size of 1 byte. Violating this
19001 precondition yields undefined behavior. **This precondition is enforced
19002 with a static assertion.**
19003
19004 @warning There is no way to enforce all preconditions at compile-time. If
19005 the function is called with noncompliant iterators and with
19006 assertions switched off, the behavior is undefined and will most
19007 likely yield segmentation violation.
19008
19009 @tparam IteratorType iterator of container with contiguous storage
19010 @param[in] first begin of the range to parse (included)
19011 @param[in] last end of the range to parse (excluded)
19012 @param[in] cb a parser callback function of type @ref parser_callback_t
19013 which is used to control the deserialization by filtering unwanted values
19014 (optional)
19015 @param[in] allow_exceptions whether to throw exceptions in case of a
19016 parse error (optional, true by default)
19017
19018 @return deserialized JSON value; in case of a parse error and
19019 @a allow_exceptions set to `false`, the return value will be
19020 value_t::discarded.
19021
19022 @throw parse_error.101 in case of an unexpected token
19023 @throw parse_error.102 if to_unicode fails or surrogate error
19024 @throw parse_error.103 if to_unicode fails
19025
19026 @complexity Linear in the length of the input. The parser is a predictive
19027 LL(1) parser. The complexity can be higher if the parser callback function
19028 @a cb has a super-linear complexity.
19029
19030 @note A UTF-8 byte order mark is silently ignored.
19031
19032 @liveexample{The example below demonstrates the `parse()` function reading
19033 from an iterator range.,parse__iteratortype__parser_callback_t}
19034
19035 @since version 2.0.3
19036 */
19037 template<class IteratorType, typename std::enable_if<
19038 std::is_base_of<
19039 std::random_access_iterator_tag,
19040 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)19041 static basic_json parse(IteratorType first, IteratorType last,
19042 const parser_callback_t cb = nullptr,
19043 const bool allow_exceptions = true)
19044 {
19045 basic_json result;
19046 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
19047 return result;
19048 }
19049
19050 template<class IteratorType, typename std::enable_if<
19051 std::is_base_of<
19052 std::random_access_iterator_tag,
19053 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)19054 static bool accept(IteratorType first, IteratorType last)
19055 {
19056 return parser(detail::input_adapter(first, last)).accept(true);
19057 }
19058
19059 template<class IteratorType, class SAX, typename std::enable_if<
19060 std::is_base_of<
19061 std::random_access_iterator_tag,
19062 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
sax_parse(IteratorType first,IteratorType last,SAX * sax)19063 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax)
19064 {
19065 return parser(detail::input_adapter(first, last)).sax_parse(sax);
19066 }
19067
19068 /*!
19069 @brief deserialize from stream
19070 @deprecated This stream operator is deprecated and will be removed in
19071 version 4.0.0 of the library. Please use
19072 @ref operator>>(std::istream&, basic_json&)
19073 instead; that is, replace calls like `j << i;` with `i >> j;`.
19074 @since version 1.0.0; deprecated since version 3.0.0
19075 */
19076 JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)19077 friend std::istream& operator<<(basic_json& j, std::istream& i)
19078 {
19079 return operator>>(i, j);
19080 }
19081
19082 /*!
19083 @brief deserialize from stream
19084
19085 Deserializes an input stream to a JSON value.
19086
19087 @param[in,out] i input stream to read a serialized JSON value from
19088 @param[in,out] j JSON value to write the deserialized input to
19089
19090 @throw parse_error.101 in case of an unexpected token
19091 @throw parse_error.102 if to_unicode fails or surrogate error
19092 @throw parse_error.103 if to_unicode fails
19093
19094 @complexity Linear in the length of the input. The parser is a predictive
19095 LL(1) parser.
19096
19097 @note A UTF-8 byte order mark is silently ignored.
19098
19099 @liveexample{The example below shows how a JSON value is constructed by
19100 reading a serialization from a stream.,operator_deserialize}
19101
19102 @sa parse(std::istream&, const parser_callback_t) for a variant with a
19103 parser callback function to filter values while parsing
19104
19105 @since version 1.0.0
19106 */
operator >>(std::istream & i,basic_json & j)19107 friend std::istream& operator>>(std::istream& i, basic_json& j)
19108 {
19109 parser(detail::input_adapter(i)).parse(false, j);
19110 return i;
19111 }
19112
19113 /// @}
19114
19115 ///////////////////////////
19116 // convenience functions //
19117 ///////////////////////////
19118
19119 /*!
19120 @brief return the type as string
19121
19122 Returns the type name as string to be used in error messages - usually to
19123 indicate that a function was called on a wrong JSON type.
19124
19125 @return a string representation of a the @a m_type member:
19126 Value type | return value
19127 ----------- | -------------
19128 null | `"null"`
19129 boolean | `"boolean"`
19130 string | `"string"`
19131 number | `"number"` (for all number types)
19132 object | `"object"`
19133 array | `"array"`
19134 discarded | `"discarded"`
19135
19136 @exceptionsafety No-throw guarantee: this function never throws exceptions.
19137
19138 @complexity Constant.
19139
19140 @liveexample{The following code exemplifies `type_name()` for all JSON
19141 types.,type_name}
19142
19143 @sa @ref type() -- return the type of the JSON value
19144 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
19145
19146 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
19147 since 3.0.0
19148 */
type_name() const19149 const char* type_name() const noexcept
19150 {
19151 {
19152 switch (m_type)
19153 {
19154 case value_t::null:
19155 return "null";
19156 case value_t::object:
19157 return "object";
19158 case value_t::array:
19159 return "array";
19160 case value_t::string:
19161 return "string";
19162 case value_t::boolean:
19163 return "boolean";
19164 case value_t::discarded:
19165 return "discarded";
19166 default:
19167 return "number";
19168 }
19169 }
19170 }
19171
19172
19173 private:
19174 //////////////////////
19175 // member variables //
19176 //////////////////////
19177
19178 /// the type of the current element
19179 value_t m_type = value_t::null;
19180
19181 /// the value of the current element
19182 json_value m_value = {};
19183
19184 //////////////////////////////////////////
19185 // binary serialization/deserialization //
19186 //////////////////////////////////////////
19187
19188 /// @name binary serialization/deserialization support
19189 /// @{
19190
19191 public:
19192 /*!
19193 @brief create a CBOR serialization of a given JSON value
19194
19195 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
19196 Binary Object Representation) serialization format. CBOR is a binary
19197 serialization format which aims to be more compact than JSON itself, yet
19198 more efficient to parse.
19199
19200 The library uses the following mapping from JSON values types to
19201 CBOR types according to the CBOR specification (RFC 7049):
19202
19203 JSON value type | value/range | CBOR type | first byte
19204 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
19205 null | `null` | Null | 0xF6
19206 boolean | `true` | True | 0xF5
19207 boolean | `false` | False | 0xF4
19208 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
19209 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
19210 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
19211 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
19212 number_integer | -24..-1 | Negative integer | 0x20..0x37
19213 number_integer | 0..23 | Integer | 0x00..0x17
19214 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
19215 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
19216 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
19217 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
19218 number_unsigned | 0..23 | Integer | 0x00..0x17
19219 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
19220 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
19221 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
19222 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
19223 number_float | *any value* | Double-Precision Float | 0xFB
19224 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
19225 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
19226 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
19227 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
19228 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
19229 array | *size*: 0..23 | array | 0x80..0x97
19230 array | *size*: 23..255 | array (1 byte follow) | 0x98
19231 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
19232 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
19233 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
19234 object | *size*: 0..23 | map | 0xA0..0xB7
19235 object | *size*: 23..255 | map (1 byte follow) | 0xB8
19236 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
19237 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
19238 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
19239
19240 @note The mapping is **complete** in the sense that any JSON value type
19241 can be converted to a CBOR value.
19242
19243 @note If NaN or Infinity are stored inside a JSON number, they are
19244 serialized properly. This behavior differs from the @ref dump()
19245 function which serializes NaN or Infinity to `null`.
19246
19247 @note The following CBOR types are not used in the conversion:
19248 - byte strings (0x40..0x5F)
19249 - UTF-8 strings terminated by "break" (0x7F)
19250 - arrays terminated by "break" (0x9F)
19251 - maps terminated by "break" (0xBF)
19252 - date/time (0xC0..0xC1)
19253 - bignum (0xC2..0xC3)
19254 - decimal fraction (0xC4)
19255 - bigfloat (0xC5)
19256 - tagged items (0xC6..0xD4, 0xD8..0xDB)
19257 - expected conversions (0xD5..0xD7)
19258 - simple values (0xE0..0xF3, 0xF8)
19259 - undefined (0xF7)
19260 - half and single-precision floats (0xF9-0xFA)
19261 - break (0xFF)
19262
19263 @param[in] j JSON value to serialize
19264 @return MessagePack serialization as byte vector
19265
19266 @complexity Linear in the size of the JSON value @a j.
19267
19268 @liveexample{The example shows the serialization of a JSON value to a byte
19269 vector in CBOR format.,to_cbor}
19270
19271 @sa http://cbor.io
19272 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19273 analogous deserialization
19274 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19275 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19276 related UBJSON format
19277
19278 @since version 2.0.9
19279 */
to_cbor(const basic_json & j)19280 static std::vector<uint8_t> to_cbor(const basic_json& j)
19281 {
19282 std::vector<uint8_t> result;
19283 to_cbor(j, result);
19284 return result;
19285 }
19286
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)19287 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
19288 {
19289 binary_writer<uint8_t>(o).write_cbor(j);
19290 }
19291
to_cbor(const basic_json & j,detail::output_adapter<char> o)19292 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
19293 {
19294 binary_writer<char>(o).write_cbor(j);
19295 }
19296
19297 /*!
19298 @brief create a MessagePack serialization of a given JSON value
19299
19300 Serializes a given JSON value @a j to a byte vector using the MessagePack
19301 serialization format. MessagePack is a binary serialization format which
19302 aims to be more compact than JSON itself, yet more efficient to parse.
19303
19304 The library uses the following mapping from JSON values types to
19305 MessagePack types according to the MessagePack specification:
19306
19307 JSON value type | value/range | MessagePack type | first byte
19308 --------------- | --------------------------------- | ---------------- | ----------
19309 null | `null` | nil | 0xC0
19310 boolean | `true` | true | 0xC3
19311 boolean | `false` | false | 0xC2
19312 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
19313 number_integer | -2147483648..-32769 | int32 | 0xD2
19314 number_integer | -32768..-129 | int16 | 0xD1
19315 number_integer | -128..-33 | int8 | 0xD0
19316 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
19317 number_integer | 0..127 | positive fixint | 0x00..0x7F
19318 number_integer | 128..255 | uint 8 | 0xCC
19319 number_integer | 256..65535 | uint 16 | 0xCD
19320 number_integer | 65536..4294967295 | uint 32 | 0xCE
19321 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
19322 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
19323 number_unsigned | 128..255 | uint 8 | 0xCC
19324 number_unsigned | 256..65535 | uint 16 | 0xCD
19325 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
19326 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
19327 number_float | *any value* | float 64 | 0xCB
19328 string | *length*: 0..31 | fixstr | 0xA0..0xBF
19329 string | *length*: 32..255 | str 8 | 0xD9
19330 string | *length*: 256..65535 | str 16 | 0xDA
19331 string | *length*: 65536..4294967295 | str 32 | 0xDB
19332 array | *size*: 0..15 | fixarray | 0x90..0x9F
19333 array | *size*: 16..65535 | array 16 | 0xDC
19334 array | *size*: 65536..4294967295 | array 32 | 0xDD
19335 object | *size*: 0..15 | fix map | 0x80..0x8F
19336 object | *size*: 16..65535 | map 16 | 0xDE
19337 object | *size*: 65536..4294967295 | map 32 | 0xDF
19338
19339 @note The mapping is **complete** in the sense that any JSON value type
19340 can be converted to a MessagePack value.
19341
19342 @note The following values can **not** be converted to a MessagePack value:
19343 - strings with more than 4294967295 bytes
19344 - arrays with more than 4294967295 elements
19345 - objects with more than 4294967295 elements
19346
19347 @note The following MessagePack types are not used in the conversion:
19348 - bin 8 - bin 32 (0xC4..0xC6)
19349 - ext 8 - ext 32 (0xC7..0xC9)
19350 - float 32 (0xCA)
19351 - fixext 1 - fixext 16 (0xD4..0xD8)
19352
19353 @note Any MessagePack output created @ref to_msgpack can be successfully
19354 parsed by @ref from_msgpack.
19355
19356 @note If NaN or Infinity are stored inside a JSON number, they are
19357 serialized properly. This behavior differs from the @ref dump()
19358 function which serializes NaN or Infinity to `null`.
19359
19360 @param[in] j JSON value to serialize
19361 @return MessagePack serialization as byte vector
19362
19363 @complexity Linear in the size of the JSON value @a j.
19364
19365 @liveexample{The example shows the serialization of a JSON value to a byte
19366 vector in MessagePack format.,to_msgpack}
19367
19368 @sa http://msgpack.org
19369 @sa @ref from_msgpack for the analogous deserialization
19370 @sa @ref to_cbor(const basic_json& for the related CBOR format
19371 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19372 related UBJSON format
19373
19374 @since version 2.0.9
19375 */
to_msgpack(const basic_json & j)19376 static std::vector<uint8_t> to_msgpack(const basic_json& j)
19377 {
19378 std::vector<uint8_t> result;
19379 to_msgpack(j, result);
19380 return result;
19381 }
19382
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)19383 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
19384 {
19385 binary_writer<uint8_t>(o).write_msgpack(j);
19386 }
19387
to_msgpack(const basic_json & j,detail::output_adapter<char> o)19388 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
19389 {
19390 binary_writer<char>(o).write_msgpack(j);
19391 }
19392
19393 /*!
19394 @brief create a UBJSON serialization of a given JSON value
19395
19396 Serializes a given JSON value @a j to a byte vector using the UBJSON
19397 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
19398 than JSON itself, yet more efficient to parse.
19399
19400 The library uses the following mapping from JSON values types to
19401 UBJSON types according to the UBJSON specification:
19402
19403 JSON value type | value/range | UBJSON type | marker
19404 --------------- | --------------------------------- | ----------- | ------
19405 null | `null` | null | `Z`
19406 boolean | `true` | true | `T`
19407 boolean | `false` | false | `F`
19408 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
19409 number_integer | -2147483648..-32769 | int32 | `l`
19410 number_integer | -32768..-129 | int16 | `I`
19411 number_integer | -128..127 | int8 | `i`
19412 number_integer | 128..255 | uint8 | `U`
19413 number_integer | 256..32767 | int16 | `I`
19414 number_integer | 32768..2147483647 | int32 | `l`
19415 number_integer | 2147483648..9223372036854775807 | int64 | `L`
19416 number_unsigned | 0..127 | int8 | `i`
19417 number_unsigned | 128..255 | uint8 | `U`
19418 number_unsigned | 256..32767 | int16 | `I`
19419 number_unsigned | 32768..2147483647 | int32 | `l`
19420 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
19421 number_float | *any value* | float64 | `D`
19422 string | *with shortest length indicator* | string | `S`
19423 array | *see notes on optimized format* | array | `[`
19424 object | *see notes on optimized format* | map | `{`
19425
19426 @note The mapping is **complete** in the sense that any JSON value type
19427 can be converted to a UBJSON value.
19428
19429 @note The following values can **not** be converted to a UBJSON value:
19430 - strings with more than 9223372036854775807 bytes (theoretical)
19431 - unsigned integer numbers above 9223372036854775807
19432
19433 @note The following markers are not used in the conversion:
19434 - `Z`: no-op values are not created.
19435 - `C`: single-byte strings are serialized with `S` markers.
19436
19437 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
19438 by @ref from_ubjson.
19439
19440 @note If NaN or Infinity are stored inside a JSON number, they are
19441 serialized properly. This behavior differs from the @ref dump()
19442 function which serializes NaN or Infinity to `null`.
19443
19444 @note The optimized formats for containers are supported: Parameter
19445 @a use_size adds size information to the beginning of a container and
19446 removes the closing marker. Parameter @a use_type further checks
19447 whether all elements of a container have the same type and adds the
19448 type marker to the beginning of the container. The @a use_type
19449 parameter must only be used together with @a use_size = true. Note
19450 that @a use_size = true alone may result in larger representations -
19451 the benefit of this parameter is that the receiving side is
19452 immediately informed on the number of elements of the container.
19453
19454 @param[in] j JSON value to serialize
19455 @param[in] use_size whether to add size annotations to container types
19456 @param[in] use_type whether to add type annotations to container types
19457 (must be combined with @a use_size = true)
19458 @return UBJSON serialization as byte vector
19459
19460 @complexity Linear in the size of the JSON value @a j.
19461
19462 @liveexample{The example shows the serialization of a JSON value to a byte
19463 vector in UBJSON format.,to_ubjson}
19464
19465 @sa http://ubjson.org
19466 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19467 analogous deserialization
19468 @sa @ref to_cbor(const basic_json& for the related CBOR format
19469 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19470
19471 @since version 3.1.0
19472 */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)19473 static std::vector<uint8_t> to_ubjson(const basic_json& j,
19474 const bool use_size = false,
19475 const bool use_type = false)
19476 {
19477 std::vector<uint8_t> result;
19478 to_ubjson(j, result, use_size, use_type);
19479 return result;
19480 }
19481
to_ubjson(const basic_json & j,detail::output_adapter<uint8_t> o,const bool use_size=false,const bool use_type=false)19482 static void to_ubjson(const basic_json& j, detail::output_adapter<uint8_t> o,
19483 const bool use_size = false, const bool use_type = false)
19484 {
19485 binary_writer<uint8_t>(o).write_ubjson(j, use_size, use_type);
19486 }
19487
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)19488 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
19489 const bool use_size = false, const bool use_type = false)
19490 {
19491 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
19492 }
19493
19494
19495 /*!
19496 @brief Serializes the given JSON object `j` to BSON and returns a vector
19497 containing the corresponding BSON-representation.
19498
19499 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
19500 stored as a single entity (a so-called document).
19501
19502 The library uses the following mapping from JSON values types to BSON types:
19503
19504 JSON value type | value/range | BSON type | marker
19505 --------------- | --------------------------------- | ----------- | ------
19506 null | `null` | null | 0x0A
19507 boolean | `true`, `false` | boolean | 0x08
19508 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
19509 number_integer | -2147483648..2147483647 | int32 | 0x10
19510 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
19511 number_unsigned | 0..2147483647 | int32 | 0x10
19512 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
19513 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
19514 number_float | *any value* | double | 0x01
19515 string | *any value* | string | 0x02
19516 array | *any value* | document | 0x04
19517 object | *any value* | document | 0x03
19518
19519 @warning The mapping is **incomplete**, since only JSON-objects (and things
19520 contained therein) can be serialized to BSON.
19521 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
19522 and the keys may not contain U+0000, since they are serialized a
19523 zero-terminated c-strings.
19524
19525 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
19526 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
19527 @throw type_error.317 if `!j.is_object()`
19528
19529 @pre The input `j` is required to be an object: `j.is_object() == true`.
19530
19531 @note Any BSON output created via @ref to_bson can be successfully parsed
19532 by @ref from_bson.
19533
19534 @param[in] j JSON value to serialize
19535 @return BSON serialization as byte vector
19536
19537 @complexity Linear in the size of the JSON value @a j.
19538
19539 @liveexample{The example shows the serialization of a JSON value to a byte
19540 vector in BSON format.,to_bson}
19541
19542 @sa http://bsonspec.org/spec.html
19543 @sa @ref from_bson(detail::input_adapter&&, const bool strict) for the
19544 analogous deserialization
19545 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19546 related UBJSON format
19547 @sa @ref to_cbor(const basic_json&) for the related CBOR format
19548 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
19549 */
to_bson(const basic_json & j)19550 static std::vector<uint8_t> to_bson(const basic_json& j)
19551 {
19552 std::vector<uint8_t> result;
19553 to_bson(j, result);
19554 return result;
19555 }
19556
19557 /*!
19558 @brief Serializes the given JSON object `j` to BSON and forwards the
19559 corresponding BSON-representation to the given output_adapter `o`.
19560 @param j The JSON object to convert to BSON.
19561 @param o The output adapter that receives the binary BSON representation.
19562 @pre The input `j` shall be an object: `j.is_object() == true`
19563 @sa @ref to_bson(const basic_json&)
19564 */
to_bson(const basic_json & j,detail::output_adapter<uint8_t> o)19565 static void to_bson(const basic_json& j, detail::output_adapter<uint8_t> o)
19566 {
19567 binary_writer<uint8_t>(o).write_bson(j);
19568 }
19569
19570 /*!
19571 @copydoc to_bson(const basic_json&, detail::output_adapter<uint8_t>)
19572 */
to_bson(const basic_json & j,detail::output_adapter<char> o)19573 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
19574 {
19575 binary_writer<char>(o).write_bson(j);
19576 }
19577
19578
19579 /*!
19580 @brief create a JSON value from an input in CBOR format
19581
19582 Deserializes a given input @a i to a JSON value using the CBOR (Concise
19583 Binary Object Representation) serialization format.
19584
19585 The library maps CBOR types to JSON value types as follows:
19586
19587 CBOR type | JSON value type | first byte
19588 ---------------------- | --------------- | ----------
19589 Integer | number_unsigned | 0x00..0x17
19590 Unsigned integer | number_unsigned | 0x18
19591 Unsigned integer | number_unsigned | 0x19
19592 Unsigned integer | number_unsigned | 0x1A
19593 Unsigned integer | number_unsigned | 0x1B
19594 Negative integer | number_integer | 0x20..0x37
19595 Negative integer | number_integer | 0x38
19596 Negative integer | number_integer | 0x39
19597 Negative integer | number_integer | 0x3A
19598 Negative integer | number_integer | 0x3B
19599 Negative integer | number_integer | 0x40..0x57
19600 UTF-8 string | string | 0x60..0x77
19601 UTF-8 string | string | 0x78
19602 UTF-8 string | string | 0x79
19603 UTF-8 string | string | 0x7A
19604 UTF-8 string | string | 0x7B
19605 UTF-8 string | string | 0x7F
19606 array | array | 0x80..0x97
19607 array | array | 0x98
19608 array | array | 0x99
19609 array | array | 0x9A
19610 array | array | 0x9B
19611 array | array | 0x9F
19612 map | object | 0xA0..0xB7
19613 map | object | 0xB8
19614 map | object | 0xB9
19615 map | object | 0xBA
19616 map | object | 0xBB
19617 map | object | 0xBF
19618 False | `false` | 0xF4
19619 True | `true` | 0xF5
19620 Null | `null` | 0xF6
19621 Half-Precision Float | number_float | 0xF9
19622 Single-Precision Float | number_float | 0xFA
19623 Double-Precision Float | number_float | 0xFB
19624
19625 @warning The mapping is **incomplete** in the sense that not all CBOR
19626 types can be converted to a JSON value. The following CBOR types
19627 are not supported and will yield parse errors (parse_error.112):
19628 - byte strings (0x40..0x5F)
19629 - date/time (0xC0..0xC1)
19630 - bignum (0xC2..0xC3)
19631 - decimal fraction (0xC4)
19632 - bigfloat (0xC5)
19633 - tagged items (0xC6..0xD4, 0xD8..0xDB)
19634 - expected conversions (0xD5..0xD7)
19635 - simple values (0xE0..0xF3, 0xF8)
19636 - undefined (0xF7)
19637
19638 @warning CBOR allows map keys of any type, whereas JSON only allows
19639 strings as keys in object values. Therefore, CBOR maps with keys
19640 other than UTF-8 strings are rejected (parse_error.113).
19641
19642 @note Any CBOR output created @ref to_cbor can be successfully parsed by
19643 @ref from_cbor.
19644
19645 @param[in] i an input in CBOR format convertible to an input adapter
19646 @param[in] strict whether to expect the input to be consumed until EOF
19647 (true by default)
19648 @param[in] allow_exceptions whether to throw exceptions in case of a
19649 parse error (optional, true by default)
19650
19651 @return deserialized JSON value; in case of a parse error and
19652 @a allow_exceptions set to `false`, the return value will be
19653 value_t::discarded.
19654
19655 @throw parse_error.110 if the given input ends prematurely or the end of
19656 file was not reached when @a strict was set to true
19657 @throw parse_error.112 if unsupported features from CBOR were
19658 used in the given input @a v or if the input is not valid CBOR
19659 @throw parse_error.113 if a string was expected as map key, but not found
19660
19661 @complexity Linear in the size of the input @a i.
19662
19663 @liveexample{The example shows the deserialization of a byte vector in CBOR
19664 format to a JSON value.,from_cbor}
19665
19666 @sa http://cbor.io
19667 @sa @ref to_cbor(const basic_json&) for the analogous serialization
19668 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for the
19669 related MessagePack format
19670 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19671 related UBJSON format
19672
19673 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
19674 consume input adapters, removed start_index parameter, and added
19675 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
19676 since 3.2.0
19677 */
19678 JSON_NODISCARD
from_cbor(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19679 static basic_json from_cbor(detail::input_adapter&& i,
19680 const bool strict = true,
19681 const bool allow_exceptions = true)
19682 {
19683 basic_json result;
19684 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19685 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::cbor, &sdp, strict);
19686 return res ? result : basic_json(value_t::discarded);
19687 }
19688
19689 /*!
19690 @copydoc from_cbor(detail::input_adapter&&, const bool, const bool)
19691 */
19692 template<typename A1, typename A2,
19693 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19694 JSON_NODISCARD
from_cbor(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19695 static basic_json from_cbor(A1 && a1, A2 && a2,
19696 const bool strict = true,
19697 const bool allow_exceptions = true)
19698 {
19699 basic_json result;
19700 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19701 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::cbor, &sdp, strict);
19702 return res ? result : basic_json(value_t::discarded);
19703 }
19704
19705 /*!
19706 @brief create a JSON value from an input in MessagePack format
19707
19708 Deserializes a given input @a i to a JSON value using the MessagePack
19709 serialization format.
19710
19711 The library maps MessagePack types to JSON value types as follows:
19712
19713 MessagePack type | JSON value type | first byte
19714 ---------------- | --------------- | ----------
19715 positive fixint | number_unsigned | 0x00..0x7F
19716 fixmap | object | 0x80..0x8F
19717 fixarray | array | 0x90..0x9F
19718 fixstr | string | 0xA0..0xBF
19719 nil | `null` | 0xC0
19720 false | `false` | 0xC2
19721 true | `true` | 0xC3
19722 float 32 | number_float | 0xCA
19723 float 64 | number_float | 0xCB
19724 uint 8 | number_unsigned | 0xCC
19725 uint 16 | number_unsigned | 0xCD
19726 uint 32 | number_unsigned | 0xCE
19727 uint 64 | number_unsigned | 0xCF
19728 int 8 | number_integer | 0xD0
19729 int 16 | number_integer | 0xD1
19730 int 32 | number_integer | 0xD2
19731 int 64 | number_integer | 0xD3
19732 str 8 | string | 0xD9
19733 str 16 | string | 0xDA
19734 str 32 | string | 0xDB
19735 array 16 | array | 0xDC
19736 array 32 | array | 0xDD
19737 map 16 | object | 0xDE
19738 map 32 | object | 0xDF
19739 negative fixint | number_integer | 0xE0-0xFF
19740
19741 @warning The mapping is **incomplete** in the sense that not all
19742 MessagePack types can be converted to a JSON value. The following
19743 MessagePack types are not supported and will yield parse errors:
19744 - bin 8 - bin 32 (0xC4..0xC6)
19745 - ext 8 - ext 32 (0xC7..0xC9)
19746 - fixext 1 - fixext 16 (0xD4..0xD8)
19747
19748 @note Any MessagePack output created @ref to_msgpack can be successfully
19749 parsed by @ref from_msgpack.
19750
19751 @param[in] i an input in MessagePack format convertible to an input
19752 adapter
19753 @param[in] strict whether to expect the input to be consumed until EOF
19754 (true by default)
19755 @param[in] allow_exceptions whether to throw exceptions in case of a
19756 parse error (optional, true by default)
19757
19758 @return deserialized JSON value; in case of a parse error and
19759 @a allow_exceptions set to `false`, the return value will be
19760 value_t::discarded.
19761
19762 @throw parse_error.110 if the given input ends prematurely or the end of
19763 file was not reached when @a strict was set to true
19764 @throw parse_error.112 if unsupported features from MessagePack were
19765 used in the given input @a i or if the input is not valid MessagePack
19766 @throw parse_error.113 if a string was expected as map key, but not found
19767
19768 @complexity Linear in the size of the input @a i.
19769
19770 @liveexample{The example shows the deserialization of a byte vector in
19771 MessagePack format to a JSON value.,from_msgpack}
19772
19773 @sa http://msgpack.org
19774 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
19775 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19776 related CBOR format
19777 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for
19778 the related UBJSON format
19779 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
19780 the related BSON format
19781
19782 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
19783 consume input adapters, removed start_index parameter, and added
19784 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
19785 since 3.2.0
19786 */
19787 JSON_NODISCARD
from_msgpack(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19788 static basic_json from_msgpack(detail::input_adapter&& i,
19789 const bool strict = true,
19790 const bool allow_exceptions = true)
19791 {
19792 basic_json result;
19793 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19794 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::msgpack, &sdp, strict);
19795 return res ? result : basic_json(value_t::discarded);
19796 }
19797
19798 /*!
19799 @copydoc from_msgpack(detail::input_adapter&&, const bool, const bool)
19800 */
19801 template<typename A1, typename A2,
19802 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19803 JSON_NODISCARD
from_msgpack(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19804 static basic_json from_msgpack(A1 && a1, A2 && a2,
19805 const bool strict = true,
19806 const bool allow_exceptions = true)
19807 {
19808 basic_json result;
19809 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19810 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::msgpack, &sdp, strict);
19811 return res ? result : basic_json(value_t::discarded);
19812 }
19813
19814 /*!
19815 @brief create a JSON value from an input in UBJSON format
19816
19817 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
19818 Binary JSON) serialization format.
19819
19820 The library maps UBJSON types to JSON value types as follows:
19821
19822 UBJSON type | JSON value type | marker
19823 ----------- | --------------------------------------- | ------
19824 no-op | *no value, next value is read* | `N`
19825 null | `null` | `Z`
19826 false | `false` | `F`
19827 true | `true` | `T`
19828 float32 | number_float | `d`
19829 float64 | number_float | `D`
19830 uint8 | number_unsigned | `U`
19831 int8 | number_integer | `i`
19832 int16 | number_integer | `I`
19833 int32 | number_integer | `l`
19834 int64 | number_integer | `L`
19835 string | string | `S`
19836 char | string | `C`
19837 array | array (optimized values are supported) | `[`
19838 object | object (optimized values are supported) | `{`
19839
19840 @note The mapping is **complete** in the sense that any UBJSON value can
19841 be converted to a JSON value.
19842
19843 @param[in] i an input in UBJSON format convertible to an input adapter
19844 @param[in] strict whether to expect the input to be consumed until EOF
19845 (true by default)
19846 @param[in] allow_exceptions whether to throw exceptions in case of a
19847 parse error (optional, true by default)
19848
19849 @return deserialized JSON value; in case of a parse error and
19850 @a allow_exceptions set to `false`, the return value will be
19851 value_t::discarded.
19852
19853 @throw parse_error.110 if the given input ends prematurely or the end of
19854 file was not reached when @a strict was set to true
19855 @throw parse_error.112 if a parse error occurs
19856 @throw parse_error.113 if a string could not be parsed successfully
19857
19858 @complexity Linear in the size of the input @a i.
19859
19860 @liveexample{The example shows the deserialization of a byte vector in
19861 UBJSON format to a JSON value.,from_ubjson}
19862
19863 @sa http://ubjson.org
19864 @sa @ref to_ubjson(const basic_json&, const bool, const bool) for the
19865 analogous serialization
19866 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19867 related CBOR format
19868 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
19869 the related MessagePack format
19870 @sa @ref from_bson(detail::input_adapter&&, const bool, const bool) for
19871 the related BSON format
19872
19873 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
19874 */
19875 JSON_NODISCARD
from_ubjson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19876 static basic_json from_ubjson(detail::input_adapter&& i,
19877 const bool strict = true,
19878 const bool allow_exceptions = true)
19879 {
19880 basic_json result;
19881 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19882 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::ubjson, &sdp, strict);
19883 return res ? result : basic_json(value_t::discarded);
19884 }
19885
19886 /*!
19887 @copydoc from_ubjson(detail::input_adapter&&, const bool, const bool)
19888 */
19889 template<typename A1, typename A2,
19890 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19891 JSON_NODISCARD
from_ubjson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19892 static basic_json from_ubjson(A1 && a1, A2 && a2,
19893 const bool strict = true,
19894 const bool allow_exceptions = true)
19895 {
19896 basic_json result;
19897 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19898 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::ubjson, &sdp, strict);
19899 return res ? result : basic_json(value_t::discarded);
19900 }
19901
19902 /*!
19903 @brief Create a JSON value from an input in BSON format
19904
19905 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
19906 serialization format.
19907
19908 The library maps BSON record types to JSON value types as follows:
19909
19910 BSON type | BSON marker byte | JSON value type
19911 --------------- | ---------------- | ---------------------------
19912 double | 0x01 | number_float
19913 string | 0x02 | string
19914 document | 0x03 | object
19915 array | 0x04 | array
19916 binary | 0x05 | still unsupported
19917 undefined | 0x06 | still unsupported
19918 ObjectId | 0x07 | still unsupported
19919 boolean | 0x08 | boolean
19920 UTC Date-Time | 0x09 | still unsupported
19921 null | 0x0A | null
19922 Regular Expr. | 0x0B | still unsupported
19923 DB Pointer | 0x0C | still unsupported
19924 JavaScript Code | 0x0D | still unsupported
19925 Symbol | 0x0E | still unsupported
19926 JavaScript Code | 0x0F | still unsupported
19927 int32 | 0x10 | number_integer
19928 Timestamp | 0x11 | still unsupported
19929 128-bit decimal float | 0x13 | still unsupported
19930 Max Key | 0x7F | still unsupported
19931 Min Key | 0xFF | still unsupported
19932
19933 @warning The mapping is **incomplete**. The unsupported mappings
19934 are indicated in the table above.
19935
19936 @param[in] i an input in BSON format convertible to an input adapter
19937 @param[in] strict whether to expect the input to be consumed until EOF
19938 (true by default)
19939 @param[in] allow_exceptions whether to throw exceptions in case of a
19940 parse error (optional, true by default)
19941
19942 @return deserialized JSON value; in case of a parse error and
19943 @a allow_exceptions set to `false`, the return value will be
19944 value_t::discarded.
19945
19946 @throw parse_error.114 if an unsupported BSON record type is encountered
19947
19948 @complexity Linear in the size of the input @a i.
19949
19950 @liveexample{The example shows the deserialization of a byte vector in
19951 BSON format to a JSON value.,from_bson}
19952
19953 @sa http://bsonspec.org/spec.html
19954 @sa @ref to_bson(const basic_json&) for the analogous serialization
19955 @sa @ref from_cbor(detail::input_adapter&&, const bool, const bool) for the
19956 related CBOR format
19957 @sa @ref from_msgpack(detail::input_adapter&&, const bool, const bool) for
19958 the related MessagePack format
19959 @sa @ref from_ubjson(detail::input_adapter&&, const bool, const bool) for the
19960 related UBJSON format
19961 */
19962 JSON_NODISCARD
from_bson(detail::input_adapter && i,const bool strict=true,const bool allow_exceptions=true)19963 static basic_json from_bson(detail::input_adapter&& i,
19964 const bool strict = true,
19965 const bool allow_exceptions = true)
19966 {
19967 basic_json result;
19968 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19969 const bool res = binary_reader(detail::input_adapter(i)).sax_parse(input_format_t::bson, &sdp, strict);
19970 return res ? result : basic_json(value_t::discarded);
19971 }
19972
19973 /*!
19974 @copydoc from_bson(detail::input_adapter&&, const bool, const bool)
19975 */
19976 template<typename A1, typename A2,
19977 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
19978 JSON_NODISCARD
from_bson(A1 && a1,A2 && a2,const bool strict=true,const bool allow_exceptions=true)19979 static basic_json from_bson(A1 && a1, A2 && a2,
19980 const bool strict = true,
19981 const bool allow_exceptions = true)
19982 {
19983 basic_json result;
19984 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
19985 const bool res = binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).sax_parse(input_format_t::bson, &sdp, strict);
19986 return res ? result : basic_json(value_t::discarded);
19987 }
19988
19989
19990
19991 /// @}
19992
19993 //////////////////////////
19994 // JSON Pointer support //
19995 //////////////////////////
19996
19997 /// @name JSON Pointer functions
19998 /// @{
19999
20000 /*!
20001 @brief access specified element via JSON Pointer
20002
20003 Uses a JSON pointer to retrieve a reference to the respective JSON value.
20004 No bound checking is performed. Similar to @ref operator[](const typename
20005 object_t::key_type&), `null` values are created in arrays and objects if
20006 necessary.
20007
20008 In particular:
20009 - If the JSON pointer points to an object key that does not exist, it
20010 is created an filled with a `null` value before a reference to it
20011 is returned.
20012 - If the JSON pointer points to an array index that does not exist, it
20013 is created an filled with a `null` value before a reference to it
20014 is returned. All indices between the current maximum and the given
20015 index are also filled with `null`.
20016 - The special value `-` is treated as a synonym for the index past the
20017 end.
20018
20019 @param[in] ptr a JSON pointer
20020
20021 @return reference to the element pointed to by @a ptr
20022
20023 @complexity Constant.
20024
20025 @throw parse_error.106 if an array index begins with '0'
20026 @throw parse_error.109 if an array index was not a number
20027 @throw out_of_range.404 if the JSON pointer can not be resolved
20028
20029 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
20030
20031 @since version 2.0.0
20032 */
operator [](const json_pointer & ptr)20033 reference operator[](const json_pointer& ptr)
20034 {
20035 return ptr.get_unchecked(this);
20036 }
20037
20038 /*!
20039 @brief access specified element via JSON Pointer
20040
20041 Uses a JSON pointer to retrieve a reference to the respective JSON value.
20042 No bound checking is performed. The function does not change the JSON
20043 value; no `null` values are created. In particular, the the special value
20044 `-` yields an exception.
20045
20046 @param[in] ptr JSON pointer to the desired element
20047
20048 @return const reference to the element pointed to by @a ptr
20049
20050 @complexity Constant.
20051
20052 @throw parse_error.106 if an array index begins with '0'
20053 @throw parse_error.109 if an array index was not a number
20054 @throw out_of_range.402 if the array index '-' is used
20055 @throw out_of_range.404 if the JSON pointer can not be resolved
20056
20057 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
20058
20059 @since version 2.0.0
20060 */
operator [](const json_pointer & ptr) const20061 const_reference operator[](const json_pointer& ptr) const
20062 {
20063 return ptr.get_unchecked(this);
20064 }
20065
20066 /*!
20067 @brief access specified element via JSON Pointer
20068
20069 Returns a reference to the element at with specified JSON pointer @a ptr,
20070 with bounds checking.
20071
20072 @param[in] ptr JSON pointer to the desired element
20073
20074 @return reference to the element pointed to by @a ptr
20075
20076 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
20077 begins with '0'. See example below.
20078
20079 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
20080 is not a number. See example below.
20081
20082 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
20083 is out of range. See example below.
20084
20085 @throw out_of_range.402 if the array index '-' is used in the passed JSON
20086 pointer @a ptr. As `at` provides checked access (and no elements are
20087 implicitly inserted), the index '-' is always invalid. See example below.
20088
20089 @throw out_of_range.403 if the JSON pointer describes a key of an object
20090 which cannot be found. See example below.
20091
20092 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
20093 See example below.
20094
20095 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20096 changes in the JSON value.
20097
20098 @complexity Constant.
20099
20100 @since version 2.0.0
20101
20102 @liveexample{The behavior is shown in the example.,at_json_pointer}
20103 */
at(const json_pointer & ptr)20104 reference at(const json_pointer& ptr)
20105 {
20106 return ptr.get_checked(this);
20107 }
20108
20109 /*!
20110 @brief access specified element via JSON Pointer
20111
20112 Returns a const reference to the element at with specified JSON pointer @a
20113 ptr, with bounds checking.
20114
20115 @param[in] ptr JSON pointer to the desired element
20116
20117 @return reference to the element pointed to by @a ptr
20118
20119 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
20120 begins with '0'. See example below.
20121
20122 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
20123 is not a number. See example below.
20124
20125 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
20126 is out of range. See example below.
20127
20128 @throw out_of_range.402 if the array index '-' is used in the passed JSON
20129 pointer @a ptr. As `at` provides checked access (and no elements are
20130 implicitly inserted), the index '-' is always invalid. See example below.
20131
20132 @throw out_of_range.403 if the JSON pointer describes a key of an object
20133 which cannot be found. See example below.
20134
20135 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
20136 See example below.
20137
20138 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20139 changes in the JSON value.
20140
20141 @complexity Constant.
20142
20143 @since version 2.0.0
20144
20145 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
20146 */
at(const json_pointer & ptr) const20147 const_reference at(const json_pointer& ptr) const
20148 {
20149 return ptr.get_checked(this);
20150 }
20151
20152 /*!
20153 @brief return flattened JSON value
20154
20155 The function creates a JSON object whose keys are JSON pointers (see [RFC
20156 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
20157 primitive. The original JSON value can be restored using the @ref
20158 unflatten() function.
20159
20160 @return an object that maps JSON pointers to primitive values
20161
20162 @note Empty objects and arrays are flattened to `null` and will not be
20163 reconstructed correctly by the @ref unflatten() function.
20164
20165 @complexity Linear in the size the JSON value.
20166
20167 @liveexample{The following code shows how a JSON object is flattened to an
20168 object whose keys consist of JSON pointers.,flatten}
20169
20170 @sa @ref unflatten() for the reverse function
20171
20172 @since version 2.0.0
20173 */
flatten() const20174 basic_json flatten() const
20175 {
20176 basic_json result(value_t::object);
20177 json_pointer::flatten("", *this, result);
20178 return result;
20179 }
20180
20181 /*!
20182 @brief unflatten a previously flattened JSON value
20183
20184 The function restores the arbitrary nesting of a JSON value that has been
20185 flattened before using the @ref flatten() function. The JSON value must
20186 meet certain constraints:
20187 1. The value must be an object.
20188 2. The keys must be JSON pointers (see
20189 [RFC 6901](https://tools.ietf.org/html/rfc6901))
20190 3. The mapped values must be primitive JSON types.
20191
20192 @return the original JSON from a flattened version
20193
20194 @note Empty objects and arrays are flattened by @ref flatten() to `null`
20195 values and can not unflattened to their original type. Apart from
20196 this example, for a JSON value `j`, the following is always true:
20197 `j == j.flatten().unflatten()`.
20198
20199 @complexity Linear in the size the JSON value.
20200
20201 @throw type_error.314 if value is not an object
20202 @throw type_error.315 if object values are not primitive
20203
20204 @liveexample{The following code shows how a flattened JSON object is
20205 unflattened into the original nested JSON object.,unflatten}
20206
20207 @sa @ref flatten() for the reverse function
20208
20209 @since version 2.0.0
20210 */
unflatten() const20211 basic_json unflatten() const
20212 {
20213 return json_pointer::unflatten(*this);
20214 }
20215
20216 /// @}
20217
20218 //////////////////////////
20219 // JSON Patch functions //
20220 //////////////////////////
20221
20222 /// @name JSON Patch functions
20223 /// @{
20224
20225 /*!
20226 @brief applies a JSON patch
20227
20228 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
20229 expressing a sequence of operations to apply to a JSON) document. With
20230 this function, a JSON Patch is applied to the current JSON value by
20231 executing all operations from the patch.
20232
20233 @param[in] json_patch JSON patch document
20234 @return patched document
20235
20236 @note The application of a patch is atomic: Either all operations succeed
20237 and the patched document is returned or an exception is thrown. In
20238 any case, the original value is not changed: the patch is applied
20239 to a copy of the value.
20240
20241 @throw parse_error.104 if the JSON patch does not consist of an array of
20242 objects
20243
20244 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
20245 attributes are missing); example: `"operation add must have member path"`
20246
20247 @throw out_of_range.401 if an array index is out of range.
20248
20249 @throw out_of_range.403 if a JSON pointer inside the patch could not be
20250 resolved successfully in the current JSON value; example: `"key baz not
20251 found"`
20252
20253 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
20254 "move")
20255
20256 @throw other_error.501 if "test" operation was unsuccessful
20257
20258 @complexity Linear in the size of the JSON value and the length of the
20259 JSON patch. As usually only a fraction of the JSON value is affected by
20260 the patch, the complexity can usually be neglected.
20261
20262 @liveexample{The following code shows how a JSON patch is applied to a
20263 value.,patch}
20264
20265 @sa @ref diff -- create a JSON patch by comparing two JSON values
20266
20267 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
20268 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
20269
20270 @since version 2.0.0
20271 */
patch(const basic_json & json_patch) const20272 basic_json patch(const basic_json& json_patch) const
20273 {
20274 // make a working copy to apply the patch to
20275 basic_json result = *this;
20276
20277 // the valid JSON Patch operations
20278 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
20279
20280 const auto get_op = [](const std::string & op)
20281 {
20282 if (op == "add")
20283 {
20284 return patch_operations::add;
20285 }
20286 if (op == "remove")
20287 {
20288 return patch_operations::remove;
20289 }
20290 if (op == "replace")
20291 {
20292 return patch_operations::replace;
20293 }
20294 if (op == "move")
20295 {
20296 return patch_operations::move;
20297 }
20298 if (op == "copy")
20299 {
20300 return patch_operations::copy;
20301 }
20302 if (op == "test")
20303 {
20304 return patch_operations::test;
20305 }
20306
20307 return patch_operations::invalid;
20308 };
20309
20310 // wrapper for "add" operation; add value at ptr
20311 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
20312 {
20313 // adding to the root of the target document means replacing it
20314 if (ptr.empty())
20315 {
20316 result = val;
20317 return;
20318 }
20319
20320 // make sure the top element of the pointer exists
20321 json_pointer top_pointer = ptr.top();
20322 if (top_pointer != ptr)
20323 {
20324 result.at(top_pointer);
20325 }
20326
20327 // get reference to parent of JSON pointer ptr
20328 const auto last_path = ptr.back();
20329 ptr.pop_back();
20330 basic_json& parent = result[ptr];
20331
20332 switch (parent.m_type)
20333 {
20334 case value_t::null:
20335 case value_t::object:
20336 {
20337 // use operator[] to add value
20338 parent[last_path] = val;
20339 break;
20340 }
20341
20342 case value_t::array:
20343 {
20344 if (last_path == "-")
20345 {
20346 // special case: append to back
20347 parent.push_back(val);
20348 }
20349 else
20350 {
20351 const auto idx = json_pointer::array_index(last_path);
20352 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
20353 {
20354 // avoid undefined behavior
20355 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
20356 }
20357
20358 // default case: insert add offset
20359 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
20360 }
20361 break;
20362 }
20363
20364 // if there exists a parent it cannot be primitive
20365 default: // LCOV_EXCL_LINE
20366 assert(false); // LCOV_EXCL_LINE
20367 }
20368 };
20369
20370 // wrapper for "remove" operation; remove value at ptr
20371 const auto operation_remove = [&result](json_pointer & ptr)
20372 {
20373 // get reference to parent of JSON pointer ptr
20374 const auto last_path = ptr.back();
20375 ptr.pop_back();
20376 basic_json& parent = result.at(ptr);
20377
20378 // remove child
20379 if (parent.is_object())
20380 {
20381 // perform range check
20382 auto it = parent.find(last_path);
20383 if (JSON_LIKELY(it != parent.end()))
20384 {
20385 parent.erase(it);
20386 }
20387 else
20388 {
20389 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
20390 }
20391 }
20392 else if (parent.is_array())
20393 {
20394 // note erase performs range check
20395 parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
20396 }
20397 };
20398
20399 // type check: top level value must be an array
20400 if (JSON_UNLIKELY(not json_patch.is_array()))
20401 {
20402 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
20403 }
20404
20405 // iterate and apply the operations
20406 for (const auto& val : json_patch)
20407 {
20408 // wrapper to get a value for an operation
20409 const auto get_value = [&val](const std::string & op,
20410 const std::string & member,
20411 bool string_type) -> basic_json &
20412 {
20413 // find value
20414 auto it = val.m_value.object->find(member);
20415
20416 // context-sensitive error message
20417 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
20418
20419 // check if desired value is present
20420 if (JSON_UNLIKELY(it == val.m_value.object->end()))
20421 {
20422 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
20423 }
20424
20425 // check if result is of type string
20426 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
20427 {
20428 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
20429 }
20430
20431 // no error: return value
20432 return it->second;
20433 };
20434
20435 // type check: every element of the array must be an object
20436 if (JSON_UNLIKELY(not val.is_object()))
20437 {
20438 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
20439 }
20440
20441 // collect mandatory members
20442 const std::string op = get_value("op", "op", true);
20443 const std::string path = get_value(op, "path", true);
20444 json_pointer ptr(path);
20445
20446 switch (get_op(op))
20447 {
20448 case patch_operations::add:
20449 {
20450 operation_add(ptr, get_value("add", "value", false));
20451 break;
20452 }
20453
20454 case patch_operations::remove:
20455 {
20456 operation_remove(ptr);
20457 break;
20458 }
20459
20460 case patch_operations::replace:
20461 {
20462 // the "path" location must exist - use at()
20463 result.at(ptr) = get_value("replace", "value", false);
20464 break;
20465 }
20466
20467 case patch_operations::move:
20468 {
20469 const std::string from_path = get_value("move", "from", true);
20470 json_pointer from_ptr(from_path);
20471
20472 // the "from" location must exist - use at()
20473 basic_json v = result.at(from_ptr);
20474
20475 // The move operation is functionally identical to a
20476 // "remove" operation on the "from" location, followed
20477 // immediately by an "add" operation at the target
20478 // location with the value that was just removed.
20479 operation_remove(from_ptr);
20480 operation_add(ptr, v);
20481 break;
20482 }
20483
20484 case patch_operations::copy:
20485 {
20486 const std::string from_path = get_value("copy", "from", true);
20487 const json_pointer from_ptr(from_path);
20488
20489 // the "from" location must exist - use at()
20490 basic_json v = result.at(from_ptr);
20491
20492 // The copy is functionally identical to an "add"
20493 // operation at the target location using the value
20494 // specified in the "from" member.
20495 operation_add(ptr, v);
20496 break;
20497 }
20498
20499 case patch_operations::test:
20500 {
20501 bool success = false;
20502 JSON_TRY
20503 {
20504 // check if "value" matches the one at "path"
20505 // the "path" location must exist - use at()
20506 success = (result.at(ptr) == get_value("test", "value", false));
20507 }
20508 JSON_INTERNAL_CATCH (out_of_range&)
20509 {
20510 // ignore out of range errors: success remains false
20511 }
20512
20513 // throw an exception if test fails
20514 if (JSON_UNLIKELY(not success))
20515 {
20516 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
20517 }
20518
20519 break;
20520 }
20521
20522 default:
20523 {
20524 // op must be "add", "remove", "replace", "move", "copy", or
20525 // "test"
20526 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
20527 }
20528 }
20529 }
20530
20531 return result;
20532 }
20533
20534 /*!
20535 @brief creates a diff as a JSON patch
20536
20537 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
20538 be changed into the value @a target by calling @ref patch function.
20539
20540 @invariant For two JSON values @a source and @a target, the following code
20541 yields always `true`:
20542 @code {.cpp}
20543 source.patch(diff(source, target)) == target;
20544 @endcode
20545
20546 @note Currently, only `remove`, `add`, and `replace` operations are
20547 generated.
20548
20549 @param[in] source JSON value to compare from
20550 @param[in] target JSON value to compare against
20551 @param[in] path helper value to create JSON pointers
20552
20553 @return a JSON patch to convert the @a source to @a target
20554
20555 @complexity Linear in the lengths of @a source and @a target.
20556
20557 @liveexample{The following code shows how a JSON patch is created as a
20558 diff for two JSON values.,diff}
20559
20560 @sa @ref patch -- apply a JSON patch
20561 @sa @ref merge_patch -- apply a JSON Merge Patch
20562
20563 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
20564
20565 @since version 2.0.0
20566 */
20567 JSON_NODISCARD
diff(const basic_json & source,const basic_json & target,const std::string & path="")20568 static basic_json diff(const basic_json& source, const basic_json& target,
20569 const std::string& path = "")
20570 {
20571 // the patch
20572 basic_json result(value_t::array);
20573
20574 // if the values are the same, return empty patch
20575 if (source == target)
20576 {
20577 return result;
20578 }
20579
20580 if (source.type() != target.type())
20581 {
20582 // different types: replace value
20583 result.push_back(
20584 {
20585 {"op", "replace"}, {"path", path}, {"value", target}
20586 });
20587 return result;
20588 }
20589
20590 switch (source.type())
20591 {
20592 case value_t::array:
20593 {
20594 // first pass: traverse common elements
20595 std::size_t i = 0;
20596 while (i < source.size() and i < target.size())
20597 {
20598 // recursive call to compare array values at index i
20599 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
20600 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20601 ++i;
20602 }
20603
20604 // i now reached the end of at least one array
20605 // in a second pass, traverse the remaining elements
20606
20607 // remove my remaining elements
20608 const auto end_index = static_cast<difference_type>(result.size());
20609 while (i < source.size())
20610 {
20611 // add operations in reverse order to avoid invalid
20612 // indices
20613 result.insert(result.begin() + end_index, object(
20614 {
20615 {"op", "remove"},
20616 {"path", path + "/" + std::to_string(i)}
20617 }));
20618 ++i;
20619 }
20620
20621 // add other remaining elements
20622 while (i < target.size())
20623 {
20624 result.push_back(
20625 {
20626 {"op", "add"},
20627 {"path", path + "/" + std::to_string(i)},
20628 {"value", target[i]}
20629 });
20630 ++i;
20631 }
20632
20633 break;
20634 }
20635
20636 case value_t::object:
20637 {
20638 // first pass: traverse this object's elements
20639 for (auto it = source.cbegin(); it != source.cend(); ++it)
20640 {
20641 // escape the key name to be used in a JSON patch
20642 const auto key = json_pointer::escape(it.key());
20643
20644 if (target.find(it.key()) != target.end())
20645 {
20646 // recursive call to compare object values at key it
20647 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
20648 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
20649 }
20650 else
20651 {
20652 // found a key that is not in o -> remove it
20653 result.push_back(object(
20654 {
20655 {"op", "remove"}, {"path", path + "/" + key}
20656 }));
20657 }
20658 }
20659
20660 // second pass: traverse other object's elements
20661 for (auto it = target.cbegin(); it != target.cend(); ++it)
20662 {
20663 if (source.find(it.key()) == source.end())
20664 {
20665 // found a key that is not in this -> add it
20666 const auto key = json_pointer::escape(it.key());
20667 result.push_back(
20668 {
20669 {"op", "add"}, {"path", path + "/" + key},
20670 {"value", it.value()}
20671 });
20672 }
20673 }
20674
20675 break;
20676 }
20677
20678 default:
20679 {
20680 // both primitive type: replace value
20681 result.push_back(
20682 {
20683 {"op", "replace"}, {"path", path}, {"value", target}
20684 });
20685 break;
20686 }
20687 }
20688
20689 return result;
20690 }
20691
20692 /// @}
20693
20694 ////////////////////////////////
20695 // JSON Merge Patch functions //
20696 ////////////////////////////////
20697
20698 /// @name JSON Merge Patch functions
20699 /// @{
20700
20701 /*!
20702 @brief applies a JSON Merge Patch
20703
20704 The merge patch format is primarily intended for use with the HTTP PATCH
20705 method as a means of describing a set of modifications to a target
20706 resource's content. This function applies a merge patch to the current
20707 JSON value.
20708
20709 The function implements the following algorithm from Section 2 of
20710 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
20711
20712 ```
20713 define MergePatch(Target, Patch):
20714 if Patch is an Object:
20715 if Target is not an Object:
20716 Target = {} // Ignore the contents and set it to an empty Object
20717 for each Name/Value pair in Patch:
20718 if Value is null:
20719 if Name exists in Target:
20720 remove the Name/Value pair from Target
20721 else:
20722 Target[Name] = MergePatch(Target[Name], Value)
20723 return Target
20724 else:
20725 return Patch
20726 ```
20727
20728 Thereby, `Target` is the current object; that is, the patch is applied to
20729 the current value.
20730
20731 @param[in] apply_patch the patch to apply
20732
20733 @complexity Linear in the lengths of @a patch.
20734
20735 @liveexample{The following code shows how a JSON Merge Patch is applied to
20736 a JSON document.,merge_patch}
20737
20738 @sa @ref patch -- apply a JSON patch
20739 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
20740
20741 @since version 3.0.0
20742 */
merge_patch(const basic_json & apply_patch)20743 void merge_patch(const basic_json& apply_patch)
20744 {
20745 if (apply_patch.is_object())
20746 {
20747 if (not is_object())
20748 {
20749 *this = object();
20750 }
20751 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
20752 {
20753 if (it.value().is_null())
20754 {
20755 erase(it.key());
20756 }
20757 else
20758 {
20759 operator[](it.key()).merge_patch(it.value());
20760 }
20761 }
20762 }
20763 else
20764 {
20765 *this = apply_patch;
20766 }
20767 }
20768
20769 /// @}
20770 };
20771 } // namespace nlohmann
20772
20773 ///////////////////////
20774 // nonmember support //
20775 ///////////////////////
20776
20777 // specialization of std::swap, and std::hash
20778 namespace std
20779 {
20780
20781 /// hash value for JSON objects
20782 template<>
20783 struct hash<nlohmann::json>
20784 {
20785 /*!
20786 @brief return a hash value for a JSON object
20787
20788 @since version 1.0.0
20789 */
operator ()std::hash20790 std::size_t operator()(const nlohmann::json& j) const
20791 {
20792 // a naive hashing via the string representation
20793 const auto& h = hash<nlohmann::json::string_t>();
20794 return h(j.dump());
20795 }
20796 };
20797
20798 /// specialization for std::less<value_t>
20799 /// @note: do not remove the space after '<',
20800 /// see https://github.com/nlohmann/json/pull/679
20801 template<>
20802 struct less< ::nlohmann::detail::value_t>
20803 {
20804 /*!
20805 @brief compare two value_t enum values
20806 @since version 3.0.0
20807 */
operator ()std::less20808 bool operator()(nlohmann::detail::value_t lhs,
20809 nlohmann::detail::value_t rhs) const noexcept
20810 {
20811 return nlohmann::detail::operator<(lhs, rhs);
20812 }
20813 };
20814
20815 /*!
20816 @brief exchanges the values of two JSON objects
20817
20818 @since version 1.0.0
20819 */
20820 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)20821 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept(
20822 is_nothrow_move_constructible<nlohmann::json>::value and
20823 is_nothrow_move_assignable<nlohmann::json>::value
20824 )
20825 {
20826 j1.swap(j2);
20827 }
20828
20829 } // namespace std
20830
20831 /*!
20832 @brief user-defined string literal for JSON values
20833
20834 This operator implements a user-defined string literal for JSON objects. It
20835 can be used by adding `"_json"` to a string literal and returns a JSON object
20836 if no parse error occurred.
20837
20838 @param[in] s a string representation of a JSON object
20839 @param[in] n the length of string @a s
20840 @return a JSON object
20841
20842 @since version 1.0.0
20843 */
operator ""_json(const char * s,std::size_t n)20844 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
20845 {
20846 return nlohmann::json::parse(s, s + n);
20847 }
20848
20849 /*!
20850 @brief user-defined string literal for JSON pointer
20851
20852 This operator implements a user-defined string literal for JSON Pointers. It
20853 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
20854 object if no parse error occurred.
20855
20856 @param[in] s a string representation of a JSON Pointer
20857 @param[in] n the length of string @a s
20858 @return a JSON pointer object
20859
20860 @since version 2.0.0
20861 */
operator ""_json_pointer(const char * s,std::size_t n)20862 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
20863 {
20864 return nlohmann::json::json_pointer(std::string(s, n));
20865 }
20866
20867 // #include <nlohmann/detail/macro_unscope.hpp>
20868
20869
20870 // restore GCC/clang diagnostic settings
20871 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
20872 #pragma GCC diagnostic pop
20873 #endif
20874 #if defined(__clang__)
20875 #pragma GCC diagnostic pop
20876 #endif
20877
20878 // clean up
20879 #undef JSON_INTERNAL_CATCH
20880 #undef JSON_CATCH
20881 #undef JSON_THROW
20882 #undef JSON_TRY
20883 #undef JSON_LIKELY
20884 #undef JSON_UNLIKELY
20885 #undef JSON_DEPRECATED
20886 #undef JSON_NODISCARD
20887 #undef JSON_HAS_CPP_14
20888 #undef JSON_HAS_CPP_17
20889 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
20890 #undef NLOHMANN_BASIC_JSON_TPL
20891
20892 #endif // INCLUDE_NLOHMANN_JSON_HPP_
20893
20894 namespace NL = nlohmann;
20895