1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 2.1.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 */
28
29 #ifndef NLOHMANN_JSON_HPP
30 #define NLOHMANN_JSON_HPP
31
32 #include <algorithm> // all_of, copy, fill, find, for_each, generate_n, none_of, remove, reverse, transform
33 #include <array> // array
34 #include <cassert> // assert
35 #include <ciso646> // and, not, or
36 #include <clocale> // lconv, localeconv
37 #include <cmath> // isfinite, labs, ldexp, signbit
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <cstdint> // int64_t, uint64_t
40 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
41 #include <cstring> // memcpy, strlen
42 #include <forward_list> // forward_list
43 #include <functional> // function, hash, less
44 #include <initializer_list> // initializer_list
45 #include <iomanip> // hex
46 #include <iosfwd> // istream, ostream
47 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
48 #include <limits> // numeric_limits
49 #include <locale> // locale
50 #include <map> // map
51 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
52 #include <numeric> // accumulate
53 #include <sstream> // stringstream
54 #include <string> // getline, stoi, string, to_string
55 #include <type_traits> // add_pointer, conditional, decay, enable_if, false_type, integral_constant, is_arithmetic, is_base_of, is_const, is_constructible, is_convertible, is_default_constructible, is_enum, is_floating_point, is_integral, is_nothrow_move_assignable, is_nothrow_move_constructible, is_pointer, is_reference, is_same, is_scalar, is_signed, remove_const, remove_cv, remove_pointer, remove_reference, true_type, underlying_type
56 #include <utility> // declval, forward, make_pair, move, pair, swap
57 #include <valarray> // valarray
58 #include <vector> // vector
59
60 // exclude unsupported compilers
61 #if defined(__clang__)
62 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
63 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
64 #endif
65 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
66 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
67 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
68 #endif
69 #endif
70
71 // disable float-equal warnings on GCC/clang
72 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
73 #pragma GCC diagnostic push
74 #pragma GCC diagnostic ignored "-Wfloat-equal"
75 #endif
76
77 // disable documentation warnings on clang
78 #if defined(__clang__)
79 #pragma GCC diagnostic push
80 #pragma GCC diagnostic ignored "-Wdocumentation"
81 #endif
82
83 // allow for portable deprecation warnings
84 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
85 #define JSON_DEPRECATED __attribute__((deprecated))
86 #elif defined(_MSC_VER)
87 #define JSON_DEPRECATED __declspec(deprecated)
88 #else
89 #define JSON_DEPRECATED
90 #endif
91
92 // allow to disable exceptions
93 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION)
94 #define JSON_THROW(exception) throw exception
95 #define JSON_TRY try
96 #define JSON_CATCH(exception) catch(exception)
97 #else
98 #define JSON_THROW(exception) std::abort()
99 #define JSON_TRY if(true)
100 #define JSON_CATCH(exception) if(false)
101 #endif
102
103 // manual branch prediction
104 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
105 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
106 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
107 #else
108 #define JSON_LIKELY(x) x
109 #define JSON_UNLIKELY(x) x
110 #endif
111
112 // cpp language standard detection
113 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
114 #define JSON_HAS_CPP_17
115 #define JSON_HAS_CPP_14
116 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
117 #define JSON_HAS_CPP_14
118 #endif
119
120 /*!
121 @brief namespace for Niels Lohmann
122 @see https://github.com/nlohmann
123 @since version 1.0.0
124 */
125 namespace nlohmann
126 {
127 template<typename = void, typename = void>
128 struct adl_serializer;
129
130 // forward declaration of basic_json (required to split the class)
131 template<template<typename U, typename V, typename... Args> class ObjectType =
132 std::map,
133 template<typename U, typename... Args> class ArrayType = std::vector,
134 class StringType = std::string, class BooleanType = bool,
135 class NumberIntegerType = std::int64_t,
136 class NumberUnsignedType = std::uint64_t,
137 class NumberFloatType = double,
138 template<typename U> class AllocatorType = std::allocator,
139 template<typename T, typename SFINAE = void> class JSONSerializer =
140 adl_serializer>
141 class basic_json;
142
143 // Ugly macros to avoid uglier copy-paste when specializing basic_json
144 // This is only temporary and will be removed in 3.0
145
146 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
147 template<template<typename, typename, typename...> class ObjectType, \
148 template<typename, typename...> class ArrayType, \
149 class StringType, class BooleanType, class NumberIntegerType, \
150 class NumberUnsignedType, class NumberFloatType, \
151 template<typename> class AllocatorType, \
152 template<typename, typename = void> class JSONSerializer>
153
154 #define NLOHMANN_BASIC_JSON_TPL \
155 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
156 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
157 AllocatorType, JSONSerializer>
158
159
160 /*!
161 @brief unnamed namespace with internal helper functions
162
163 This namespace collects some functions that could not be defined inside the
164 @ref basic_json class.
165
166 @since version 2.1.0
167 */
168 namespace detail
169 {
170 ////////////////
171 // exceptions //
172 ////////////////
173
174 /*!
175 @brief general exception of the @ref basic_json class
176
177 This class is an extension of `std::exception` objects with a member @a id for
178 exception ids. It is used as the base class for all exceptions thrown by the
179 @ref basic_json class. This class can hence be used as "wildcard" to catch
180 exceptions.
181
182 Subclasses:
183 - @ref parse_error for exceptions indicating a parse error
184 - @ref invalid_iterator for exceptions indicating errors with iterators
185 - @ref type_error for exceptions indicating executing a member function with
186 a wrong type
187 - @ref out_of_range for exceptions indicating access out of the defined range
188 - @ref other_error for exceptions indicating other library errors
189
190 @internal
191 @note To have nothrow-copy-constructible exceptions, we internally use
192 `std::runtime_error` which can cope with arbitrary-length error messages.
193 Intermediate strings are built with static functions and then passed to
194 the actual constructor.
195 @endinternal
196
197 @liveexample{The following code shows how arbitrary library exceptions can be
198 caught.,exception}
199
200 @since version 3.0.0
201 */
202 class exception : public std::exception
203 {
204 public:
205 /// returns the explanatory string
what() const206 const char* what() const noexcept override
207 {
208 return m.what();
209 }
210
211 /// the id of the exception
212 const int id;
213
214 protected:
exception(int id_,const char * what_arg)215 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
216
name(const std::string & ename,int id_)217 static std::string name(const std::string& ename, int id_)
218 {
219 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
220 }
221
222 private:
223 /// an exception object as storage for error messages
224 std::runtime_error m;
225 };
226
227 /*!
228 @brief exception indicating a parse error
229
230 This excpetion is thrown by the library when a parse error occurs. Parse errors
231 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
232 as when using JSON Patch.
233
234 Member @a byte holds the byte index of the last read character in the input
235 file.
236
237 Exceptions have ids 1xx.
238
239 name / id | example message | description
240 ------------------------------ | --------------- | -------------------------
241 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.
242 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.
243 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.
244 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.
245 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.
246 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 wihtout a leading `0`.
247 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.
248 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.
249 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
250 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.
251 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.
252 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.
253
254 @note For an input with n bytes, 1 is the index of the first character and n+1
255 is the index of the terminating null byte or the end of file. This also
256 holds true when reading a byte vector (CBOR or MessagePack).
257
258 @liveexample{The following code shows how a `parse_error` exception can be
259 caught.,parse_error}
260
261 @sa @ref exception for the base class of the library exceptions
262 @sa @ref invalid_iterator for exceptions indicating errors with iterators
263 @sa @ref type_error for exceptions indicating executing a member function with
264 a wrong type
265 @sa @ref out_of_range for exceptions indicating access out of the defined range
266 @sa @ref other_error for exceptions indicating other library errors
267
268 @since version 3.0.0
269 */
270 class parse_error : public exception
271 {
272 public:
273 /*!
274 @brief create a parse error exception
275 @param[in] id_ the id of the exception
276 @param[in] byte_ the byte index where the error occurred (or 0 if the
277 position cannot be determined)
278 @param[in] what_arg the explanatory string
279 @return parse_error object
280 */
create(int id_,std::size_t byte_,const std::string & what_arg)281 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
282 {
283 std::string w = exception::name("parse_error", id_) + "parse error" +
284 (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
285 ": " + what_arg;
286 return parse_error(id_, byte_, w.c_str());
287 }
288
289 /*!
290 @brief byte index of the parse error
291
292 The byte index of the last read character in the input file.
293
294 @note For an input with n bytes, 1 is the index of the first character and
295 n+1 is the index of the terminating null byte or the end of file.
296 This also holds true when reading a byte vector (CBOR or MessagePack).
297 */
298 const std::size_t byte;
299
300 private:
parse_error(int id_,std::size_t byte_,const char * what_arg)301 parse_error(int id_, std::size_t byte_, const char* what_arg)
302 : exception(id_, what_arg), byte(byte_) {}
303 };
304
305 /*!
306 @brief exception indicating errors with iterators
307
308 This exception is thrown if iterators passed to a library function do not match
309 the expected semantics.
310
311 Exceptions have ids 2xx.
312
313 name / id | example message | description
314 ----------------------------------- | --------------- | -------------------------
315 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.
316 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.
317 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.
318 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.
319 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.
320 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.
321 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.
322 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.
323 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.
324 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.
325 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.
326 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
327 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
328 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().
329
330 @liveexample{The following code shows how an `invalid_iterator` exception can be
331 caught.,invalid_iterator}
332
333 @sa @ref exception for the base class of the library exceptions
334 @sa @ref parse_error for exceptions indicating a parse error
335 @sa @ref type_error for exceptions indicating executing a member function with
336 a wrong type
337 @sa @ref out_of_range for exceptions indicating access out of the defined range
338 @sa @ref other_error for exceptions indicating other library errors
339
340 @since version 3.0.0
341 */
342 class invalid_iterator : public exception
343 {
344 public:
create(int id_,const std::string & what_arg)345 static invalid_iterator create(int id_, const std::string& what_arg)
346 {
347 std::string w = exception::name("invalid_iterator", id_) + what_arg;
348 return invalid_iterator(id_, w.c_str());
349 }
350
351 private:
invalid_iterator(int id_,const char * what_arg)352 invalid_iterator(int id_, const char* what_arg)
353 : exception(id_, what_arg) {}
354 };
355
356 /*!
357 @brief exception indicating executing a member function with a wrong type
358
359 This exception is thrown in case of a type error; that is, a library function is
360 executed on a JSON value whose type does not match the expected semantics.
361
362 Exceptions have ids 3xx.
363
364 name / id | example message | description
365 ----------------------------- | --------------- | -------------------------
366 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.
367 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.
368 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&.
369 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
370 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
371 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
372 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
373 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.
374 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
375 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
376 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.
377 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
378 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.
379 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
380 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.
381
382 @liveexample{The following code shows how a `type_error` exception can be
383 caught.,type_error}
384
385 @sa @ref exception for the base class of the library exceptions
386 @sa @ref parse_error for exceptions indicating a parse error
387 @sa @ref invalid_iterator for exceptions indicating errors with iterators
388 @sa @ref out_of_range for exceptions indicating access out of the defined range
389 @sa @ref other_error for exceptions indicating other library errors
390
391 @since version 3.0.0
392 */
393 class type_error : public exception
394 {
395 public:
create(int id_,const std::string & what_arg)396 static type_error create(int id_, const std::string& what_arg)
397 {
398 std::string w = exception::name("type_error", id_) + what_arg;
399 return type_error(id_, w.c_str());
400 }
401
402 private:
type_error(int id_,const char * what_arg)403 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
404 };
405
406 /*!
407 @brief exception indicating access out of the defined range
408
409 This exception is thrown in case a library function is called on an input
410 parameter that exceeds the expected range, for instance in case of array
411 indices or nonexisting object keys.
412
413 Exceptions have ids 4xx.
414
415 name / id | example message | description
416 ------------------------------- | --------------- | -------------------------
417 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.
418 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.
419 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
420 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
421 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.
422 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.
423
424 @liveexample{The following code shows how an `out_of_range` exception can be
425 caught.,out_of_range}
426
427 @sa @ref exception for the base class of the library exceptions
428 @sa @ref parse_error for exceptions indicating a parse error
429 @sa @ref invalid_iterator for exceptions indicating errors with iterators
430 @sa @ref type_error for exceptions indicating executing a member function with
431 a wrong type
432 @sa @ref other_error for exceptions indicating other library errors
433
434 @since version 3.0.0
435 */
436 class out_of_range : public exception
437 {
438 public:
create(int id_,const std::string & what_arg)439 static out_of_range create(int id_, const std::string& what_arg)
440 {
441 std::string w = exception::name("out_of_range", id_) + what_arg;
442 return out_of_range(id_, w.c_str());
443 }
444
445 private:
out_of_range(int id_,const char * what_arg)446 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
447 };
448
449 /*!
450 @brief exception indicating other library errors
451
452 This exception is thrown in case of errors that cannot be classified with the
453 other exception types.
454
455 Exceptions have ids 5xx.
456
457 name / id | example message | description
458 ------------------------------ | --------------- | -------------------------
459 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
460 json.exception.other_error.502 | invalid object size for conversion | Some conversions to user-defined types impose constraints on the object size (e.g. std::pair)
461
462 @sa @ref exception for the base class of the library exceptions
463 @sa @ref parse_error for exceptions indicating a parse error
464 @sa @ref invalid_iterator for exceptions indicating errors with iterators
465 @sa @ref type_error for exceptions indicating executing a member function with
466 a wrong type
467 @sa @ref out_of_range for exceptions indicating access out of the defined range
468
469 @liveexample{The following code shows how an `other_error` exception can be
470 caught.,other_error}
471
472 @since version 3.0.0
473 */
474 class other_error : public exception
475 {
476 public:
create(int id_,const std::string & what_arg)477 static other_error create(int id_, const std::string& what_arg)
478 {
479 std::string w = exception::name("other_error", id_) + what_arg;
480 return other_error(id_, w.c_str());
481 }
482
483 private:
other_error(int id_,const char * what_arg)484 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
485 };
486
487
488
489 ///////////////////////////
490 // JSON type enumeration //
491 ///////////////////////////
492
493 /*!
494 @brief the JSON type enumeration
495
496 This enumeration collects the different JSON types. It is internally used to
497 distinguish the stored values, and the functions @ref basic_json::is_null(),
498 @ref basic_json::is_object(), @ref basic_json::is_array(),
499 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
500 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
501 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
502 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
503 @ref basic_json::is_structured() rely on it.
504
505 @note There are three enumeration entries (number_integer, number_unsigned, and
506 number_float), because the library distinguishes these three types for numbers:
507 @ref basic_json::number_unsigned_t is used for unsigned integers,
508 @ref basic_json::number_integer_t is used for signed integers, and
509 @ref basic_json::number_float_t is used for floating-point numbers or to
510 approximate integers which do not fit in the limits of their respective type.
511
512 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
513 value with the default value for a given type
514
515 @since version 1.0.0
516 */
517 enum class value_t : uint8_t
518 {
519 null, ///< null value
520 object, ///< object (unordered set of name/value pairs)
521 array, ///< array (ordered collection of values)
522 string, ///< string value
523 boolean, ///< boolean value
524 number_integer, ///< number value (signed integer)
525 number_unsigned, ///< number value (unsigned integer)
526 number_float, ///< number value (floating-point)
527 discarded ///< discarded by the the parser callback function
528 };
529
530 /*!
531 @brief comparison operator for JSON types
532
533 Returns an ordering that is similar to Python:
534 - order: null < boolean < number < object < array < string
535 - furthermore, each type is not smaller than itself
536
537 @since version 1.0.0
538 */
operator <(const value_t lhs,const value_t rhs)539 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
540 {
541 static constexpr std::array<uint8_t, 8> order = {{
542 0, // null
543 3, // object
544 4, // array
545 5, // string
546 1, // boolean
547 2, // integer
548 2, // unsigned
549 2, // float
550 }
551 };
552
553 // discarded values are not comparable
554 return lhs != value_t::discarded and rhs != value_t::discarded and
555 order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
556 }
557
558
559 /////////////
560 // helpers //
561 /////////////
562
563 template<typename> struct is_basic_json : std::false_type {};
564
565 NLOHMANN_BASIC_JSON_TPL_DECLARATION
566 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
567
568 // alias templates to reduce boilerplate
569 template<bool B, typename T = void>
570 using enable_if_t = typename std::enable_if<B, T>::type;
571
572 template<typename T>
573 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
574
575 // implementation of C++14 index_sequence and affiliates
576 // source: https://stackoverflow.com/a/32223343
577 template<std::size_t... Ints>
578 struct index_sequence
579 {
580 using type = index_sequence;
581 using value_type = std::size_t;
sizenlohmann::detail::index_sequence582 static constexpr std::size_t size() noexcept
583 {
584 return sizeof...(Ints);
585 }
586 };
587
588 template<class Sequence1, class Sequence2>
589 struct merge_and_renumber;
590
591 template<std::size_t... I1, std::size_t... I2>
592 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
593 : index_sequence < I1..., (sizeof...(I1) + I2)... >
594 {};
595
596 template<std::size_t N>
597 struct make_index_sequence
598 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
599 typename make_index_sequence < N - N / 2 >::type >
600 {};
601
602 template<> struct make_index_sequence<0> : index_sequence<> { };
603 template<> struct make_index_sequence<1> : index_sequence<0> { };
604
605 template<typename... Ts>
606 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
607
608 /*
609 Implementation of two C++17 constructs: conjunction, negation. This is needed
610 to avoid evaluating all the traits in a condition
611
612 For example: not std::is_same<void, T>::value and has_value_type<T>::value
613 will not compile when T = void (on MSVC at least). Whereas
614 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
615 stop evaluating if negation<...>::value == false
616
617 Please note that those constructs must be used with caution, since symbols can
618 become very long quickly (which can slow down compilation and cause MSVC
619 internal compiler errors). Only use it when you have to (see example ahead).
620 */
621 template<class...> struct conjunction : std::true_type {};
622 template<class B1> struct conjunction<B1> : B1 {};
623 template<class B1, class... Bn>
624 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
625
626 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
627
628 // dispatch utility (taken from ranges-v3)
629 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
630 template<> struct priority_tag<0> {};
631
632
633 //////////////////
634 // constructors //
635 //////////////////
636
637 template<value_t> struct external_constructor;
638
639 template<>
640 struct external_constructor<value_t::boolean>
641 {
642 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor643 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
644 {
645 j.m_type = value_t::boolean;
646 j.m_value = b;
647 j.assert_invariant();
648 }
649 };
650
651 template<>
652 struct external_constructor<value_t::string>
653 {
654 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor655 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
656 {
657 j.m_type = value_t::string;
658 j.m_value = s;
659 j.assert_invariant();
660 }
661
662 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor663 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
664 {
665 j.m_type = value_t::string;
666 j.m_value = std::move(s);
667 j.assert_invariant();
668 }
669 };
670
671 template<>
672 struct external_constructor<value_t::number_float>
673 {
674 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor675 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
676 {
677 j.m_type = value_t::number_float;
678 j.m_value = val;
679 j.assert_invariant();
680 }
681 };
682
683 template<>
684 struct external_constructor<value_t::number_unsigned>
685 {
686 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor687 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
688 {
689 j.m_type = value_t::number_unsigned;
690 j.m_value = val;
691 j.assert_invariant();
692 }
693 };
694
695 template<>
696 struct external_constructor<value_t::number_integer>
697 {
698 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor699 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
700 {
701 j.m_type = value_t::number_integer;
702 j.m_value = val;
703 j.assert_invariant();
704 }
705 };
706
707 template<>
708 struct external_constructor<value_t::array>
709 {
710 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor711 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
712 {
713 j.m_type = value_t::array;
714 j.m_value = arr;
715 j.assert_invariant();
716 }
717
718 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor719 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
720 {
721 j.m_type = value_t::array;
722 j.m_value = std::move(arr);
723 j.assert_invariant();
724 }
725
726 template<typename BasicJsonType, typename CompatibleArrayType,
727 enable_if_t<not std::is_same<CompatibleArrayType,
728 typename BasicJsonType::array_t>::value,
729 int> = 0>
constructnlohmann::detail::external_constructor730 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
731 {
732 using std::begin;
733 using std::end;
734 j.m_type = value_t::array;
735 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
736 j.assert_invariant();
737 }
738
739 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor740 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
741 {
742 j.m_type = value_t::array;
743 j.m_value = value_t::array;
744 j.m_value.array->reserve(arr.size());
745 for (bool x : arr)
746 {
747 j.m_value.array->push_back(x);
748 }
749 j.assert_invariant();
750 }
751
752 template<typename BasicJsonType, typename T,
753 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor754 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
755 {
756 j.m_type = value_t::array;
757 j.m_value = value_t::array;
758 j.m_value.array->resize(arr.size());
759 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
760 j.assert_invariant();
761 }
762 };
763
764 template<>
765 struct external_constructor<value_t::object>
766 {
767 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor768 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
769 {
770 j.m_type = value_t::object;
771 j.m_value = obj;
772 j.assert_invariant();
773 }
774
775 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor776 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
777 {
778 j.m_type = value_t::object;
779 j.m_value = std::move(obj);
780 j.assert_invariant();
781 }
782
783 template<typename BasicJsonType, typename CompatibleObjectType,
784 enable_if_t<not std::is_same<CompatibleObjectType,
785 typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor786 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
787 {
788 using std::begin;
789 using std::end;
790
791 j.m_type = value_t::object;
792 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
793 j.assert_invariant();
794 }
795 };
796
797
798 ////////////////////////
799 // has_/is_ functions //
800 ////////////////////////
801
802 /*!
803 @brief Helper to determine whether there's a key_type for T.
804
805 This helper is used to tell associative containers apart from other containers
806 such as sequence containers. For instance, `std::map` passes the test as it
807 contains a `mapped_type`, whereas `std::vector` fails the test.
808
809 @sa http://stackoverflow.com/a/7728728/266378
810 @since version 1.0.0, overworked in version 2.0.6
811 */
812 #define NLOHMANN_JSON_HAS_HELPER(type) \
813 template<typename T> struct has_##type { \
814 private: \
815 template<typename U, typename = typename U::type> \
816 static int detect(U &&); \
817 static void detect(...); \
818 public: \
819 static constexpr bool value = \
820 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
821 }
822
823 NLOHMANN_JSON_HAS_HELPER(mapped_type);
824 NLOHMANN_JSON_HAS_HELPER(key_type);
825 NLOHMANN_JSON_HAS_HELPER(value_type);
826 NLOHMANN_JSON_HAS_HELPER(iterator);
827
828 #undef NLOHMANN_JSON_HAS_HELPER
829
830
831 template<bool B, class RealType, class CompatibleObjectType>
832 struct is_compatible_object_type_impl : std::false_type {};
833
834 template<class RealType, class CompatibleObjectType>
835 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
836 {
837 static constexpr auto value =
838 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
839 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
840 };
841
842 template<class BasicJsonType, class CompatibleObjectType>
843 struct is_compatible_object_type
844 {
845 static auto constexpr value = is_compatible_object_type_impl <
846 conjunction<negation<std::is_same<void, CompatibleObjectType>>,
847 has_mapped_type<CompatibleObjectType>,
848 has_key_type<CompatibleObjectType>>::value,
849 typename BasicJsonType::object_t, CompatibleObjectType >::value;
850 };
851
852 template<typename BasicJsonType, typename T>
853 struct is_basic_json_nested_type
854 {
855 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
856 std::is_same<T, typename BasicJsonType::const_iterator>::value or
857 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
858 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
859 };
860
861 template<class BasicJsonType, class CompatibleArrayType>
862 struct is_compatible_array_type
863 {
864 static auto constexpr value =
865 conjunction<negation<std::is_same<void, CompatibleArrayType>>,
866 negation<is_compatible_object_type<
867 BasicJsonType, CompatibleArrayType>>,
868 negation<std::is_constructible<typename BasicJsonType::string_t,
869 CompatibleArrayType>>,
870 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
871 has_value_type<CompatibleArrayType>,
872 has_iterator<CompatibleArrayType>>::value;
873 };
874
875 template<bool, typename, typename>
876 struct is_compatible_integer_type_impl : std::false_type {};
877
878 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
879 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
880 {
881 // is there an assert somewhere on overflows?
882 using RealLimits = std::numeric_limits<RealIntegerType>;
883 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
884
885 static constexpr auto value =
886 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
887 CompatibleLimits::is_integer and
888 RealLimits::is_signed == CompatibleLimits::is_signed;
889 };
890
891 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
892 struct is_compatible_integer_type
893 {
894 static constexpr auto value =
895 is_compatible_integer_type_impl <
896 std::is_integral<CompatibleNumberIntegerType>::value and
897 not std::is_same<bool, CompatibleNumberIntegerType>::value,
898 RealIntegerType, CompatibleNumberIntegerType > ::value;
899 };
900
901
902 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
903 template<typename BasicJsonType, typename T>
904 struct has_from_json
905 {
906 private:
907 // also check the return type of from_json
908 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
909 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
910 static int detect(U&&);
911 static void detect(...);
912
913 public:
914 static constexpr bool value = std::is_integral<decltype(
915 detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
916 };
917
918 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
919 // this overload is used for non-default-constructible user-defined-types
920 template<typename BasicJsonType, typename T>
921 struct has_non_default_from_json
922 {
923 private:
924 template <
925 typename U,
926 typename = enable_if_t<std::is_same<
927 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
928 static int detect(U&&);
929 static void detect(...);
930
931 public:
932 static constexpr bool value = std::is_integral<decltype(detect(
933 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
934 };
935
936 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
937 template<typename BasicJsonType, typename T>
938 struct has_to_json
939 {
940 private:
941 template<typename U, typename = decltype(uncvref_t<U>::to_json(
942 std::declval<BasicJsonType&>(), std::declval<T>()))>
943 static int detect(U&&);
944 static void detect(...);
945
946 public:
947 static constexpr bool value = std::is_integral<decltype(detect(
948 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
949 };
950
951
952 /////////////
953 // to_json //
954 /////////////
955
956 template<typename BasicJsonType, typename T, enable_if_t<
957 std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)958 void to_json(BasicJsonType& j, T b) noexcept
959 {
960 external_constructor<value_t::boolean>::construct(j, b);
961 }
962
963 template<typename BasicJsonType, typename CompatibleString,
964 enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
965 CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)966 void to_json(BasicJsonType& j, const CompatibleString& s)
967 {
968 external_constructor<value_t::string>::construct(j, s);
969 }
970
971 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)972 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
973 {
974 external_constructor<value_t::string>::construct(j, std::move(s));
975 }
976
977 template<typename BasicJsonType, typename FloatType,
978 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)979 void to_json(BasicJsonType& j, FloatType val) noexcept
980 {
981 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
982 }
983
984 template <
985 typename BasicJsonType, typename CompatibleNumberUnsignedType,
986 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
987 CompatibleNumberUnsignedType>::value, int> = 0 >
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)988 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
989 {
990 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
991 }
992
993 template <
994 typename BasicJsonType, typename CompatibleNumberIntegerType,
995 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
996 CompatibleNumberIntegerType>::value, int> = 0 >
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)997 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
998 {
999 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
1000 }
1001
1002 template<typename BasicJsonType, typename EnumType,
1003 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)1004 void to_json(BasicJsonType& j, EnumType e) noexcept
1005 {
1006 using underlying_type = typename std::underlying_type<EnumType>::type;
1007 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
1008 }
1009
1010 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)1011 void to_json(BasicJsonType& j, const std::vector<bool>& e)
1012 {
1013 external_constructor<value_t::array>::construct(j, e);
1014 }
1015
1016 template <
1017 typename BasicJsonType, typename CompatibleArrayType,
1018 enable_if_t <
1019 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
1020 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
1021 int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)1022 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
1023 {
1024 external_constructor<value_t::array>::construct(j, arr);
1025 }
1026
1027 template <typename BasicJsonType, typename T,
1028 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,std::valarray<T> arr)1029 void to_json(BasicJsonType& j, std::valarray<T> arr)
1030 {
1031 external_constructor<value_t::array>::construct(j, std::move(arr));
1032 }
1033
1034 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)1035 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
1036 {
1037 external_constructor<value_t::array>::construct(j, std::move(arr));
1038 }
1039
1040 template <
1041 typename BasicJsonType, typename CompatibleObjectType,
1042 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
1043 int> = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)1044 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
1045 {
1046 external_constructor<value_t::object>::construct(j, obj);
1047 }
1048
1049 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)1050 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
1051 {
1052 external_constructor<value_t::object>::construct(j, std::move(obj));
1053 }
1054
1055 template<typename BasicJsonType, typename T, std::size_t N,
1056 enable_if_t<not std::is_constructible<
1057 typename BasicJsonType::string_t, T (&)[N]>::value,
1058 int> = 0>
to_json(BasicJsonType & j,T (& arr)[N])1059 void to_json(BasicJsonType& j, T (&arr)[N])
1060 {
1061 external_constructor<value_t::array>::construct(j, arr);
1062 }
1063
1064 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)1065 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1066 {
1067 j = {p.first, p.second};
1068 }
1069
1070 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)1071 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1072 {
1073 j = {std::get<Idx>(t)...};
1074 }
1075
1076 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)1077 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1078 {
1079 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1080 }
1081
1082 ///////////////
1083 // from_json //
1084 ///////////////
1085
1086 // overloads for basic_json template parameters
1087 template<typename BasicJsonType, typename ArithmeticType,
1088 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1089 not std::is_same<ArithmeticType,
1090 typename BasicJsonType::boolean_t>::value,
1091 int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1092 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1093 {
1094 switch (static_cast<value_t>(j))
1095 {
1096 case value_t::number_unsigned:
1097 {
1098 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1099 break;
1100 }
1101 case value_t::number_integer:
1102 {
1103 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1104 break;
1105 }
1106 case value_t::number_float:
1107 {
1108 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1109 break;
1110 }
1111
1112 default:
1113 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1114 }
1115 }
1116
1117 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1118 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1119 {
1120 if (JSON_UNLIKELY(not j.is_boolean()))
1121 {
1122 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1123 }
1124 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1125 }
1126
1127 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1128 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1129 {
1130 if (JSON_UNLIKELY(not j.is_string()))
1131 {
1132 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1133 }
1134 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1135 }
1136
1137 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1138 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1139 {
1140 get_arithmetic_value(j, val);
1141 }
1142
1143 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1144 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1145 {
1146 get_arithmetic_value(j, val);
1147 }
1148
1149 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1150 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1151 {
1152 get_arithmetic_value(j, val);
1153 }
1154
1155 template<typename BasicJsonType, typename EnumType,
1156 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1157 void from_json(const BasicJsonType& j, EnumType& e)
1158 {
1159 typename std::underlying_type<EnumType>::type val;
1160 get_arithmetic_value(j, val);
1161 e = static_cast<EnumType>(val);
1162 }
1163
1164 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::array_t & arr)1165 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
1166 {
1167 if (JSON_UNLIKELY(not j.is_array()))
1168 {
1169 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1170 }
1171 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1172 }
1173
1174 // forward_list doesn't have an insert method
1175 template<typename BasicJsonType, typename T, typename Allocator,
1176 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1177 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1178 {
1179 if (JSON_UNLIKELY(not j.is_array()))
1180 {
1181 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1182 }
1183 std::transform(j.rbegin(), j.rend(),
1184 std::front_inserter(l), [](const BasicJsonType & i)
1185 {
1186 return i.template get<T>();
1187 });
1188 }
1189
1190 // valarray doesn't have an insert method
1191 template<typename BasicJsonType, typename T,
1192 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1193 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1194 {
1195 if (JSON_UNLIKELY(not j.is_array()))
1196 {
1197 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1198 }
1199 l.resize(j.size());
1200 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1201 }
1202
1203 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<0>)1204 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
1205 {
1206 using std::end;
1207
1208 std::transform(j.begin(), j.end(),
1209 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1210 {
1211 // get<BasicJsonType>() returns *this, this won't call a from_json
1212 // method when value_type is BasicJsonType
1213 return i.template get<typename CompatibleArrayType::value_type>();
1214 });
1215 }
1216
1217 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<1>)1218 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1219 -> decltype(
1220 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1221 void())
1222 {
1223 using std::end;
1224
1225 arr.reserve(j.size());
1226 std::transform(j.begin(), j.end(),
1227 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1228 {
1229 // get<BasicJsonType>() returns *this, this won't call a from_json
1230 // method when value_type is BasicJsonType
1231 return i.template get<typename CompatibleArrayType::value_type>();
1232 });
1233 }
1234
1235 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1236 void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
1237 {
1238 for (std::size_t i = 0; i < N; ++i)
1239 {
1240 arr[i] = j.at(i).template get<T>();
1241 }
1242 }
1243
1244 template<typename BasicJsonType, typename CompatibleArrayType,
1245 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1246 std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
1247 not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleArrayType & arr)1248 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
1249 {
1250 if (JSON_UNLIKELY(not j.is_array()))
1251 {
1252 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1253 }
1254
1255 from_json_array_impl(j, arr, priority_tag<2> {});
1256 }
1257
1258 template<typename BasicJsonType, typename CompatibleObjectType,
1259 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleObjectType & obj)1260 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1261 {
1262 if (JSON_UNLIKELY(not j.is_object()))
1263 {
1264 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1265 }
1266
1267 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1268 using value_type = typename CompatibleObjectType::value_type;
1269 std::transform(
1270 inner_object->begin(), inner_object->end(),
1271 std::inserter(obj, obj.begin()),
1272 [](typename BasicJsonType::object_t::value_type const & p)
1273 {
1274 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1275 });
1276 }
1277
1278 // overload for arithmetic types, not chosen for basic_json template arguments
1279 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1280 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1281 // an arithmetic type?
1282 template<typename BasicJsonType, typename ArithmeticType,
1283 enable_if_t <
1284 std::is_arithmetic<ArithmeticType>::value and
1285 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1286 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1287 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1288 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1289 int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1290 void from_json(const BasicJsonType& j, ArithmeticType& val)
1291 {
1292 switch (static_cast<value_t>(j))
1293 {
1294 case value_t::number_unsigned:
1295 {
1296 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1297 break;
1298 }
1299 case value_t::number_integer:
1300 {
1301 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1302 break;
1303 }
1304 case value_t::number_float:
1305 {
1306 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1307 break;
1308 }
1309 case value_t::boolean:
1310 {
1311 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1312 break;
1313 }
1314
1315 default:
1316 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1317 }
1318 }
1319
1320 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1321 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1322 {
1323 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1324 }
1325
1326 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1327 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1328 {
1329 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1330 }
1331
1332 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1333 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1334 {
1335 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1336 }
1337
1338 struct to_json_fn
1339 {
1340 private:
1341 template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1342 auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1343 -> decltype(to_json(j, std::forward<T>(val)), void())
1344 {
1345 return to_json(j, std::forward<T>(val));
1346 }
1347
1348 template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1349 void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1350 {
1351 static_assert(sizeof(BasicJsonType) == 0,
1352 "could not find to_json() method in T's namespace");
1353 }
1354
1355 public:
1356 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn1357 void operator()(BasicJsonType& j, T&& val) const
1358 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1359 {
1360 return call(j, std::forward<T>(val), priority_tag<1> {});
1361 }
1362 };
1363
1364 struct from_json_fn
1365 {
1366 private:
1367 template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1368 auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
1369 noexcept(noexcept(from_json(j, val)))
1370 -> decltype(from_json(j, val), void())
1371 {
1372 return from_json(j, val);
1373 }
1374
1375 template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1376 void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1377 {
1378 static_assert(sizeof(BasicJsonType) == 0,
1379 "could not find from_json() method in T's namespace");
1380 }
1381
1382 public:
1383 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1384 void operator()(const BasicJsonType& j, T& val) const
1385 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1386 {
1387 return call(j, val, priority_tag<1> {});
1388 }
1389 };
1390
1391 // taken from ranges-v3
1392 template<typename T>
1393 struct static_const
1394 {
1395 static constexpr T value{};
1396 };
1397
1398 template<typename T>
1399 constexpr T static_const<T>::value;
1400
1401 ////////////////////
1402 // input adapters //
1403 ////////////////////
1404
1405 /*!
1406 @brief abstract input adapter interface
1407
1408 Produces a stream of std::char_traits<char>::int_type characters from a
1409 std::istream, a buffer, or some other input type. Accepts the return of exactly
1410 one non-EOF character for future input. The int_type characters returned
1411 consist of all valid char values as positive values (typically unsigned char),
1412 plus an EOF value outside that range, specified by the value of the function
1413 std::char_traits<char>::eof(). This value is typically -1, but could be any
1414 arbitrary value which is not a valid char value.
1415 */
1416 struct input_adapter_protocol
1417 {
1418 /// get a character [0,255] or std::char_traits<char>::eof().
1419 virtual std::char_traits<char>::int_type get_character() = 0;
1420 /// restore the last non-eof() character to input
1421 virtual void unget_character() = 0;
1422 virtual ~input_adapter_protocol() = default;
1423 };
1424
1425 /// a type to simplify interfaces
1426 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1427
1428 /*!
1429 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
1430 beginning of input. Does not support changing the underlying std::streambuf
1431 in mid-input. Maintains underlying std::istream and std::streambuf to support
1432 subsequent use of standard std::istream operations to process any input
1433 characters following those used in parsing the JSON input. Clears the
1434 std::istream flags; any input errors (e.g., EOF) will be detected by the first
1435 subsequent call for input from the std::istream.
1436 */
1437 class input_stream_adapter : public input_adapter_protocol
1438 {
1439 public:
~input_stream_adapter()1440 ~input_stream_adapter() override
1441 {
1442 // clear stream flags; we use underlying streambuf I/O, do not
1443 // maintain ifstream flags
1444 is.clear();
1445 }
1446
input_stream_adapter(std::istream & i)1447 explicit input_stream_adapter(std::istream& i)
1448 : is(i), sb(*i.rdbuf())
1449 {
1450 // ignore Byte Order Mark at start of input
1451 std::char_traits<char>::int_type c;
1452 if ((c = get_character()) == 0xEF)
1453 {
1454 if ((c = get_character()) == 0xBB)
1455 {
1456 if ((c = get_character()) == 0xBF)
1457 {
1458 return; // Ignore BOM
1459 }
1460 else if (c != std::char_traits<char>::eof())
1461 {
1462 is.unget();
1463 }
1464 is.putback('\xBB');
1465 }
1466 else if (c != std::char_traits<char>::eof())
1467 {
1468 is.unget();
1469 }
1470 is.putback('\xEF');
1471 }
1472 else if (c != std::char_traits<char>::eof())
1473 {
1474 is.unget(); // Not BOM. Process as usual.
1475 }
1476 }
1477
1478 // delete because of pointer members
1479 input_stream_adapter(const input_stream_adapter&) = delete;
1480 input_stream_adapter& operator=(input_stream_adapter&) = delete;
1481
1482 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1483 // ensure that std::char_traits<char>::eof() and the character 0xff do not
1484 // end up as the same value, eg. 0xffffffff.
get_character()1485 std::char_traits<char>::int_type get_character() override
1486 {
1487 return sb.sbumpc();
1488 }
1489
unget_character()1490 void unget_character() override
1491 {
1492 sb.sungetc(); // is.unget() avoided for performance
1493 }
1494
1495 private:
1496 /// the associated input stream
1497 std::istream& is;
1498 std::streambuf& sb;
1499 };
1500
1501 /// input adapter for buffer input
1502 class input_buffer_adapter : public input_adapter_protocol
1503 {
1504 public:
input_buffer_adapter(const char * b,const std::size_t l)1505 input_buffer_adapter(const char* b, const std::size_t l)
1506 : cursor(b), limit(b + l), start(b)
1507 {
1508 // skip byte order mark
1509 if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF')
1510 {
1511 cursor += 3;
1512 }
1513 }
1514
1515 // delete because of pointer members
1516 input_buffer_adapter(const input_buffer_adapter&) = delete;
1517 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1518
get_character()1519 std::char_traits<char>::int_type get_character() noexcept override
1520 {
1521 if (JSON_LIKELY(cursor < limit))
1522 {
1523 return std::char_traits<char>::to_int_type(*(cursor++));
1524 }
1525
1526 return std::char_traits<char>::eof();
1527 }
1528
unget_character()1529 void unget_character() noexcept override
1530 {
1531 if (JSON_LIKELY(cursor > start))
1532 {
1533 --cursor;
1534 }
1535 }
1536
1537 private:
1538 /// pointer to the current character
1539 const char* cursor;
1540 /// pointer past the last character
1541 const char* limit;
1542 /// pointer to the first character
1543 const char* start;
1544 };
1545
1546 class input_adapter
1547 {
1548 public:
1549 // native support
1550
1551 /// input adapter for input stream
input_adapter(std::istream & i)1552 input_adapter(std::istream& i)
1553 : ia(std::make_shared<input_stream_adapter>(i)) {}
1554
1555 /// input adapter for input stream
input_adapter(std::istream && i)1556 input_adapter(std::istream&& i)
1557 : ia(std::make_shared<input_stream_adapter>(i)) {}
1558
1559 /// input adapter for buffer
1560 template<typename CharT,
1561 typename std::enable_if<
1562 std::is_pointer<CharT>::value and
1563 std::is_integral<
1564 typename std::remove_pointer<CharT>::type>::value and
1565 sizeof(typename std::remove_pointer<CharT>::type) == 1,
1566 int>::type = 0>
input_adapter(CharT b,std::size_t l)1567 input_adapter(CharT b, std::size_t l)
1568 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
1569
1570 // derived support
1571
1572 /// input adapter for string literal
1573 template<typename CharT,
1574 typename std::enable_if<
1575 std::is_pointer<CharT>::value and
1576 std::is_integral<
1577 typename std::remove_pointer<CharT>::type>::value and
1578 sizeof(typename std::remove_pointer<CharT>::type) == 1,
1579 int>::type = 0>
input_adapter(CharT b)1580 input_adapter(CharT b)
1581 : input_adapter(reinterpret_cast<const char*>(b),
1582 std::strlen(reinterpret_cast<const char*>(b))) {}
1583
1584 /// input adapter for iterator range with contiguous storage
1585 template<class IteratorType,
1586 typename std::enable_if<
1587 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category,
1588 std::random_access_iterator_tag>::value,
1589 int>::type = 0>
input_adapter(IteratorType first,IteratorType last)1590 input_adapter(IteratorType first, IteratorType last)
1591 {
1592 // assertion to check that the iterator range is indeed contiguous,
1593 // see http://stackoverflow.com/a/35008842/266378 for more discussion
1594 assert(std::accumulate(
1595 first, last, std::pair<bool, int>(true, 0),
1596 [&first](std::pair<bool, int> res, decltype(*first) val)
1597 {
1598 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1599 return res;
1600 }).first);
1601
1602 // assertion to check that each element is 1 byte long
1603 static_assert(
1604 sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
1605 "each element in the iterator range must have the size of 1 byte");
1606
1607 const auto len = static_cast<size_t>(std::distance(first, last));
1608 if (JSON_LIKELY(len > 0))
1609 {
1610 // there is at least one element: use the address of first
1611 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
1612 }
1613 else
1614 {
1615 // the address of first cannot be used: use nullptr
1616 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
1617 }
1618 }
1619
1620 /// input adapter for array
1621 template<class T, std::size_t N>
input_adapter(T (& array)[N])1622 input_adapter(T (&array)[N])
1623 : input_adapter(std::begin(array), std::end(array)) {}
1624
1625 /// input adapter for contiguous container
1626 template <
1627 class ContiguousContainer,
1628 typename std::enable_if <
1629 not std::is_pointer<ContiguousContainer>::value and
1630 std::is_base_of<std::random_access_iterator_tag,
1631 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1632 int >::type = 0 >
input_adapter(const ContiguousContainer & c)1633 input_adapter(const ContiguousContainer& c)
1634 : input_adapter(std::begin(c), std::end(c)) {}
1635
operator input_adapter_t()1636 operator input_adapter_t()
1637 {
1638 return ia;
1639 }
1640
1641 private:
1642 /// the actual adapter
1643 input_adapter_t ia = nullptr;
1644 };
1645
1646 //////////////////////
1647 // lexer and parser //
1648 //////////////////////
1649
1650 /*!
1651 @brief lexical analysis
1652
1653 This class organizes the lexical analysis during JSON deserialization.
1654 */
1655 template<typename BasicJsonType>
1656 class lexer
1657 {
1658 using number_integer_t = typename BasicJsonType::number_integer_t;
1659 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1660 using number_float_t = typename BasicJsonType::number_float_t;
1661
1662 public:
1663 /// token types for the parser
1664 enum class token_type
1665 {
1666 uninitialized, ///< indicating the scanner is uninitialized
1667 literal_true, ///< the `true` literal
1668 literal_false, ///< the `false` literal
1669 literal_null, ///< the `null` literal
1670 value_string, ///< a string -- use get_string() for actual value
1671 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
1672 value_integer, ///< a signed integer -- use get_number_integer() for actual value
1673 value_float, ///< an floating point number -- use get_number_float() for actual value
1674 begin_array, ///< the character for array begin `[`
1675 begin_object, ///< the character for object begin `{`
1676 end_array, ///< the character for array end `]`
1677 end_object, ///< the character for object end `}`
1678 name_separator, ///< the name separator `:`
1679 value_separator, ///< the value separator `,`
1680 parse_error, ///< indicating a parse error
1681 end_of_input, ///< indicating the end of the input buffer
1682 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
1683 };
1684
1685 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)1686 static const char* token_type_name(const token_type t) noexcept
1687 {
1688 switch (t)
1689 {
1690 case token_type::uninitialized:
1691 return "<uninitialized>";
1692 case token_type::literal_true:
1693 return "true literal";
1694 case token_type::literal_false:
1695 return "false literal";
1696 case token_type::literal_null:
1697 return "null literal";
1698 case token_type::value_string:
1699 return "string literal";
1700 case lexer::token_type::value_unsigned:
1701 case lexer::token_type::value_integer:
1702 case lexer::token_type::value_float:
1703 return "number literal";
1704 case token_type::begin_array:
1705 return "'['";
1706 case token_type::begin_object:
1707 return "'{'";
1708 case token_type::end_array:
1709 return "']'";
1710 case token_type::end_object:
1711 return "'}'";
1712 case token_type::name_separator:
1713 return "':'";
1714 case token_type::value_separator:
1715 return "','";
1716 case token_type::parse_error:
1717 return "<parse error>";
1718 case token_type::end_of_input:
1719 return "end of input";
1720 case token_type::literal_or_value:
1721 return "'[', '{', or a literal";
1722 default: // catch non-enum values
1723 return "unknown token"; // LCOV_EXCL_LINE
1724 }
1725 }
1726
lexer(detail::input_adapter_t adapter)1727 explicit lexer(detail::input_adapter_t adapter)
1728 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1729
1730 // delete because of pointer members
1731 lexer(const lexer&) = delete;
1732 lexer& operator=(lexer&) = delete;
1733
1734 private:
1735 /////////////////////
1736 // locales
1737 /////////////////////
1738
1739 /// return the locale-dependent decimal point
get_decimal_point()1740 static char get_decimal_point() noexcept
1741 {
1742 const auto loc = localeconv();
1743 assert(loc != nullptr);
1744 return (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
1745 }
1746
1747 /////////////////////
1748 // scan functions
1749 /////////////////////
1750
1751 /*!
1752 @brief get codepoint from 4 hex characters following `\u`
1753
1754 For input "\u c1 c2 c3 c4" the codepoint is:
1755 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
1756 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
1757
1758 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
1759 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
1760 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
1761 between the ASCII value of the character and the desired integer value.
1762
1763 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
1764 non-hex character)
1765 */
get_codepoint()1766 int get_codepoint()
1767 {
1768 // this function only makes sense after reading `\u`
1769 assert(current == 'u');
1770 int codepoint = 0;
1771
1772 const auto factors = { 12, 8, 4, 0 };
1773 for (const auto factor : factors)
1774 {
1775 get();
1776
1777 if (current >= '0' and current <= '9')
1778 {
1779 codepoint += ((current - 0x30) << factor);
1780 }
1781 else if (current >= 'A' and current <= 'F')
1782 {
1783 codepoint += ((current - 0x37) << factor);
1784 }
1785 else if (current >= 'a' and current <= 'f')
1786 {
1787 codepoint += ((current - 0x57) << factor);
1788 }
1789 else
1790 {
1791 return -1;
1792 }
1793 }
1794
1795 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
1796 return codepoint;
1797 }
1798
1799 /*!
1800 @brief check if the next byte(s) are inside a given range
1801
1802 Adds the current byte and, for each passed range, reads a new byte and
1803 checks if it is inside the range. If a violation was detected, set up an
1804 error message and return false. Otherwise, return true.
1805
1806 @return true if and only if no range violation was detected
1807 */
next_byte_in_range(std::initializer_list<int> ranges)1808 bool next_byte_in_range(std::initializer_list<int> ranges)
1809 {
1810 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
1811 add(current);
1812
1813 for (auto range = ranges.begin(); range != ranges.end(); ++range)
1814 {
1815 get();
1816 if (JSON_LIKELY(*range <= current and current <= *(++range)))
1817 {
1818 add(current);
1819 }
1820 else
1821 {
1822 error_message = "invalid string: ill-formed UTF-8 byte";
1823 return false;
1824 }
1825 }
1826
1827 return true;
1828 }
1829
1830 /*!
1831 @brief scan a string literal
1832
1833 This function scans a string according to Sect. 7 of RFC 7159. While
1834 scanning, bytes are escaped and copied into buffer yytext. Then the function
1835 returns successfully, yytext is *not* null-terminated (as it may contain \0
1836 bytes), and yytext.size() is the number of bytes in the string.
1837
1838 @return token_type::value_string if string could be successfully scanned,
1839 token_type::parse_error otherwise
1840
1841 @note In case of errors, variable error_message contains a textual
1842 description.
1843 */
scan_string()1844 token_type scan_string()
1845 {
1846 // reset yytext (ignore opening quote)
1847 reset();
1848
1849 // we entered the function by reading an open quote
1850 assert(current == '\"');
1851
1852 while (true)
1853 {
1854 // get next character
1855 switch (get())
1856 {
1857 // end of file while parsing string
1858 case std::char_traits<char>::eof():
1859 {
1860 error_message = "invalid string: missing closing quote";
1861 return token_type::parse_error;
1862 }
1863
1864 // closing quote
1865 case '\"':
1866 {
1867 return token_type::value_string;
1868 }
1869
1870 // escapes
1871 case '\\':
1872 {
1873 switch (get())
1874 {
1875 // quotation mark
1876 case '\"':
1877 add('\"');
1878 break;
1879 // reverse solidus
1880 case '\\':
1881 add('\\');
1882 break;
1883 // solidus
1884 case '/':
1885 add('/');
1886 break;
1887 // backspace
1888 case 'b':
1889 add('\b');
1890 break;
1891 // form feed
1892 case 'f':
1893 add('\f');
1894 break;
1895 // line feed
1896 case 'n':
1897 add('\n');
1898 break;
1899 // carriage return
1900 case 'r':
1901 add('\r');
1902 break;
1903 // tab
1904 case 't':
1905 add('\t');
1906 break;
1907
1908 // unicode escapes
1909 case 'u':
1910 {
1911 int codepoint;
1912 const int codepoint1 = get_codepoint();
1913
1914 if (JSON_UNLIKELY(codepoint1 == -1))
1915 {
1916 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
1917 return token_type::parse_error;
1918 }
1919
1920 // check if code point is a high surrogate
1921 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
1922 {
1923 // expect next \uxxxx entry
1924 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
1925 {
1926 const int codepoint2 = get_codepoint();
1927
1928 if (JSON_UNLIKELY(codepoint2 == -1))
1929 {
1930 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
1931 return token_type::parse_error;
1932 }
1933
1934 // check if codepoint2 is a low surrogate
1935 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
1936 {
1937 codepoint =
1938 // high surrogate occupies the most significant 22 bits
1939 (codepoint1 << 10)
1940 // low surrogate occupies the least significant 15 bits
1941 + codepoint2
1942 // there is still the 0xD800, 0xDC00 and 0x10000 noise
1943 // in the result so we have to subtract with:
1944 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
1945 - 0x35FDC00;
1946 }
1947 else
1948 {
1949 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1950 return token_type::parse_error;
1951 }
1952 }
1953 else
1954 {
1955 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1956 return token_type::parse_error;
1957 }
1958 }
1959 else
1960 {
1961 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
1962 {
1963 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
1964 return token_type::parse_error;
1965 }
1966
1967 // only work with first code point
1968 codepoint = codepoint1;
1969 }
1970
1971 // result of the above calculation yields a proper codepoint
1972 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
1973
1974 // translate code point to bytes
1975 if (codepoint < 0x80)
1976 {
1977 // 1-byte characters: 0xxxxxxx (ASCII)
1978 add(codepoint);
1979 }
1980 else if (codepoint <= 0x7ff)
1981 {
1982 // 2-byte characters: 110xxxxx 10xxxxxx
1983 add(0xC0 | (codepoint >> 6));
1984 add(0x80 | (codepoint & 0x3F));
1985 }
1986 else if (codepoint <= 0xffff)
1987 {
1988 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
1989 add(0xE0 | (codepoint >> 12));
1990 add(0x80 | ((codepoint >> 6) & 0x3F));
1991 add(0x80 | (codepoint & 0x3F));
1992 }
1993 else
1994 {
1995 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1996 add(0xF0 | (codepoint >> 18));
1997 add(0x80 | ((codepoint >> 12) & 0x3F));
1998 add(0x80 | ((codepoint >> 6) & 0x3F));
1999 add(0x80 | (codepoint & 0x3F));
2000 }
2001
2002 break;
2003 }
2004
2005 // other characters after escape
2006 default:
2007 error_message = "invalid string: forbidden character after backslash";
2008 return token_type::parse_error;
2009 }
2010
2011 break;
2012 }
2013
2014 // invalid control characters
2015 case 0x00:
2016 case 0x01:
2017 case 0x02:
2018 case 0x03:
2019 case 0x04:
2020 case 0x05:
2021 case 0x06:
2022 case 0x07:
2023 case 0x08:
2024 case 0x09:
2025 case 0x0a:
2026 case 0x0b:
2027 case 0x0c:
2028 case 0x0d:
2029 case 0x0e:
2030 case 0x0f:
2031 case 0x10:
2032 case 0x11:
2033 case 0x12:
2034 case 0x13:
2035 case 0x14:
2036 case 0x15:
2037 case 0x16:
2038 case 0x17:
2039 case 0x18:
2040 case 0x19:
2041 case 0x1a:
2042 case 0x1b:
2043 case 0x1c:
2044 case 0x1d:
2045 case 0x1e:
2046 case 0x1f:
2047 {
2048 error_message = "invalid string: control character must be escaped";
2049 return token_type::parse_error;
2050 }
2051
2052 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
2053 case 0x20:
2054 case 0x21:
2055 case 0x23:
2056 case 0x24:
2057 case 0x25:
2058 case 0x26:
2059 case 0x27:
2060 case 0x28:
2061 case 0x29:
2062 case 0x2a:
2063 case 0x2b:
2064 case 0x2c:
2065 case 0x2d:
2066 case 0x2e:
2067 case 0x2f:
2068 case 0x30:
2069 case 0x31:
2070 case 0x32:
2071 case 0x33:
2072 case 0x34:
2073 case 0x35:
2074 case 0x36:
2075 case 0x37:
2076 case 0x38:
2077 case 0x39:
2078 case 0x3a:
2079 case 0x3b:
2080 case 0x3c:
2081 case 0x3d:
2082 case 0x3e:
2083 case 0x3f:
2084 case 0x40:
2085 case 0x41:
2086 case 0x42:
2087 case 0x43:
2088 case 0x44:
2089 case 0x45:
2090 case 0x46:
2091 case 0x47:
2092 case 0x48:
2093 case 0x49:
2094 case 0x4a:
2095 case 0x4b:
2096 case 0x4c:
2097 case 0x4d:
2098 case 0x4e:
2099 case 0x4f:
2100 case 0x50:
2101 case 0x51:
2102 case 0x52:
2103 case 0x53:
2104 case 0x54:
2105 case 0x55:
2106 case 0x56:
2107 case 0x57:
2108 case 0x58:
2109 case 0x59:
2110 case 0x5a:
2111 case 0x5b:
2112 case 0x5d:
2113 case 0x5e:
2114 case 0x5f:
2115 case 0x60:
2116 case 0x61:
2117 case 0x62:
2118 case 0x63:
2119 case 0x64:
2120 case 0x65:
2121 case 0x66:
2122 case 0x67:
2123 case 0x68:
2124 case 0x69:
2125 case 0x6a:
2126 case 0x6b:
2127 case 0x6c:
2128 case 0x6d:
2129 case 0x6e:
2130 case 0x6f:
2131 case 0x70:
2132 case 0x71:
2133 case 0x72:
2134 case 0x73:
2135 case 0x74:
2136 case 0x75:
2137 case 0x76:
2138 case 0x77:
2139 case 0x78:
2140 case 0x79:
2141 case 0x7a:
2142 case 0x7b:
2143 case 0x7c:
2144 case 0x7d:
2145 case 0x7e:
2146 case 0x7f:
2147 {
2148 add(current);
2149 break;
2150 }
2151
2152 // U+0080..U+07FF: bytes C2..DF 80..BF
2153 case 0xc2:
2154 case 0xc3:
2155 case 0xc4:
2156 case 0xc5:
2157 case 0xc6:
2158 case 0xc7:
2159 case 0xc8:
2160 case 0xc9:
2161 case 0xca:
2162 case 0xcb:
2163 case 0xcc:
2164 case 0xcd:
2165 case 0xce:
2166 case 0xcf:
2167 case 0xd0:
2168 case 0xd1:
2169 case 0xd2:
2170 case 0xd3:
2171 case 0xd4:
2172 case 0xd5:
2173 case 0xd6:
2174 case 0xd7:
2175 case 0xd8:
2176 case 0xd9:
2177 case 0xda:
2178 case 0xdb:
2179 case 0xdc:
2180 case 0xdd:
2181 case 0xde:
2182 case 0xdf:
2183 {
2184 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2185 {
2186 return token_type::parse_error;
2187 }
2188 break;
2189 }
2190
2191 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2192 case 0xe0:
2193 {
2194 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2195 {
2196 return token_type::parse_error;
2197 }
2198 break;
2199 }
2200
2201 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2202 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2203 case 0xe1:
2204 case 0xe2:
2205 case 0xe3:
2206 case 0xe4:
2207 case 0xe5:
2208 case 0xe6:
2209 case 0xe7:
2210 case 0xe8:
2211 case 0xe9:
2212 case 0xea:
2213 case 0xeb:
2214 case 0xec:
2215 case 0xee:
2216 case 0xef:
2217 {
2218 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2219 {
2220 return token_type::parse_error;
2221 }
2222 break;
2223 }
2224
2225 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2226 case 0xed:
2227 {
2228 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2229 {
2230 return token_type::parse_error;
2231 }
2232 break;
2233 }
2234
2235 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2236 case 0xf0:
2237 {
2238 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2239 {
2240 return token_type::parse_error;
2241 }
2242 break;
2243 }
2244
2245 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2246 case 0xf1:
2247 case 0xf2:
2248 case 0xf3:
2249 {
2250 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2251 {
2252 return token_type::parse_error;
2253 }
2254 break;
2255 }
2256
2257 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2258 case 0xf4:
2259 {
2260 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2261 {
2262 return token_type::parse_error;
2263 }
2264 break;
2265 }
2266
2267 // remaining bytes (80..C1 and F5..FF) are ill-formed
2268 default:
2269 {
2270 error_message = "invalid string: ill-formed UTF-8 byte";
2271 return token_type::parse_error;
2272 }
2273 }
2274 }
2275 }
2276
strtof(float & f,const char * str,char ** endptr)2277 static void strtof(float& f, const char* str, char** endptr) noexcept
2278 {
2279 f = std::strtof(str, endptr);
2280 }
2281
strtof(double & f,const char * str,char ** endptr)2282 static void strtof(double& f, const char* str, char** endptr) noexcept
2283 {
2284 f = std::strtod(str, endptr);
2285 }
2286
strtof(long double & f,const char * str,char ** endptr)2287 static void strtof(long double& f, const char* str, char** endptr) noexcept
2288 {
2289 f = std::strtold(str, endptr);
2290 }
2291
2292 /*!
2293 @brief scan a number literal
2294
2295 This function scans a string according to Sect. 6 of RFC 7159.
2296
2297 The function is realized with a deterministic finite state machine derived
2298 from the grammar described in RFC 7159. Starting in state "init", the
2299 input is read and used to determined the next state. Only state "done"
2300 accepts the number. State "error" is a trap state to model errors. In the
2301 table below, "anything" means any character but the ones listed before.
2302
2303 state | 0 | 1-9 | e E | + | - | . | anything
2304 ---------|----------|----------|----------|---------|---------|----------|-----------
2305 init | zero | any1 | [error] | [error] | minus | [error] | [error]
2306 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
2307 zero | done | done | exponent | done | done | decimal1 | done
2308 any1 | any1 | any1 | exponent | done | done | decimal1 | done
2309 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
2310 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
2311 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
2312 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
2313 any2 | any2 | any2 | done | done | done | done | done
2314
2315 The state machine is realized with one label per state (prefixed with
2316 "scan_number_") and `goto` statements between them. The state machine
2317 contains cycles, but any cycle can be left when EOF is read. Therefore,
2318 the function is guaranteed to terminate.
2319
2320 During scanning, the read bytes are stored in yytext. This string is
2321 then converted to a signed integer, an unsigned integer, or a
2322 floating-point number.
2323
2324 @return token_type::value_unsigned, token_type::value_integer, or
2325 token_type::value_float if number could be successfully scanned,
2326 token_type::parse_error otherwise
2327
2328 @note The scanner is independent of the current locale. Internally, the
2329 locale's decimal point is used instead of `.` to work with the
2330 locale-dependent converters.
2331 */
scan_number()2332 token_type scan_number()
2333 {
2334 // reset yytext to store the number's bytes
2335 reset();
2336
2337 // the type of the parsed number; initially set to unsigned; will be
2338 // changed if minus sign, decimal point or exponent is read
2339 token_type number_type = token_type::value_unsigned;
2340
2341 // state (init): we just found out we need to scan a number
2342 switch (current)
2343 {
2344 case '-':
2345 {
2346 add(current);
2347 goto scan_number_minus;
2348 }
2349
2350 case '0':
2351 {
2352 add(current);
2353 goto scan_number_zero;
2354 }
2355
2356 case '1':
2357 case '2':
2358 case '3':
2359 case '4':
2360 case '5':
2361 case '6':
2362 case '7':
2363 case '8':
2364 case '9':
2365 {
2366 add(current);
2367 goto scan_number_any1;
2368 }
2369
2370 default:
2371 {
2372 // all other characters are rejected outside scan_number()
2373 assert(false); // LCOV_EXCL_LINE
2374 }
2375 }
2376
2377 scan_number_minus:
2378 // state: we just parsed a leading minus sign
2379 number_type = token_type::value_integer;
2380 switch (get())
2381 {
2382 case '0':
2383 {
2384 add(current);
2385 goto scan_number_zero;
2386 }
2387
2388 case '1':
2389 case '2':
2390 case '3':
2391 case '4':
2392 case '5':
2393 case '6':
2394 case '7':
2395 case '8':
2396 case '9':
2397 {
2398 add(current);
2399 goto scan_number_any1;
2400 }
2401
2402 default:
2403 {
2404 error_message = "invalid number; expected digit after '-'";
2405 return token_type::parse_error;
2406 }
2407 }
2408
2409 scan_number_zero:
2410 // state: we just parse a zero (maybe with a leading minus sign)
2411 switch (get())
2412 {
2413 case '.':
2414 {
2415 add(decimal_point_char);
2416 goto scan_number_decimal1;
2417 }
2418
2419 case 'e':
2420 case 'E':
2421 {
2422 add(current);
2423 goto scan_number_exponent;
2424 }
2425
2426 default:
2427 goto scan_number_done;
2428 }
2429
2430 scan_number_any1:
2431 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2432 switch (get())
2433 {
2434 case '0':
2435 case '1':
2436 case '2':
2437 case '3':
2438 case '4':
2439 case '5':
2440 case '6':
2441 case '7':
2442 case '8':
2443 case '9':
2444 {
2445 add(current);
2446 goto scan_number_any1;
2447 }
2448
2449 case '.':
2450 {
2451 add(decimal_point_char);
2452 goto scan_number_decimal1;
2453 }
2454
2455 case 'e':
2456 case 'E':
2457 {
2458 add(current);
2459 goto scan_number_exponent;
2460 }
2461
2462 default:
2463 goto scan_number_done;
2464 }
2465
2466 scan_number_decimal1:
2467 // state: we just parsed a decimal point
2468 number_type = token_type::value_float;
2469 switch (get())
2470 {
2471 case '0':
2472 case '1':
2473 case '2':
2474 case '3':
2475 case '4':
2476 case '5':
2477 case '6':
2478 case '7':
2479 case '8':
2480 case '9':
2481 {
2482 add(current);
2483 goto scan_number_decimal2;
2484 }
2485
2486 default:
2487 {
2488 error_message = "invalid number; expected digit after '.'";
2489 return token_type::parse_error;
2490 }
2491 }
2492
2493 scan_number_decimal2:
2494 // we just parsed at least one number after a decimal point
2495 switch (get())
2496 {
2497 case '0':
2498 case '1':
2499 case '2':
2500 case '3':
2501 case '4':
2502 case '5':
2503 case '6':
2504 case '7':
2505 case '8':
2506 case '9':
2507 {
2508 add(current);
2509 goto scan_number_decimal2;
2510 }
2511
2512 case 'e':
2513 case 'E':
2514 {
2515 add(current);
2516 goto scan_number_exponent;
2517 }
2518
2519 default:
2520 goto scan_number_done;
2521 }
2522
2523 scan_number_exponent:
2524 // we just parsed an exponent
2525 number_type = token_type::value_float;
2526 switch (get())
2527 {
2528 case '+':
2529 case '-':
2530 {
2531 add(current);
2532 goto scan_number_sign;
2533 }
2534
2535 case '0':
2536 case '1':
2537 case '2':
2538 case '3':
2539 case '4':
2540 case '5':
2541 case '6':
2542 case '7':
2543 case '8':
2544 case '9':
2545 {
2546 add(current);
2547 goto scan_number_any2;
2548 }
2549
2550 default:
2551 {
2552 error_message =
2553 "invalid number; expected '+', '-', or digit after exponent";
2554 return token_type::parse_error;
2555 }
2556 }
2557
2558 scan_number_sign:
2559 // we just parsed an exponent sign
2560 switch (get())
2561 {
2562 case '0':
2563 case '1':
2564 case '2':
2565 case '3':
2566 case '4':
2567 case '5':
2568 case '6':
2569 case '7':
2570 case '8':
2571 case '9':
2572 {
2573 add(current);
2574 goto scan_number_any2;
2575 }
2576
2577 default:
2578 {
2579 error_message = "invalid number; expected digit after exponent sign";
2580 return token_type::parse_error;
2581 }
2582 }
2583
2584 scan_number_any2:
2585 // we just parsed a number after the exponent or exponent sign
2586 switch (get())
2587 {
2588 case '0':
2589 case '1':
2590 case '2':
2591 case '3':
2592 case '4':
2593 case '5':
2594 case '6':
2595 case '7':
2596 case '8':
2597 case '9':
2598 {
2599 add(current);
2600 goto scan_number_any2;
2601 }
2602
2603 default:
2604 goto scan_number_done;
2605 }
2606
2607 scan_number_done:
2608 // unget the character after the number (we only read it to know that
2609 // we are done scanning a number)
2610 unget();
2611
2612 char* endptr = nullptr;
2613 errno = 0;
2614
2615 // try to parse integers first and fall back to floats
2616 if (number_type == token_type::value_unsigned)
2617 {
2618 const auto x = std::strtoull(yytext.data(), &endptr, 10);
2619
2620 // we checked the number format before
2621 assert(endptr == yytext.data() + yytext.size());
2622
2623 if (errno == 0)
2624 {
2625 value_unsigned = static_cast<number_unsigned_t>(x);
2626 if (value_unsigned == x)
2627 {
2628 return token_type::value_unsigned;
2629 }
2630 }
2631 }
2632 else if (number_type == token_type::value_integer)
2633 {
2634 const auto x = std::strtoll(yytext.data(), &endptr, 10);
2635
2636 // we checked the number format before
2637 assert(endptr == yytext.data() + yytext.size());
2638
2639 if (errno == 0)
2640 {
2641 value_integer = static_cast<number_integer_t>(x);
2642 if (value_integer == x)
2643 {
2644 return token_type::value_integer;
2645 }
2646 }
2647 }
2648
2649 // this code is reached if we parse a floating-point number or if an
2650 // integer conversion above failed
2651 strtof(value_float, yytext.data(), &endptr);
2652
2653 // we checked the number format before
2654 assert(endptr == yytext.data() + yytext.size());
2655
2656 return token_type::value_float;
2657 }
2658
2659 /*!
2660 @param[in] literal_text the literal text to expect
2661 @param[in] length the length of the passed literal text
2662 @param[in] return_type the token type to return on success
2663 */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)2664 token_type scan_literal(const char* literal_text, const std::size_t length,
2665 token_type return_type)
2666 {
2667 assert(current == literal_text[0]);
2668 for (std::size_t i = 1; i < length; ++i)
2669 {
2670 if (JSON_UNLIKELY(get() != literal_text[i]))
2671 {
2672 error_message = "invalid literal";
2673 return token_type::parse_error;
2674 }
2675 }
2676 return return_type;
2677 }
2678
2679 /////////////////////
2680 // input management
2681 /////////////////////
2682
2683 /// reset yytext; current character is beginning of token
reset()2684 void reset() noexcept
2685 {
2686 yytext.clear();
2687 token_string.clear();
2688 token_string.push_back(std::char_traits<char>::to_char_type(current));
2689 }
2690
2691 /*
2692 @brief get next character from the input
2693
2694 This function provides the interface to the used input adapter. It does
2695 not throw in case the input reached EOF, but returns a
2696 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
2697 for use in error messages.
2698
2699 @return character read from the input
2700 */
get()2701 std::char_traits<char>::int_type get()
2702 {
2703 ++chars_read;
2704 current = ia->get_character();
2705 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2706 {
2707 token_string.push_back(std::char_traits<char>::to_char_type(current));
2708 }
2709 return current;
2710 }
2711
2712 /// unget current character (return it again on next get)
unget()2713 void unget()
2714 {
2715 --chars_read;
2716 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2717 {
2718 ia->unget_character();
2719 assert(token_string.size() != 0);
2720 token_string.pop_back();
2721 }
2722 }
2723
2724 /// add a character to yytext
add(int c)2725 void add(int c)
2726 {
2727 yytext.push_back(std::char_traits<char>::to_char_type(c));
2728 }
2729
2730 public:
2731 /////////////////////
2732 // value getters
2733 /////////////////////
2734
2735 /// return integer value
get_number_integer() const2736 constexpr number_integer_t get_number_integer() const noexcept
2737 {
2738 return value_integer;
2739 }
2740
2741 /// return unsigned integer value
get_number_unsigned() const2742 constexpr number_unsigned_t get_number_unsigned() const noexcept
2743 {
2744 return value_unsigned;
2745 }
2746
2747 /// return floating-point value
get_number_float() const2748 constexpr number_float_t get_number_float() const noexcept
2749 {
2750 return value_float;
2751 }
2752
2753 /// return current string value (implicitly resets the token; useful only once)
move_string()2754 std::string move_string()
2755 {
2756 return std::move(yytext);
2757 }
2758
2759 /////////////////////
2760 // diagnostics
2761 /////////////////////
2762
2763 /// return position of last read token
get_position() const2764 constexpr std::size_t get_position() const noexcept
2765 {
2766 return chars_read;
2767 }
2768
2769 /// return the last read token (for errors only). Will never contain EOF
2770 /// (an arbitrary value that is not a valid char value, often -1), because
2771 /// 255 may legitimately occur. May contain NUL, which should be escaped.
get_token_string() const2772 std::string get_token_string() const
2773 {
2774 // escape control characters
2775 std::string result;
2776 for (auto c : token_string)
2777 {
2778 if ('\x00' <= c and c <= '\x1f')
2779 {
2780 // escape control characters
2781 std::stringstream ss;
2782 ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
2783 << std::hex << static_cast<int>(c) << ">";
2784 result += ss.str();
2785 }
2786 else
2787 {
2788 // add character as is
2789 result.push_back(c);
2790 }
2791 }
2792
2793 return result;
2794 }
2795
2796 /// return syntax error message
get_error_message() const2797 constexpr const char* get_error_message() const noexcept
2798 {
2799 return error_message;
2800 }
2801
2802 /////////////////////
2803 // actual scanner
2804 /////////////////////
2805
scan()2806 token_type scan()
2807 {
2808 // read next character and ignore whitespace
2809 do
2810 {
2811 get();
2812 }
2813 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
2814
2815 switch (current)
2816 {
2817 // structural characters
2818 case '[':
2819 return token_type::begin_array;
2820 case ']':
2821 return token_type::end_array;
2822 case '{':
2823 return token_type::begin_object;
2824 case '}':
2825 return token_type::end_object;
2826 case ':':
2827 return token_type::name_separator;
2828 case ',':
2829 return token_type::value_separator;
2830
2831 // literals
2832 case 't':
2833 return scan_literal("true", 4, token_type::literal_true);
2834 case 'f':
2835 return scan_literal("false", 5, token_type::literal_false);
2836 case 'n':
2837 return scan_literal("null", 4, token_type::literal_null);
2838
2839 // string
2840 case '\"':
2841 return scan_string();
2842
2843 // number
2844 case '-':
2845 case '0':
2846 case '1':
2847 case '2':
2848 case '3':
2849 case '4':
2850 case '5':
2851 case '6':
2852 case '7':
2853 case '8':
2854 case '9':
2855 return scan_number();
2856
2857 // end of input (the null byte is needed when parsing from
2858 // string literals)
2859 case '\0':
2860 case std::char_traits<char>::eof():
2861 return token_type::end_of_input;
2862
2863 // error
2864 default:
2865 error_message = "invalid literal";
2866 return token_type::parse_error;
2867 }
2868 }
2869
2870 private:
2871 /// input adapter
2872 detail::input_adapter_t ia = nullptr;
2873
2874 /// the current character
2875 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
2876
2877 /// the number of characters read
2878 std::size_t chars_read = 0;
2879
2880 /// raw input token string (for error messages)
2881 std::vector<char> token_string { };
2882
2883 /// buffer for variable-length tokens (numbers, strings)
2884 std::string yytext { };
2885
2886 /// a description of occurred lexer errors
2887 const char* error_message = "";
2888
2889 // number values
2890 number_integer_t value_integer = 0;
2891 number_unsigned_t value_unsigned = 0;
2892 number_float_t value_float = 0;
2893
2894 /// the decimal point
2895 const char decimal_point_char = '.';
2896 };
2897
2898 /*!
2899 @brief syntax analysis
2900
2901 This class implements a recursive decent parser.
2902 */
2903 template<typename BasicJsonType>
2904 class parser
2905 {
2906 using number_integer_t = typename BasicJsonType::number_integer_t;
2907 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2908 using number_float_t = typename BasicJsonType::number_float_t;
2909 using lexer_t = lexer<BasicJsonType>;
2910 using token_type = typename lexer_t::token_type;
2911
2912 public:
2913 enum class parse_event_t : uint8_t
2914 {
2915 /// the parser read `{` and started to process a JSON object
2916 object_start,
2917 /// the parser read `}` and finished processing a JSON object
2918 object_end,
2919 /// the parser read `[` and started to process a JSON array
2920 array_start,
2921 /// the parser read `]` and finished processing a JSON array
2922 array_end,
2923 /// the parser read a key of a value in an object
2924 key,
2925 /// the parser finished reading a JSON value
2926 value
2927 };
2928
2929 using parser_callback_t =
2930 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
2931
2932 /// a parser reading from an input adapter
parser(detail::input_adapter_t adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)2933 explicit parser(detail::input_adapter_t adapter,
2934 const parser_callback_t cb = nullptr,
2935 const bool allow_exceptions_ = true)
2936 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
2937 {}
2938
2939 /*!
2940 @brief public parser interface
2941
2942 @param[in] strict whether to expect the last token to be EOF
2943 @param[in,out] result parsed JSON value
2944
2945 @throw parse_error.101 in case of an unexpected token
2946 @throw parse_error.102 if to_unicode fails or surrogate error
2947 @throw parse_error.103 if to_unicode fails
2948 */
parse(const bool strict,BasicJsonType & result)2949 void parse(const bool strict, BasicJsonType& result)
2950 {
2951 // read first token
2952 get_token();
2953
2954 parse_internal(true, result);
2955 result.assert_invariant();
2956
2957 // in strict mode, input must be completely read
2958 if (strict)
2959 {
2960 get_token();
2961 expect(token_type::end_of_input);
2962 }
2963
2964 // in case of an error, return discarded value
2965 if (errored)
2966 {
2967 result = value_t::discarded;
2968 return;
2969 }
2970
2971 // set top-level value to null if it was discarded by the callback
2972 // function
2973 if (result.is_discarded())
2974 {
2975 result = nullptr;
2976 }
2977 }
2978
2979 /*!
2980 @brief public accept interface
2981
2982 @param[in] strict whether to expect the last token to be EOF
2983 @return whether the input is a proper JSON text
2984 */
accept(const bool strict=true)2985 bool accept(const bool strict = true)
2986 {
2987 // read first token
2988 get_token();
2989
2990 if (not accept_internal())
2991 {
2992 return false;
2993 }
2994
2995 // strict => last token must be EOF
2996 return not strict or (get_token() == token_type::end_of_input);
2997 }
2998
2999 private:
3000 /*!
3001 @brief the actual parser
3002 @throw parse_error.101 in case of an unexpected token
3003 @throw parse_error.102 if to_unicode fails or surrogate error
3004 @throw parse_error.103 if to_unicode fails
3005 */
parse_internal(bool keep,BasicJsonType & result)3006 void parse_internal(bool keep, BasicJsonType& result)
3007 {
3008 // never parse after a parse error was detected
3009 assert(not errored);
3010
3011 // start with a discarded value
3012 if (not result.is_discarded())
3013 {
3014 result.m_value.destroy(result.m_type);
3015 result.m_type = value_t::discarded;
3016 }
3017
3018 switch (last_token)
3019 {
3020 case token_type::begin_object:
3021 {
3022 if (keep)
3023 {
3024 if (callback)
3025 {
3026 keep = callback(depth++, parse_event_t::object_start, result);
3027 }
3028
3029 if (not callback or keep)
3030 {
3031 // explicitly set result to object to cope with {}
3032 result.m_type = value_t::object;
3033 result.m_value = value_t::object;
3034 }
3035 }
3036
3037 // read next token
3038 get_token();
3039
3040 // closing } -> we are done
3041 if (last_token == token_type::end_object)
3042 {
3043 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3044 {
3045 result.m_value.destroy(result.m_type);
3046 result.m_type = value_t::discarded;
3047 }
3048 break;
3049 }
3050
3051 // parse values
3052 std::string key;
3053 BasicJsonType value;
3054 while (true)
3055 {
3056 // store key
3057 if (not expect(token_type::value_string))
3058 {
3059 return;
3060 }
3061 key = m_lexer.move_string();
3062
3063 bool keep_tag = false;
3064 if (keep)
3065 {
3066 if (callback)
3067 {
3068 BasicJsonType k(key);
3069 keep_tag = callback(depth, parse_event_t::key, k);
3070 }
3071 else
3072 {
3073 keep_tag = true;
3074 }
3075 }
3076
3077 // parse separator (:)
3078 get_token();
3079 if (not expect(token_type::name_separator))
3080 {
3081 return;
3082 }
3083
3084 // parse and add value
3085 get_token();
3086 value.m_value.destroy(value.m_type);
3087 value.m_type = value_t::discarded;
3088 parse_internal(keep, value);
3089
3090 if (JSON_UNLIKELY(errored))
3091 {
3092 return;
3093 }
3094
3095 if (keep and keep_tag and not value.is_discarded())
3096 {
3097 result.m_value.object->emplace(std::move(key), std::move(value));
3098 }
3099
3100 // comma -> next value
3101 get_token();
3102 if (last_token == token_type::value_separator)
3103 {
3104 get_token();
3105 continue;
3106 }
3107
3108 // closing }
3109 if (not expect(token_type::end_object))
3110 {
3111 return;
3112 }
3113 break;
3114 }
3115
3116 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3117 {
3118 result.m_value.destroy(result.m_type);
3119 result.m_type = value_t::discarded;
3120 }
3121 break;
3122 }
3123
3124 case token_type::begin_array:
3125 {
3126 if (keep)
3127 {
3128 if (callback)
3129 {
3130 keep = callback(depth++, parse_event_t::array_start, result);
3131 }
3132
3133 if (not callback or keep)
3134 {
3135 // explicitly set result to array to cope with []
3136 result.m_type = value_t::array;
3137 result.m_value = value_t::array;
3138 }
3139 }
3140
3141 // read next token
3142 get_token();
3143
3144 // closing ] -> we are done
3145 if (last_token == token_type::end_array)
3146 {
3147 if (callback and not callback(--depth, parse_event_t::array_end, result))
3148 {
3149 result.m_value.destroy(result.m_type);
3150 result.m_type = value_t::discarded;
3151 }
3152 break;
3153 }
3154
3155 // parse values
3156 BasicJsonType value;
3157 while (true)
3158 {
3159 // parse value
3160 value.m_value.destroy(value.m_type);
3161 value.m_type = value_t::discarded;
3162 parse_internal(keep, value);
3163
3164 if (JSON_UNLIKELY(errored))
3165 {
3166 return;
3167 }
3168
3169 if (keep and not value.is_discarded())
3170 {
3171 result.m_value.array->push_back(std::move(value));
3172 }
3173
3174 // comma -> next value
3175 get_token();
3176 if (last_token == token_type::value_separator)
3177 {
3178 get_token();
3179 continue;
3180 }
3181
3182 // closing ]
3183 if (not expect(token_type::end_array))
3184 {
3185 return;
3186 }
3187 break;
3188 }
3189
3190 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
3191 {
3192 result.m_value.destroy(result.m_type);
3193 result.m_type = value_t::discarded;
3194 }
3195 break;
3196 }
3197
3198 case token_type::literal_null:
3199 {
3200 result.m_type = value_t::null;
3201 break;
3202 }
3203
3204 case token_type::value_string:
3205 {
3206 result.m_type = value_t::string;
3207 result.m_value = m_lexer.move_string();
3208 break;
3209 }
3210
3211 case token_type::literal_true:
3212 {
3213 result.m_type = value_t::boolean;
3214 result.m_value = true;
3215 break;
3216 }
3217
3218 case token_type::literal_false:
3219 {
3220 result.m_type = value_t::boolean;
3221 result.m_value = false;
3222 break;
3223 }
3224
3225 case token_type::value_unsigned:
3226 {
3227 result.m_type = value_t::number_unsigned;
3228 result.m_value = m_lexer.get_number_unsigned();
3229 break;
3230 }
3231
3232 case token_type::value_integer:
3233 {
3234 result.m_type = value_t::number_integer;
3235 result.m_value = m_lexer.get_number_integer();
3236 break;
3237 }
3238
3239 case token_type::value_float:
3240 {
3241 result.m_type = value_t::number_float;
3242 result.m_value = m_lexer.get_number_float();
3243
3244 // throw in case of infinity or NAN
3245 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
3246 {
3247 if (allow_exceptions)
3248 {
3249 JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
3250 m_lexer.get_token_string() + "'"));
3251 }
3252 expect(token_type::uninitialized);
3253 }
3254 break;
3255 }
3256
3257 case token_type::parse_error:
3258 {
3259 // using "uninitialized" to avoid "expected" message
3260 if (not expect(token_type::uninitialized))
3261 {
3262 return;
3263 }
3264 break; // LCOV_EXCL_LINE
3265 }
3266
3267 default:
3268 {
3269 // the last token was unexpected; we expected a value
3270 if (not expect(token_type::literal_or_value))
3271 {
3272 return;
3273 }
3274 break; // LCOV_EXCL_LINE
3275 }
3276 }
3277
3278 if (keep and callback and not callback(depth, parse_event_t::value, result))
3279 {
3280 result.m_type = value_t::discarded;
3281 }
3282 }
3283
3284 /*!
3285 @brief the acutal acceptor
3286
3287 @invariant 1. The last token is not yet processed. Therefore, the caller
3288 of this function must make sure a token has been read.
3289 2. When this function returns, the last token is processed.
3290 That is, the last read character was already considered.
3291
3292 This invariant makes sure that no token needs to be "unput".
3293 */
accept_internal()3294 bool accept_internal()
3295 {
3296 switch (last_token)
3297 {
3298 case token_type::begin_object:
3299 {
3300 // read next token
3301 get_token();
3302
3303 // closing } -> we are done
3304 if (last_token == token_type::end_object)
3305 {
3306 return true;
3307 }
3308
3309 // parse values
3310 while (true)
3311 {
3312 // parse key
3313 if (last_token != token_type::value_string)
3314 {
3315 return false;
3316 }
3317
3318 // parse separator (:)
3319 get_token();
3320 if (last_token != token_type::name_separator)
3321 {
3322 return false;
3323 }
3324
3325 // parse value
3326 get_token();
3327 if (not accept_internal())
3328 {
3329 return false;
3330 }
3331
3332 // comma -> next value
3333 get_token();
3334 if (last_token == token_type::value_separator)
3335 {
3336 get_token();
3337 continue;
3338 }
3339
3340 // closing }
3341 return (last_token == token_type::end_object);
3342 }
3343 }
3344
3345 case token_type::begin_array:
3346 {
3347 // read next token
3348 get_token();
3349
3350 // closing ] -> we are done
3351 if (last_token == token_type::end_array)
3352 {
3353 return true;
3354 }
3355
3356 // parse values
3357 while (true)
3358 {
3359 // parse value
3360 if (not accept_internal())
3361 {
3362 return false;
3363 }
3364
3365 // comma -> next value
3366 get_token();
3367 if (last_token == token_type::value_separator)
3368 {
3369 get_token();
3370 continue;
3371 }
3372
3373 // closing ]
3374 return (last_token == token_type::end_array);
3375 }
3376 }
3377
3378 case token_type::value_float:
3379 {
3380 // reject infinity or NAN
3381 return std::isfinite(m_lexer.get_number_float());
3382 }
3383
3384 case token_type::literal_false:
3385 case token_type::literal_null:
3386 case token_type::literal_true:
3387 case token_type::value_integer:
3388 case token_type::value_string:
3389 case token_type::value_unsigned:
3390 return true;
3391
3392 default: // the last token was unexpected
3393 return false;
3394 }
3395 }
3396
3397 /// get next token from lexer
get_token()3398 token_type get_token()
3399 {
3400 return (last_token = m_lexer.scan());
3401 }
3402
3403 /*!
3404 @throw parse_error.101 if expected token did not occur
3405 */
expect(token_type t)3406 bool expect(token_type t)
3407 {
3408 if (JSON_UNLIKELY(t != last_token))
3409 {
3410 errored = true;
3411 expected = t;
3412 if (allow_exceptions)
3413 {
3414 throw_exception();
3415 }
3416 else
3417 {
3418 return false;
3419 }
3420 }
3421
3422 return true;
3423 }
3424
throw_exception() const3425 [[noreturn]] void throw_exception() const
3426 {
3427 std::string error_msg = "syntax error - ";
3428 if (last_token == token_type::parse_error)
3429 {
3430 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
3431 m_lexer.get_token_string() + "'";
3432 }
3433 else
3434 {
3435 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
3436 }
3437
3438 if (expected != token_type::uninitialized)
3439 {
3440 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
3441 }
3442
3443 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3444 }
3445
3446 private:
3447 /// current level of recursion
3448 int depth = 0;
3449 /// callback function
3450 const parser_callback_t callback = nullptr;
3451 /// the type of the last read token
3452 token_type last_token = token_type::uninitialized;
3453 /// the lexer
3454 lexer_t m_lexer;
3455 /// whether a syntax error occurred
3456 bool errored = false;
3457 /// possible reason for the syntax error
3458 token_type expected = token_type::uninitialized;
3459 /// whether to throw exceptions in case of errors
3460 const bool allow_exceptions = true;
3461 };
3462
3463 ///////////////
3464 // iterators //
3465 ///////////////
3466
3467 /*!
3468 @brief an iterator for primitive JSON types
3469
3470 This class models an iterator for primitive JSON types (boolean, number,
3471 string). It's only purpose is to allow the iterator/const_iterator classes
3472 to "iterate" over primitive values. Internally, the iterator is modeled by
3473 a `difference_type` variable. Value begin_value (`0`) models the begin,
3474 end_value (`1`) models past the end.
3475 */
3476 class primitive_iterator_t
3477 {
3478 public:
3479 using difference_type = std::ptrdiff_t;
3480
get_value() const3481 constexpr difference_type get_value() const noexcept
3482 {
3483 return m_it;
3484 }
3485
3486 /// set iterator to a defined beginning
set_begin()3487 void set_begin() noexcept
3488 {
3489 m_it = begin_value;
3490 }
3491
3492 /// set iterator to a defined past the end
set_end()3493 void set_end() noexcept
3494 {
3495 m_it = end_value;
3496 }
3497
3498 /// return whether the iterator can be dereferenced
is_begin() const3499 constexpr bool is_begin() const noexcept
3500 {
3501 return m_it == begin_value;
3502 }
3503
3504 /// return whether the iterator is at end
is_end() const3505 constexpr bool is_end() const noexcept
3506 {
3507 return m_it == end_value;
3508 }
3509
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)3510 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3511 {
3512 return lhs.m_it == rhs.m_it;
3513 }
3514
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)3515 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3516 {
3517 return lhs.m_it < rhs.m_it;
3518 }
3519
operator +(difference_type i)3520 primitive_iterator_t operator+(difference_type i)
3521 {
3522 auto result = *this;
3523 result += i;
3524 return result;
3525 }
3526
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)3527 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3528 {
3529 return lhs.m_it - rhs.m_it;
3530 }
3531
operator <<(std::ostream & os,primitive_iterator_t it)3532 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
3533 {
3534 return os << it.m_it;
3535 }
3536
operator ++()3537 primitive_iterator_t& operator++()
3538 {
3539 ++m_it;
3540 return *this;
3541 }
3542
operator ++(int)3543 primitive_iterator_t operator++(int)
3544 {
3545 auto result = *this;
3546 m_it++;
3547 return result;
3548 }
3549
operator --()3550 primitive_iterator_t& operator--()
3551 {
3552 --m_it;
3553 return *this;
3554 }
3555
operator --(int)3556 primitive_iterator_t operator--(int)
3557 {
3558 auto result = *this;
3559 m_it--;
3560 return result;
3561 }
3562
operator +=(difference_type n)3563 primitive_iterator_t& operator+=(difference_type n)
3564 {
3565 m_it += n;
3566 return *this;
3567 }
3568
operator -=(difference_type n)3569 primitive_iterator_t& operator-=(difference_type n)
3570 {
3571 m_it -= n;
3572 return *this;
3573 }
3574
3575 private:
3576 static constexpr difference_type begin_value = 0;
3577 static constexpr difference_type end_value = begin_value + 1;
3578
3579 /// iterator as signed integer type
3580 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3581 };
3582
3583 /*!
3584 @brief an iterator value
3585
3586 @note This structure could easily be a union, but MSVC currently does not allow
3587 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
3588 */
3589 template<typename BasicJsonType> struct internal_iterator
3590 {
3591 /// iterator for JSON objects
3592 typename BasicJsonType::object_t::iterator object_iterator {};
3593 /// iterator for JSON arrays
3594 typename BasicJsonType::array_t::iterator array_iterator {};
3595 /// generic iterator for all other types
3596 primitive_iterator_t primitive_iterator {};
3597 };
3598
3599 template<typename IteratorType> class iteration_proxy;
3600
3601 /*!
3602 @brief a template for a bidirectional iterator for the @ref basic_json class
3603
3604 This class implements a both iterators (iterator and const_iterator) for the
3605 @ref basic_json class.
3606
3607 @note An iterator is called *initialized* when a pointer to a JSON value has
3608 been set (e.g., by a constructor or a copy assignment). If the iterator is
3609 default-constructed, it is *uninitialized* and most methods are undefined.
3610 **The library uses assertions to detect calls on uninitialized iterators.**
3611
3612 @requirement The class satisfies the following concept requirements:
3613 -
3614 [BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator):
3615 The iterator that can be moved can be moved in both directions (i.e.
3616 incremented and decremented).
3617
3618 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
3619 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
3620 */
3621 template<typename BasicJsonType>
3622 class iter_impl : public std::iterator<std::bidirectional_iterator_tag, BasicJsonType>
3623 {
3624 /// allow basic_json to access private members
3625 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
3626 friend BasicJsonType;
3627 friend iteration_proxy<iter_impl>;
3628
3629 using object_t = typename BasicJsonType::object_t;
3630 using array_t = typename BasicJsonType::array_t;
3631 // make sure BasicJsonType is basic_json or const basic_json
3632 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
3633 "iter_impl only accepts (const) basic_json");
3634
3635 public:
3636 /// the type of the values when the iterator is dereferenced
3637 using value_type = typename BasicJsonType::value_type;
3638 /// a type to represent differences between iterators
3639 using difference_type = typename BasicJsonType::difference_type;
3640 /// defines a pointer to the type iterated over (value_type)
3641 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
3642 typename BasicJsonType::const_pointer,
3643 typename BasicJsonType::pointer>::type;
3644 /// defines a reference to the type iterated over (value_type)
3645 using reference =
3646 typename std::conditional<std::is_const<BasicJsonType>::value,
3647 typename BasicJsonType::const_reference,
3648 typename BasicJsonType::reference>::type;
3649
3650 /// default constructor
3651 iter_impl() = default;
3652
3653 /*!
3654 @brief constructor for a given JSON instance
3655 @param[in] object pointer to a JSON object for this iterator
3656 @pre object != nullptr
3657 @post The iterator is initialized; i.e. `m_object != nullptr`.
3658 */
iter_impl(pointer object)3659 explicit iter_impl(pointer object) noexcept : m_object(object)
3660 {
3661 assert(m_object != nullptr);
3662
3663 switch (m_object->m_type)
3664 {
3665 case value_t::object:
3666 {
3667 m_it.object_iterator = typename object_t::iterator();
3668 break;
3669 }
3670
3671 case value_t::array:
3672 {
3673 m_it.array_iterator = typename array_t::iterator();
3674 break;
3675 }
3676
3677 default:
3678 {
3679 m_it.primitive_iterator = primitive_iterator_t();
3680 break;
3681 }
3682 }
3683 }
3684
3685 /*!
3686 @note The conventional copy constructor and copy assignment are implicitly
3687 defined. Combined with the following converting constructor and
3688 assignment, they support: (1) copy from iterator to iterator, (2)
3689 copy from const iterator to const iterator, and (3) conversion from
3690 iterator to const iterator. However conversion from const iterator
3691 to iterator is not defined.
3692 */
3693
3694 /*!
3695 @brief converting constructor
3696 @param[in] other non-const iterator to copy from
3697 @note It is not checked whether @a other is initialized.
3698 */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)3699 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3700 : m_object(other.m_object), m_it(other.m_it) {}
3701
3702 /*!
3703 @brief converting assignment
3704 @param[in,out] other non-const iterator to copy from
3705 @return const/non-const iterator
3706 @note It is not checked whether @a other is initialized.
3707 */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)3708 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3709 {
3710 m_object = other.m_object;
3711 m_it = other.m_it;
3712 return *this;
3713 }
3714
3715 private:
3716 /*!
3717 @brief set the iterator to the first value
3718 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3719 */
set_begin()3720 void set_begin() noexcept
3721 {
3722 assert(m_object != nullptr);
3723
3724 switch (m_object->m_type)
3725 {
3726 case value_t::object:
3727 {
3728 m_it.object_iterator = m_object->m_value.object->begin();
3729 break;
3730 }
3731
3732 case value_t::array:
3733 {
3734 m_it.array_iterator = m_object->m_value.array->begin();
3735 break;
3736 }
3737
3738 case value_t::null:
3739 {
3740 // set to end so begin()==end() is true: null is empty
3741 m_it.primitive_iterator.set_end();
3742 break;
3743 }
3744
3745 default:
3746 {
3747 m_it.primitive_iterator.set_begin();
3748 break;
3749 }
3750 }
3751 }
3752
3753 /*!
3754 @brief set the iterator past the last value
3755 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3756 */
set_end()3757 void set_end() noexcept
3758 {
3759 assert(m_object != nullptr);
3760
3761 switch (m_object->m_type)
3762 {
3763 case value_t::object:
3764 {
3765 m_it.object_iterator = m_object->m_value.object->end();
3766 break;
3767 }
3768
3769 case value_t::array:
3770 {
3771 m_it.array_iterator = m_object->m_value.array->end();
3772 break;
3773 }
3774
3775 default:
3776 {
3777 m_it.primitive_iterator.set_end();
3778 break;
3779 }
3780 }
3781 }
3782
3783 public:
3784 /*!
3785 @brief return a reference to the value pointed to by the iterator
3786 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3787 */
operator *() const3788 reference operator*() const
3789 {
3790 assert(m_object != nullptr);
3791
3792 switch (m_object->m_type)
3793 {
3794 case value_t::object:
3795 {
3796 assert(m_it.object_iterator != m_object->m_value.object->end());
3797 return m_it.object_iterator->second;
3798 }
3799
3800 case value_t::array:
3801 {
3802 assert(m_it.array_iterator != m_object->m_value.array->end());
3803 return *m_it.array_iterator;
3804 }
3805
3806 case value_t::null:
3807 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3808
3809 default:
3810 {
3811 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3812 {
3813 return *m_object;
3814 }
3815
3816 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3817 }
3818 }
3819 }
3820
3821 /*!
3822 @brief dereference the iterator
3823 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3824 */
operator ->() const3825 pointer operator->() const
3826 {
3827 assert(m_object != nullptr);
3828
3829 switch (m_object->m_type)
3830 {
3831 case value_t::object:
3832 {
3833 assert(m_it.object_iterator != m_object->m_value.object->end());
3834 return &(m_it.object_iterator->second);
3835 }
3836
3837 case value_t::array:
3838 {
3839 assert(m_it.array_iterator != m_object->m_value.array->end());
3840 return &*m_it.array_iterator;
3841 }
3842
3843 default:
3844 {
3845 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3846 {
3847 return m_object;
3848 }
3849
3850 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3851 }
3852 }
3853 }
3854
3855 /*!
3856 @brief post-increment (it++)
3857 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3858 */
operator ++(int)3859 iter_impl operator++(int)
3860 {
3861 auto result = *this;
3862 ++(*this);
3863 return result;
3864 }
3865
3866 /*!
3867 @brief pre-increment (++it)
3868 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3869 */
operator ++()3870 iter_impl& operator++()
3871 {
3872 assert(m_object != nullptr);
3873
3874 switch (m_object->m_type)
3875 {
3876 case value_t::object:
3877 {
3878 std::advance(m_it.object_iterator, 1);
3879 break;
3880 }
3881
3882 case value_t::array:
3883 {
3884 std::advance(m_it.array_iterator, 1);
3885 break;
3886 }
3887
3888 default:
3889 {
3890 ++m_it.primitive_iterator;
3891 break;
3892 }
3893 }
3894
3895 return *this;
3896 }
3897
3898 /*!
3899 @brief post-decrement (it--)
3900 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3901 */
operator --(int)3902 iter_impl operator--(int)
3903 {
3904 auto result = *this;
3905 --(*this);
3906 return result;
3907 }
3908
3909 /*!
3910 @brief pre-decrement (--it)
3911 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3912 */
operator --()3913 iter_impl& operator--()
3914 {
3915 assert(m_object != nullptr);
3916
3917 switch (m_object->m_type)
3918 {
3919 case value_t::object:
3920 {
3921 std::advance(m_it.object_iterator, -1);
3922 break;
3923 }
3924
3925 case value_t::array:
3926 {
3927 std::advance(m_it.array_iterator, -1);
3928 break;
3929 }
3930
3931 default:
3932 {
3933 --m_it.primitive_iterator;
3934 break;
3935 }
3936 }
3937
3938 return *this;
3939 }
3940
3941 /*!
3942 @brief comparison: equal
3943 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3944 */
operator ==(const iter_impl & other) const3945 bool operator==(const iter_impl& other) const
3946 {
3947 // if objects are not the same, the comparison is undefined
3948 if (JSON_UNLIKELY(m_object != other.m_object))
3949 {
3950 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
3951 }
3952
3953 assert(m_object != nullptr);
3954
3955 switch (m_object->m_type)
3956 {
3957 case value_t::object:
3958 return (m_it.object_iterator == other.m_it.object_iterator);
3959
3960 case value_t::array:
3961 return (m_it.array_iterator == other.m_it.array_iterator);
3962
3963 default:
3964 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
3965 }
3966 }
3967
3968 /*!
3969 @brief comparison: not equal
3970 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3971 */
operator !=(const iter_impl & other) const3972 bool operator!=(const iter_impl& other) const
3973 {
3974 return not operator==(other);
3975 }
3976
3977 /*!
3978 @brief comparison: smaller
3979 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3980 */
operator <(const iter_impl & other) const3981 bool operator<(const iter_impl& other) const
3982 {
3983 // if objects are not the same, the comparison is undefined
3984 if (JSON_UNLIKELY(m_object != other.m_object))
3985 {
3986 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
3987 }
3988
3989 assert(m_object != nullptr);
3990
3991 switch (m_object->m_type)
3992 {
3993 case value_t::object:
3994 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
3995
3996 case value_t::array:
3997 return (m_it.array_iterator < other.m_it.array_iterator);
3998
3999 default:
4000 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
4001 }
4002 }
4003
4004 /*!
4005 @brief comparison: less than or equal
4006 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4007 */
operator <=(const iter_impl & other) const4008 bool operator<=(const iter_impl& other) const
4009 {
4010 return not other.operator < (*this);
4011 }
4012
4013 /*!
4014 @brief comparison: greater than
4015 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4016 */
operator >(const iter_impl & other) const4017 bool operator>(const iter_impl& other) const
4018 {
4019 return not operator<=(other);
4020 }
4021
4022 /*!
4023 @brief comparison: greater than or equal
4024 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4025 */
operator >=(const iter_impl & other) const4026 bool operator>=(const iter_impl& other) const
4027 {
4028 return not operator<(other);
4029 }
4030
4031 /*!
4032 @brief add to iterator
4033 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4034 */
operator +=(difference_type i)4035 iter_impl& operator+=(difference_type i)
4036 {
4037 assert(m_object != nullptr);
4038
4039 switch (m_object->m_type)
4040 {
4041 case value_t::object:
4042 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4043
4044 case value_t::array:
4045 {
4046 std::advance(m_it.array_iterator, i);
4047 break;
4048 }
4049
4050 default:
4051 {
4052 m_it.primitive_iterator += i;
4053 break;
4054 }
4055 }
4056
4057 return *this;
4058 }
4059
4060 /*!
4061 @brief subtract from iterator
4062 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4063 */
operator -=(difference_type i)4064 iter_impl& operator-=(difference_type i)
4065 {
4066 return operator+=(-i);
4067 }
4068
4069 /*!
4070 @brief add to iterator
4071 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4072 */
operator +(difference_type i) const4073 iter_impl operator+(difference_type i) const
4074 {
4075 auto result = *this;
4076 result += i;
4077 return result;
4078 }
4079
4080 /*!
4081 @brief addition of distance and iterator
4082 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4083 */
operator +(difference_type i,const iter_impl & it)4084 friend iter_impl operator+(difference_type i, const iter_impl& it)
4085 {
4086 auto result = it;
4087 result += i;
4088 return result;
4089 }
4090
4091 /*!
4092 @brief subtract from iterator
4093 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4094 */
operator -(difference_type i) const4095 iter_impl operator-(difference_type i) const
4096 {
4097 auto result = *this;
4098 result -= i;
4099 return result;
4100 }
4101
4102 /*!
4103 @brief return difference
4104 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4105 */
operator -(const iter_impl & other) const4106 difference_type operator-(const iter_impl& other) const
4107 {
4108 assert(m_object != nullptr);
4109
4110 switch (m_object->m_type)
4111 {
4112 case value_t::object:
4113 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4114
4115 case value_t::array:
4116 return m_it.array_iterator - other.m_it.array_iterator;
4117
4118 default:
4119 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4120 }
4121 }
4122
4123 /*!
4124 @brief access to successor
4125 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4126 */
operator [](difference_type n) const4127 reference operator[](difference_type n) const
4128 {
4129 assert(m_object != nullptr);
4130
4131 switch (m_object->m_type)
4132 {
4133 case value_t::object:
4134 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
4135
4136 case value_t::array:
4137 return *std::next(m_it.array_iterator, n);
4138
4139 case value_t::null:
4140 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4141
4142 default:
4143 {
4144 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4145 {
4146 return *m_object;
4147 }
4148
4149 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4150 }
4151 }
4152 }
4153
4154 /*!
4155 @brief return the key of an object iterator
4156 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4157 */
key() const4158 typename object_t::key_type key() const
4159 {
4160 assert(m_object != nullptr);
4161
4162 if (JSON_LIKELY(m_object->is_object()))
4163 {
4164 return m_it.object_iterator->first;
4165 }
4166
4167 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
4168 }
4169
4170 /*!
4171 @brief return the value of an iterator
4172 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4173 */
value() const4174 reference value() const
4175 {
4176 return operator*();
4177 }
4178
4179 private:
4180 /// associated JSON instance
4181 pointer m_object = nullptr;
4182 /// the actual iterator of the associated instance
4183 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it = {};
4184 };
4185
4186 /// proxy class for the iterator_wrapper functions
4187 template<typename IteratorType> class iteration_proxy
4188 {
4189 private:
4190 /// helper class for iteration
4191 class iteration_proxy_internal
4192 {
4193 private:
4194 /// the iterator
4195 IteratorType anchor;
4196 /// an index for arrays (used to create key names)
4197 std::size_t array_index = 0;
4198
4199 public:
iteration_proxy_internal(IteratorType it)4200 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4201
4202 /// dereference operator (needed for range-based for)
operator *()4203 iteration_proxy_internal& operator*()
4204 {
4205 return *this;
4206 }
4207
4208 /// increment operator (needed for range-based for)
operator ++()4209 iteration_proxy_internal& operator++()
4210 {
4211 ++anchor;
4212 ++array_index;
4213
4214 return *this;
4215 }
4216
4217 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_internal & o) const4218 bool operator!=(const iteration_proxy_internal& o) const noexcept
4219 {
4220 return anchor != o.anchor;
4221 }
4222
4223 /// return key of the iterator
key() const4224 std::string key() const
4225 {
4226 assert(anchor.m_object != nullptr);
4227
4228 switch (anchor.m_object->type())
4229 {
4230 // use integer array index as key
4231 case value_t::array:
4232 return std::to_string(array_index);
4233
4234 // use key from the object
4235 case value_t::object:
4236 return anchor.key();
4237
4238 // use an empty key for all primitive types
4239 default:
4240 return "";
4241 }
4242 }
4243
4244 /// return value of the iterator
value() const4245 typename IteratorType::reference value() const
4246 {
4247 return anchor.value();
4248 }
4249 };
4250
4251 /// the container to iterate
4252 typename IteratorType::reference container;
4253
4254 public:
4255 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)4256 explicit iteration_proxy(typename IteratorType::reference cont)
4257 : container(cont) {}
4258
4259 /// return iterator begin (needed for range-based for)
begin()4260 iteration_proxy_internal begin() noexcept
4261 {
4262 return iteration_proxy_internal(container.begin());
4263 }
4264
4265 /// return iterator end (needed for range-based for)
end()4266 iteration_proxy_internal end() noexcept
4267 {
4268 return iteration_proxy_internal(container.end());
4269 }
4270 };
4271
4272 /*!
4273 @brief a template for a reverse iterator class
4274
4275 @tparam Base the base iterator type to reverse. Valid types are @ref
4276 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
4277 create @ref const_reverse_iterator).
4278
4279 @requirement The class satisfies the following concept requirements:
4280 -
4281 [BidirectionalIterator](http://en.cppreference.com/w/cpp/concept/BidirectionalIterator):
4282 The iterator that can be moved can be moved in both directions (i.e.
4283 incremented and decremented).
4284 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
4285 It is possible to write to the pointed-to element (only if @a Base is
4286 @ref iterator).
4287
4288 @since version 1.0.0
4289 */
4290 template<typename Base>
4291 class json_reverse_iterator : public std::reverse_iterator<Base>
4292 {
4293 public:
4294 using difference_type = std::ptrdiff_t;
4295 /// shortcut to the reverse iterator adaptor
4296 using base_iterator = std::reverse_iterator<Base>;
4297 /// the reference type for the pointed-to element
4298 using reference = typename Base::reference;
4299
4300 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)4301 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
4302 : base_iterator(it) {}
4303
4304 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)4305 json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
4306
4307 /// post-increment (it++)
operator ++(int)4308 json_reverse_iterator operator++(int)
4309 {
4310 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4311 }
4312
4313 /// pre-increment (++it)
operator ++()4314 json_reverse_iterator& operator++()
4315 {
4316 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4317 }
4318
4319 /// post-decrement (it--)
operator --(int)4320 json_reverse_iterator operator--(int)
4321 {
4322 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4323 }
4324
4325 /// pre-decrement (--it)
operator --()4326 json_reverse_iterator& operator--()
4327 {
4328 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4329 }
4330
4331 /// add to iterator
operator +=(difference_type i)4332 json_reverse_iterator& operator+=(difference_type i)
4333 {
4334 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4335 }
4336
4337 /// add to iterator
operator +(difference_type i) const4338 json_reverse_iterator operator+(difference_type i) const
4339 {
4340 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4341 }
4342
4343 /// subtract from iterator
operator -(difference_type i) const4344 json_reverse_iterator operator-(difference_type i) const
4345 {
4346 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4347 }
4348
4349 /// return difference
operator -(const json_reverse_iterator & other) const4350 difference_type operator-(const json_reverse_iterator& other) const
4351 {
4352 return base_iterator(*this) - base_iterator(other);
4353 }
4354
4355 /// access to successor
operator [](difference_type n) const4356 reference operator[](difference_type n) const
4357 {
4358 return *(this->operator+(n));
4359 }
4360
4361 /// return the key of an object iterator
key() const4362 auto key() const -> decltype(std::declval<Base>().key())
4363 {
4364 auto it = --this->base();
4365 return it.key();
4366 }
4367
4368 /// return the value of an iterator
value() const4369 reference value() const
4370 {
4371 auto it = --this->base();
4372 return it.operator * ();
4373 }
4374 };
4375
4376 /////////////////////
4377 // output adapters //
4378 /////////////////////
4379
4380 /// abstract output adapter interface
4381 template<typename CharType> struct output_adapter_protocol
4382 {
4383 virtual void write_character(CharType c) = 0;
4384 virtual void write_characters(const CharType* s, std::size_t length) = 0;
4385 virtual ~output_adapter_protocol() = default;
4386 };
4387
4388 /// a type to simplify interfaces
4389 template<typename CharType>
4390 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4391
4392 /// output adapter for byte vectors
4393 template<typename CharType>
4394 class output_vector_adapter : public output_adapter_protocol<CharType>
4395 {
4396 public:
output_vector_adapter(std::vector<CharType> & vec)4397 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4398
write_character(CharType c)4399 void write_character(CharType c) override
4400 {
4401 v.push_back(c);
4402 }
4403
write_characters(const CharType * s,std::size_t length)4404 void write_characters(const CharType* s, std::size_t length) override
4405 {
4406 std::copy(s, s + length, std::back_inserter(v));
4407 }
4408
4409 private:
4410 std::vector<CharType>& v;
4411 };
4412
4413 /// output adapter for output streams
4414 template<typename CharType>
4415 class output_stream_adapter : public output_adapter_protocol<CharType>
4416 {
4417 public:
output_stream_adapter(std::basic_ostream<CharType> & s)4418 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4419
write_character(CharType c)4420 void write_character(CharType c) override
4421 {
4422 stream.put(c);
4423 }
4424
write_characters(const CharType * s,std::size_t length)4425 void write_characters(const CharType* s, std::size_t length) override
4426 {
4427 stream.write(s, static_cast<std::streamsize>(length));
4428 }
4429
4430 private:
4431 std::basic_ostream<CharType>& stream;
4432 };
4433
4434 /// output adapter for basic_string
4435 template<typename CharType>
4436 class output_string_adapter : public output_adapter_protocol<CharType>
4437 {
4438 public:
output_string_adapter(std::basic_string<CharType> & s)4439 explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
4440
write_character(CharType c)4441 void write_character(CharType c) override
4442 {
4443 str.push_back(c);
4444 }
4445
write_characters(const CharType * s,std::size_t length)4446 void write_characters(const CharType* s, std::size_t length) override
4447 {
4448 str.append(s, length);
4449 }
4450
4451 private:
4452 std::basic_string<CharType>& str;
4453 };
4454
4455 template<typename CharType>
4456 class output_adapter
4457 {
4458 public:
output_adapter(std::vector<CharType> & vec)4459 output_adapter(std::vector<CharType>& vec)
4460 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4461
output_adapter(std::basic_ostream<CharType> & s)4462 output_adapter(std::basic_ostream<CharType>& s)
4463 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4464
output_adapter(std::basic_string<CharType> & s)4465 output_adapter(std::basic_string<CharType>& s)
4466 : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
4467
operator output_adapter_t<CharType>()4468 operator output_adapter_t<CharType>()
4469 {
4470 return oa;
4471 }
4472
4473 private:
4474 output_adapter_t<CharType> oa = nullptr;
4475 };
4476
4477 //////////////////////////////
4478 // binary reader and writer //
4479 //////////////////////////////
4480
4481 /*!
4482 @brief deserialization of CBOR and MessagePack values
4483 */
4484 template<typename BasicJsonType>
4485 class binary_reader
4486 {
4487 using number_integer_t = typename BasicJsonType::number_integer_t;
4488 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4489
4490 public:
4491 /*!
4492 @brief create a binary reader
4493
4494 @param[in] adapter input adapter to read from
4495 */
binary_reader(input_adapter_t adapter)4496 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4497 {
4498 assert(ia);
4499 }
4500
4501 /*!
4502 @brief create a JSON value from CBOR input
4503
4504 @param[in] strict whether to expect the input to be consumed completed
4505 @return JSON value created from CBOR input
4506
4507 @throw parse_error.110 if input ended unexpectedly or the end of file was
4508 not reached when @a strict was set to true
4509 @throw parse_error.112 if unsupported byte was read
4510 */
parse_cbor(const bool strict)4511 BasicJsonType parse_cbor(const bool strict)
4512 {
4513 const auto res = parse_cbor_internal();
4514 if (strict)
4515 {
4516 get();
4517 check_eof(true);
4518 }
4519 return res;
4520 }
4521
4522 /*!
4523 @brief create a JSON value from MessagePack input
4524
4525 @param[in] strict whether to expect the input to be consumed completed
4526 @return JSON value created from MessagePack input
4527
4528 @throw parse_error.110 if input ended unexpectedly or the end of file was
4529 not reached when @a strict was set to true
4530 @throw parse_error.112 if unsupported byte was read
4531 */
parse_msgpack(const bool strict)4532 BasicJsonType parse_msgpack(const bool strict)
4533 {
4534 const auto res = parse_msgpack_internal();
4535 if (strict)
4536 {
4537 get();
4538 check_eof(true);
4539 }
4540 return res;
4541 }
4542
4543 /*!
4544 @brief determine system byte order
4545
4546 @return true if and only if system's byte order is little endian
4547
4548 @note from http://stackoverflow.com/a/1001328/266378
4549 */
little_endianess(int num=1)4550 static constexpr bool little_endianess(int num = 1) noexcept
4551 {
4552 return (*reinterpret_cast<char*>(&num) == 1);
4553 }
4554
4555 private:
4556 /*!
4557 @param[in] get_char whether a new character should be retrieved from the
4558 input (true, default) or whether the last read
4559 character should be considered instead
4560 */
parse_cbor_internal(const bool get_char=true)4561 BasicJsonType parse_cbor_internal(const bool get_char = true)
4562 {
4563 switch (get_char ? get() : current)
4564 {
4565 // EOF
4566 case std::char_traits<char>::eof():
4567 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4568
4569 // Integer 0x00..0x17 (0..23)
4570 case 0x00:
4571 case 0x01:
4572 case 0x02:
4573 case 0x03:
4574 case 0x04:
4575 case 0x05:
4576 case 0x06:
4577 case 0x07:
4578 case 0x08:
4579 case 0x09:
4580 case 0x0a:
4581 case 0x0b:
4582 case 0x0c:
4583 case 0x0d:
4584 case 0x0e:
4585 case 0x0f:
4586 case 0x10:
4587 case 0x11:
4588 case 0x12:
4589 case 0x13:
4590 case 0x14:
4591 case 0x15:
4592 case 0x16:
4593 case 0x17:
4594 return static_cast<number_unsigned_t>(current);
4595
4596 case 0x18: // Unsigned integer (one-byte uint8_t follows)
4597 return get_number<uint8_t>();
4598
4599 case 0x19: // Unsigned integer (two-byte uint16_t follows)
4600 return get_number<uint16_t>();
4601
4602 case 0x1a: // Unsigned integer (four-byte uint32_t follows)
4603 return get_number<uint32_t>();
4604
4605 case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
4606 return get_number<uint64_t>();
4607
4608 // Negative integer -1-0x00..-1-0x17 (-1..-24)
4609 case 0x20:
4610 case 0x21:
4611 case 0x22:
4612 case 0x23:
4613 case 0x24:
4614 case 0x25:
4615 case 0x26:
4616 case 0x27:
4617 case 0x28:
4618 case 0x29:
4619 case 0x2a:
4620 case 0x2b:
4621 case 0x2c:
4622 case 0x2d:
4623 case 0x2e:
4624 case 0x2f:
4625 case 0x30:
4626 case 0x31:
4627 case 0x32:
4628 case 0x33:
4629 case 0x34:
4630 case 0x35:
4631 case 0x36:
4632 case 0x37:
4633 return static_cast<int8_t>(0x20 - 1 - current);
4634
4635 case 0x38: // Negative integer (one-byte uint8_t follows)
4636 {
4637 // must be uint8_t !
4638 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4639 }
4640
4641 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
4642 {
4643 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4644 }
4645
4646 case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
4647 {
4648 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4649 }
4650
4651 case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
4652 {
4653 return static_cast<number_integer_t>(-1) -
4654 static_cast<number_integer_t>(get_number<uint64_t>());
4655 }
4656
4657 // UTF-8 string (0x00..0x17 bytes follow)
4658 case 0x60:
4659 case 0x61:
4660 case 0x62:
4661 case 0x63:
4662 case 0x64:
4663 case 0x65:
4664 case 0x66:
4665 case 0x67:
4666 case 0x68:
4667 case 0x69:
4668 case 0x6a:
4669 case 0x6b:
4670 case 0x6c:
4671 case 0x6d:
4672 case 0x6e:
4673 case 0x6f:
4674 case 0x70:
4675 case 0x71:
4676 case 0x72:
4677 case 0x73:
4678 case 0x74:
4679 case 0x75:
4680 case 0x76:
4681 case 0x77:
4682 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4683 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4684 case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
4685 case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
4686 case 0x7f: // UTF-8 string (indefinite length)
4687 {
4688 return get_cbor_string();
4689 }
4690
4691 // array (0x00..0x17 data items follow)
4692 case 0x80:
4693 case 0x81:
4694 case 0x82:
4695 case 0x83:
4696 case 0x84:
4697 case 0x85:
4698 case 0x86:
4699 case 0x87:
4700 case 0x88:
4701 case 0x89:
4702 case 0x8a:
4703 case 0x8b:
4704 case 0x8c:
4705 case 0x8d:
4706 case 0x8e:
4707 case 0x8f:
4708 case 0x90:
4709 case 0x91:
4710 case 0x92:
4711 case 0x93:
4712 case 0x94:
4713 case 0x95:
4714 case 0x96:
4715 case 0x97:
4716 {
4717 return get_cbor_array(current & 0x1f);
4718 }
4719
4720 case 0x98: // array (one-byte uint8_t for n follows)
4721 {
4722 return get_cbor_array(get_number<uint8_t>());
4723 }
4724
4725 case 0x99: // array (two-byte uint16_t for n follow)
4726 {
4727 return get_cbor_array(get_number<uint16_t>());
4728 }
4729
4730 case 0x9a: // array (four-byte uint32_t for n follow)
4731 {
4732 return get_cbor_array(get_number<uint32_t>());
4733 }
4734
4735 case 0x9b: // array (eight-byte uint64_t for n follow)
4736 {
4737 return get_cbor_array(get_number<uint64_t>());
4738 }
4739
4740 case 0x9f: // array (indefinite length)
4741 {
4742 BasicJsonType result = value_t::array;
4743 while (get() != 0xff)
4744 {
4745 result.push_back(parse_cbor_internal(false));
4746 }
4747 return result;
4748 }
4749
4750 // map (0x00..0x17 pairs of data items follow)
4751 case 0xa0:
4752 case 0xa1:
4753 case 0xa2:
4754 case 0xa3:
4755 case 0xa4:
4756 case 0xa5:
4757 case 0xa6:
4758 case 0xa7:
4759 case 0xa8:
4760 case 0xa9:
4761 case 0xaa:
4762 case 0xab:
4763 case 0xac:
4764 case 0xad:
4765 case 0xae:
4766 case 0xaf:
4767 case 0xb0:
4768 case 0xb1:
4769 case 0xb2:
4770 case 0xb3:
4771 case 0xb4:
4772 case 0xb5:
4773 case 0xb6:
4774 case 0xb7:
4775 {
4776 return get_cbor_object(current & 0x1f);
4777 }
4778
4779 case 0xb8: // map (one-byte uint8_t for n follows)
4780 {
4781 return get_cbor_object(get_number<uint8_t>());
4782 }
4783
4784 case 0xb9: // map (two-byte uint16_t for n follow)
4785 {
4786 return get_cbor_object(get_number<uint16_t>());
4787 }
4788
4789 case 0xba: // map (four-byte uint32_t for n follow)
4790 {
4791 return get_cbor_object(get_number<uint32_t>());
4792 }
4793
4794 case 0xbb: // map (eight-byte uint64_t for n follow)
4795 {
4796 return get_cbor_object(get_number<uint64_t>());
4797 }
4798
4799 case 0xbf: // map (indefinite length)
4800 {
4801 BasicJsonType result = value_t::object;
4802 while (get() != 0xff)
4803 {
4804 auto key = get_cbor_string();
4805 result[key] = parse_cbor_internal();
4806 }
4807 return result;
4808 }
4809
4810 case 0xf4: // false
4811 {
4812 return false;
4813 }
4814
4815 case 0xf5: // true
4816 {
4817 return true;
4818 }
4819
4820 case 0xf6: // null
4821 {
4822 return value_t::null;
4823 }
4824
4825 case 0xf9: // Half-Precision Float (two-byte IEEE 754)
4826 {
4827 const int byte1 = get();
4828 check_eof();
4829 const int byte2 = get();
4830 check_eof();
4831
4832 // code from RFC 7049, Appendix D, Figure 3:
4833 // As half-precision floating-point numbers were only added
4834 // to IEEE 754 in 2008, today's programming platforms often
4835 // still only have limited support for them. It is very
4836 // easy to include at least decoding support for them even
4837 // without such support. An example of a small decoder for
4838 // half-precision floating-point numbers in the C language
4839 // is shown in Fig. 3.
4840 const int half = (byte1 << 8) + byte2;
4841 const int exp = (half >> 10) & 0x1f;
4842 const int mant = half & 0x3ff;
4843 double val;
4844 if (exp == 0)
4845 {
4846 val = std::ldexp(mant, -24);
4847 }
4848 else if (exp != 31)
4849 {
4850 val = std::ldexp(mant + 1024, exp - 25);
4851 }
4852 else
4853 {
4854 val = (mant == 0) ? std::numeric_limits<double>::infinity()
4855 : std::numeric_limits<double>::quiet_NaN();
4856 }
4857 return (half & 0x8000) != 0 ? -val : val;
4858 }
4859
4860 case 0xfa: // Single-Precision Float (four-byte IEEE 754)
4861 {
4862 return get_number<float>();
4863 }
4864
4865 case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
4866 {
4867 return get_number<double>();
4868 }
4869
4870 default: // anything else (0xFF is handled inside the other types)
4871 {
4872 std::stringstream ss;
4873 ss << std::setw(2) << std::setfill('0') << std::hex << current;
4874 JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
4875 }
4876 }
4877 }
4878
parse_msgpack_internal()4879 BasicJsonType parse_msgpack_internal()
4880 {
4881 switch (get())
4882 {
4883 // EOF
4884 case std::char_traits<char>::eof():
4885 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4886
4887 // positive fixint
4888 case 0x00:
4889 case 0x01:
4890 case 0x02:
4891 case 0x03:
4892 case 0x04:
4893 case 0x05:
4894 case 0x06:
4895 case 0x07:
4896 case 0x08:
4897 case 0x09:
4898 case 0x0a:
4899 case 0x0b:
4900 case 0x0c:
4901 case 0x0d:
4902 case 0x0e:
4903 case 0x0f:
4904 case 0x10:
4905 case 0x11:
4906 case 0x12:
4907 case 0x13:
4908 case 0x14:
4909 case 0x15:
4910 case 0x16:
4911 case 0x17:
4912 case 0x18:
4913 case 0x19:
4914 case 0x1a:
4915 case 0x1b:
4916 case 0x1c:
4917 case 0x1d:
4918 case 0x1e:
4919 case 0x1f:
4920 case 0x20:
4921 case 0x21:
4922 case 0x22:
4923 case 0x23:
4924 case 0x24:
4925 case 0x25:
4926 case 0x26:
4927 case 0x27:
4928 case 0x28:
4929 case 0x29:
4930 case 0x2a:
4931 case 0x2b:
4932 case 0x2c:
4933 case 0x2d:
4934 case 0x2e:
4935 case 0x2f:
4936 case 0x30:
4937 case 0x31:
4938 case 0x32:
4939 case 0x33:
4940 case 0x34:
4941 case 0x35:
4942 case 0x36:
4943 case 0x37:
4944 case 0x38:
4945 case 0x39:
4946 case 0x3a:
4947 case 0x3b:
4948 case 0x3c:
4949 case 0x3d:
4950 case 0x3e:
4951 case 0x3f:
4952 case 0x40:
4953 case 0x41:
4954 case 0x42:
4955 case 0x43:
4956 case 0x44:
4957 case 0x45:
4958 case 0x46:
4959 case 0x47:
4960 case 0x48:
4961 case 0x49:
4962 case 0x4a:
4963 case 0x4b:
4964 case 0x4c:
4965 case 0x4d:
4966 case 0x4e:
4967 case 0x4f:
4968 case 0x50:
4969 case 0x51:
4970 case 0x52:
4971 case 0x53:
4972 case 0x54:
4973 case 0x55:
4974 case 0x56:
4975 case 0x57:
4976 case 0x58:
4977 case 0x59:
4978 case 0x5a:
4979 case 0x5b:
4980 case 0x5c:
4981 case 0x5d:
4982 case 0x5e:
4983 case 0x5f:
4984 case 0x60:
4985 case 0x61:
4986 case 0x62:
4987 case 0x63:
4988 case 0x64:
4989 case 0x65:
4990 case 0x66:
4991 case 0x67:
4992 case 0x68:
4993 case 0x69:
4994 case 0x6a:
4995 case 0x6b:
4996 case 0x6c:
4997 case 0x6d:
4998 case 0x6e:
4999 case 0x6f:
5000 case 0x70:
5001 case 0x71:
5002 case 0x72:
5003 case 0x73:
5004 case 0x74:
5005 case 0x75:
5006 case 0x76:
5007 case 0x77:
5008 case 0x78:
5009 case 0x79:
5010 case 0x7a:
5011 case 0x7b:
5012 case 0x7c:
5013 case 0x7d:
5014 case 0x7e:
5015 case 0x7f:
5016 return static_cast<number_unsigned_t>(current);
5017
5018 // fixmap
5019 case 0x80:
5020 case 0x81:
5021 case 0x82:
5022 case 0x83:
5023 case 0x84:
5024 case 0x85:
5025 case 0x86:
5026 case 0x87:
5027 case 0x88:
5028 case 0x89:
5029 case 0x8a:
5030 case 0x8b:
5031 case 0x8c:
5032 case 0x8d:
5033 case 0x8e:
5034 case 0x8f:
5035 {
5036 return get_msgpack_object(current & 0x0f);
5037 }
5038
5039 // fixarray
5040 case 0x90:
5041 case 0x91:
5042 case 0x92:
5043 case 0x93:
5044 case 0x94:
5045 case 0x95:
5046 case 0x96:
5047 case 0x97:
5048 case 0x98:
5049 case 0x99:
5050 case 0x9a:
5051 case 0x9b:
5052 case 0x9c:
5053 case 0x9d:
5054 case 0x9e:
5055 case 0x9f:
5056 {
5057 return get_msgpack_array(current & 0x0f);
5058 }
5059
5060 // fixstr
5061 case 0xa0:
5062 case 0xa1:
5063 case 0xa2:
5064 case 0xa3:
5065 case 0xa4:
5066 case 0xa5:
5067 case 0xa6:
5068 case 0xa7:
5069 case 0xa8:
5070 case 0xa9:
5071 case 0xaa:
5072 case 0xab:
5073 case 0xac:
5074 case 0xad:
5075 case 0xae:
5076 case 0xaf:
5077 case 0xb0:
5078 case 0xb1:
5079 case 0xb2:
5080 case 0xb3:
5081 case 0xb4:
5082 case 0xb5:
5083 case 0xb6:
5084 case 0xb7:
5085 case 0xb8:
5086 case 0xb9:
5087 case 0xba:
5088 case 0xbb:
5089 case 0xbc:
5090 case 0xbd:
5091 case 0xbe:
5092 case 0xbf:
5093 return get_msgpack_string();
5094
5095 case 0xc0: // nil
5096 return value_t::null;
5097
5098 case 0xc2: // false
5099 return false;
5100
5101 case 0xc3: // true
5102 return true;
5103
5104 case 0xca: // float 32
5105 return get_number<float>();
5106
5107 case 0xcb: // float 64
5108 return get_number<double>();
5109
5110 case 0xcc: // uint 8
5111 return get_number<uint8_t>();
5112
5113 case 0xcd: // uint 16
5114 return get_number<uint16_t>();
5115
5116 case 0xce: // uint 32
5117 return get_number<uint32_t>();
5118
5119 case 0xcf: // uint 64
5120 return get_number<uint64_t>();
5121
5122 case 0xd0: // int 8
5123 return get_number<int8_t>();
5124
5125 case 0xd1: // int 16
5126 return get_number<int16_t>();
5127
5128 case 0xd2: // int 32
5129 return get_number<int32_t>();
5130
5131 case 0xd3: // int 64
5132 return get_number<int64_t>();
5133
5134 case 0xd9: // str 8
5135 case 0xda: // str 16
5136 case 0xdb: // str 32
5137 return get_msgpack_string();
5138
5139 case 0xdc: // array 16
5140 {
5141 return get_msgpack_array(get_number<uint16_t>());
5142 }
5143
5144 case 0xdd: // array 32
5145 {
5146 return get_msgpack_array(get_number<uint32_t>());
5147 }
5148
5149 case 0xde: // map 16
5150 {
5151 return get_msgpack_object(get_number<uint16_t>());
5152 }
5153
5154 case 0xdf: // map 32
5155 {
5156 return get_msgpack_object(get_number<uint32_t>());
5157 }
5158
5159 // positive fixint
5160 case 0xe0:
5161 case 0xe1:
5162 case 0xe2:
5163 case 0xe3:
5164 case 0xe4:
5165 case 0xe5:
5166 case 0xe6:
5167 case 0xe7:
5168 case 0xe8:
5169 case 0xe9:
5170 case 0xea:
5171 case 0xeb:
5172 case 0xec:
5173 case 0xed:
5174 case 0xee:
5175 case 0xef:
5176 case 0xf0:
5177 case 0xf1:
5178 case 0xf2:
5179 case 0xf3:
5180 case 0xf4:
5181 case 0xf5:
5182 case 0xf6:
5183 case 0xf7:
5184 case 0xf8:
5185 case 0xf9:
5186 case 0xfa:
5187 case 0xfb:
5188 case 0xfc:
5189 case 0xfd:
5190 case 0xfe:
5191 case 0xff:
5192 return static_cast<int8_t>(current);
5193
5194 default: // anything else
5195 {
5196 std::stringstream ss;
5197 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5198 JSON_THROW(parse_error::create(112, chars_read,
5199 "error reading MessagePack; last byte: 0x" + ss.str()));
5200 }
5201 }
5202 }
5203
5204 /*!
5205 @brief get next character from the input
5206
5207 This function provides the interface to the used input adapter. It does
5208 not throw in case the input reached EOF, but returns a -'ve valued
5209 `std::char_traits<char>::eof()` in that case.
5210
5211 @return character read from the input
5212 */
get()5213 int get()
5214 {
5215 ++chars_read;
5216 return (current = ia->get_character());
5217 }
5218
5219 /*
5220 @brief read a number from the input
5221
5222 @tparam NumberType the type of the number
5223
5224 @return number of type @a NumberType
5225
5226 @note This function needs to respect the system's endianess, because
5227 bytes in CBOR and MessagePack are stored in network order (big
5228 endian) and therefore need reordering on little endian systems.
5229
5230 @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
5231 */
get_number()5232 template<typename NumberType> NumberType get_number()
5233 {
5234 // step 1: read input into array with system's byte order
5235 std::array<uint8_t, sizeof(NumberType)> vec;
5236 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5237 {
5238 get();
5239 check_eof();
5240
5241 // reverse byte order prior to conversion if necessary
5242 if (is_little_endian)
5243 {
5244 vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5245 }
5246 else
5247 {
5248 vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
5249 }
5250 }
5251
5252 // step 2: convert array into number of type T and return
5253 NumberType result;
5254 std::memcpy(&result, vec.data(), sizeof(NumberType));
5255 return result;
5256 }
5257
5258 /*!
5259 @brief create a string by reading characters from the input
5260
5261 @param[in] len number of bytes to read
5262
5263 @note We can not reserve @a len bytes for the result, because @a len
5264 may be too large. Usually, @ref check_eof() detects the end of
5265 the input before we run out of string memory.
5266
5267 @return string created by reading @a len bytes
5268
5269 @throw parse_error.110 if input has less than @a len bytes
5270 */
5271 template<typename NumberType>
get_string(const NumberType len)5272 std::string get_string(const NumberType len)
5273 {
5274 std::string result;
5275 std::generate_n(std::back_inserter(result), len, [this]()
5276 {
5277 get();
5278 check_eof();
5279 return static_cast<char>(current);
5280 });
5281 return result;
5282 }
5283
5284 /*!
5285 @brief reads a CBOR string
5286
5287 This function first reads starting bytes to determine the expected
5288 string length and then copies this number of bytes into a string.
5289 Additionally, CBOR's strings with indefinite lengths are supported.
5290
5291 @return string
5292
5293 @throw parse_error.110 if input ended
5294 @throw parse_error.113 if an unexpected byte is read
5295 */
get_cbor_string()5296 std::string get_cbor_string()
5297 {
5298 check_eof();
5299
5300 switch (current)
5301 {
5302 // UTF-8 string (0x00..0x17 bytes follow)
5303 case 0x60:
5304 case 0x61:
5305 case 0x62:
5306 case 0x63:
5307 case 0x64:
5308 case 0x65:
5309 case 0x66:
5310 case 0x67:
5311 case 0x68:
5312 case 0x69:
5313 case 0x6a:
5314 case 0x6b:
5315 case 0x6c:
5316 case 0x6d:
5317 case 0x6e:
5318 case 0x6f:
5319 case 0x70:
5320 case 0x71:
5321 case 0x72:
5322 case 0x73:
5323 case 0x74:
5324 case 0x75:
5325 case 0x76:
5326 case 0x77:
5327 {
5328 return get_string(current & 0x1f);
5329 }
5330
5331 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5332 {
5333 return get_string(get_number<uint8_t>());
5334 }
5335
5336 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5337 {
5338 return get_string(get_number<uint16_t>());
5339 }
5340
5341 case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
5342 {
5343 return get_string(get_number<uint32_t>());
5344 }
5345
5346 case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
5347 {
5348 return get_string(get_number<uint64_t>());
5349 }
5350
5351 case 0x7f: // UTF-8 string (indefinite length)
5352 {
5353 std::string result;
5354 while (get() != 0xff)
5355 {
5356 check_eof();
5357 result.push_back(static_cast<char>(current));
5358 }
5359 return result;
5360 }
5361
5362 default:
5363 {
5364 std::stringstream ss;
5365 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5366 JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
5367 }
5368 }
5369 }
5370
5371 template<typename NumberType>
get_cbor_array(const NumberType len)5372 BasicJsonType get_cbor_array(const NumberType len)
5373 {
5374 BasicJsonType result = value_t::array;
5375 std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5376 {
5377 return parse_cbor_internal();
5378 });
5379 return result;
5380 }
5381
5382 template<typename NumberType>
get_cbor_object(const NumberType len)5383 BasicJsonType get_cbor_object(const NumberType len)
5384 {
5385 BasicJsonType result = value_t::object;
5386 std::generate_n(std::inserter(*result.m_value.object,
5387 result.m_value.object->end()),
5388 len, [this]()
5389 {
5390 get();
5391 auto key = get_cbor_string();
5392 auto val = parse_cbor_internal();
5393 return std::make_pair(std::move(key), std::move(val));
5394 });
5395 return result;
5396 }
5397
5398 /*!
5399 @brief reads a MessagePack string
5400
5401 This function first reads starting bytes to determine the expected
5402 string length and then copies this number of bytes into a string.
5403
5404 @return string
5405
5406 @throw parse_error.110 if input ended
5407 @throw parse_error.113 if an unexpected byte is read
5408 */
get_msgpack_string()5409 std::string get_msgpack_string()
5410 {
5411 check_eof();
5412
5413 switch (current)
5414 {
5415 // fixstr
5416 case 0xa0:
5417 case 0xa1:
5418 case 0xa2:
5419 case 0xa3:
5420 case 0xa4:
5421 case 0xa5:
5422 case 0xa6:
5423 case 0xa7:
5424 case 0xa8:
5425 case 0xa9:
5426 case 0xaa:
5427 case 0xab:
5428 case 0xac:
5429 case 0xad:
5430 case 0xae:
5431 case 0xaf:
5432 case 0xb0:
5433 case 0xb1:
5434 case 0xb2:
5435 case 0xb3:
5436 case 0xb4:
5437 case 0xb5:
5438 case 0xb6:
5439 case 0xb7:
5440 case 0xb8:
5441 case 0xb9:
5442 case 0xba:
5443 case 0xbb:
5444 case 0xbc:
5445 case 0xbd:
5446 case 0xbe:
5447 case 0xbf:
5448 {
5449 return get_string(current & 0x1f);
5450 }
5451
5452 case 0xd9: // str 8
5453 {
5454 return get_string(get_number<uint8_t>());
5455 }
5456
5457 case 0xda: // str 16
5458 {
5459 return get_string(get_number<uint16_t>());
5460 }
5461
5462 case 0xdb: // str 32
5463 {
5464 return get_string(get_number<uint32_t>());
5465 }
5466
5467 default:
5468 {
5469 std::stringstream ss;
5470 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5471 JSON_THROW(parse_error::create(113, chars_read,
5472 "expected a MessagePack string; last byte: 0x" + ss.str()));
5473 }
5474 }
5475 }
5476
5477 template<typename NumberType>
get_msgpack_array(const NumberType len)5478 BasicJsonType get_msgpack_array(const NumberType len)
5479 {
5480 BasicJsonType result = value_t::array;
5481 std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5482 {
5483 return parse_msgpack_internal();
5484 });
5485 return result;
5486 }
5487
5488 template<typename NumberType>
get_msgpack_object(const NumberType len)5489 BasicJsonType get_msgpack_object(const NumberType len)
5490 {
5491 BasicJsonType result = value_t::object;
5492 std::generate_n(std::inserter(*result.m_value.object,
5493 result.m_value.object->end()),
5494 len, [this]()
5495 {
5496 get();
5497 auto key = get_msgpack_string();
5498 auto val = parse_msgpack_internal();
5499 return std::make_pair(std::move(key), std::move(val));
5500 });
5501 return result;
5502 }
5503
5504 /*!
5505 @brief check if input ended
5506 @throw parse_error.110 if input ended
5507 */
check_eof(const bool expect_eof=false) const5508 void check_eof(const bool expect_eof = false) const
5509 {
5510 if (expect_eof)
5511 {
5512 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
5513 {
5514 JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
5515 }
5516 }
5517 else
5518 {
5519 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
5520 {
5521 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5522 }
5523 }
5524 }
5525
5526 private:
5527 /// input adapter
5528 input_adapter_t ia = nullptr;
5529
5530 /// the current character
5531 int current = std::char_traits<char>::eof();
5532
5533 /// the number of characters read
5534 std::size_t chars_read = 0;
5535
5536 /// whether we can assume little endianess
5537 const bool is_little_endian = little_endianess();
5538 };
5539
5540 /*!
5541 @brief serialization to CBOR and MessagePack values
5542 */
5543 template<typename BasicJsonType, typename CharType>
5544 class binary_writer
5545 {
5546 public:
5547 /*!
5548 @brief create a binary writer
5549
5550 @param[in] adapter output adapter to write to
5551 */
binary_writer(output_adapter_t<CharType> adapter)5552 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5553 {
5554 assert(oa);
5555 }
5556
5557 /*!
5558 @brief[in] j JSON value to serialize
5559 */
write_cbor(const BasicJsonType & j)5560 void write_cbor(const BasicJsonType& j)
5561 {
5562 switch (j.type())
5563 {
5564 case value_t::null:
5565 {
5566 oa->write_character(static_cast<CharType>(0xf6));
5567 break;
5568 }
5569
5570 case value_t::boolean:
5571 {
5572 oa->write_character(j.m_value.boolean
5573 ? static_cast<CharType>(0xf5)
5574 : static_cast<CharType>(0xf4));
5575 break;
5576 }
5577
5578 case value_t::number_integer:
5579 {
5580 if (j.m_value.number_integer >= 0)
5581 {
5582 // CBOR does not differentiate between positive signed
5583 // integers and unsigned integers. Therefore, we used the
5584 // code from the value_t::number_unsigned case here.
5585 if (j.m_value.number_integer <= 0x17)
5586 {
5587 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5588 }
5589 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
5590 {
5591 oa->write_character(static_cast<CharType>(0x18));
5592 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5593 }
5594 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
5595 {
5596 oa->write_character(static_cast<CharType>(0x19));
5597 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5598 }
5599 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
5600 {
5601 oa->write_character(static_cast<CharType>(0x1a));
5602 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5603 }
5604 else
5605 {
5606 oa->write_character(static_cast<CharType>(0x1b));
5607 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5608 }
5609 }
5610 else
5611 {
5612 // The conversions below encode the sign in the first
5613 // byte, and the value is converted to a positive number.
5614 const auto positive_number = -1 - j.m_value.number_integer;
5615 if (j.m_value.number_integer >= -24)
5616 {
5617 write_number(static_cast<uint8_t>(0x20 + positive_number));
5618 }
5619 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
5620 {
5621 oa->write_character(static_cast<CharType>(0x38));
5622 write_number(static_cast<uint8_t>(positive_number));
5623 }
5624 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
5625 {
5626 oa->write_character(static_cast<CharType>(0x39));
5627 write_number(static_cast<uint16_t>(positive_number));
5628 }
5629 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
5630 {
5631 oa->write_character(static_cast<CharType>(0x3a));
5632 write_number(static_cast<uint32_t>(positive_number));
5633 }
5634 else
5635 {
5636 oa->write_character(static_cast<CharType>(0x3b));
5637 write_number(static_cast<uint64_t>(positive_number));
5638 }
5639 }
5640 break;
5641 }
5642
5643 case value_t::number_unsigned:
5644 {
5645 if (j.m_value.number_unsigned <= 0x17)
5646 {
5647 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5648 }
5649 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5650 {
5651 oa->write_character(static_cast<CharType>(0x18));
5652 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5653 }
5654 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5655 {
5656 oa->write_character(static_cast<CharType>(0x19));
5657 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
5658 }
5659 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5660 {
5661 oa->write_character(static_cast<CharType>(0x1a));
5662 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
5663 }
5664 else
5665 {
5666 oa->write_character(static_cast<CharType>(0x1b));
5667 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
5668 }
5669 break;
5670 }
5671
5672 case value_t::number_float: // Double-Precision Float
5673 {
5674 oa->write_character(static_cast<CharType>(0xfb));
5675 write_number(j.m_value.number_float);
5676 break;
5677 }
5678
5679 case value_t::string:
5680 {
5681 // step 1: write control byte and the string length
5682 const auto N = j.m_value.string->size();
5683 if (N <= 0x17)
5684 {
5685 write_number(static_cast<uint8_t>(0x60 + N));
5686 }
5687 else if (N <= 0xff)
5688 {
5689 oa->write_character(static_cast<CharType>(0x78));
5690 write_number(static_cast<uint8_t>(N));
5691 }
5692 else if (N <= 0xffff)
5693 {
5694 oa->write_character(static_cast<CharType>(0x79));
5695 write_number(static_cast<uint16_t>(N));
5696 }
5697 else if (N <= 0xffffffff)
5698 {
5699 oa->write_character(static_cast<CharType>(0x7a));
5700 write_number(static_cast<uint32_t>(N));
5701 }
5702 // LCOV_EXCL_START
5703 else if (N <= 0xffffffffffffffff)
5704 {
5705 oa->write_character(static_cast<CharType>(0x7b));
5706 write_number(static_cast<uint64_t>(N));
5707 }
5708 // LCOV_EXCL_STOP
5709
5710 // step 2: write the string
5711 oa->write_characters(
5712 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
5713 j.m_value.string->size());
5714 break;
5715 }
5716
5717 case value_t::array:
5718 {
5719 // step 1: write control byte and the array size
5720 const auto N = j.m_value.array->size();
5721 if (N <= 0x17)
5722 {
5723 write_number(static_cast<uint8_t>(0x80 + N));
5724 }
5725 else if (N <= 0xff)
5726 {
5727 oa->write_character(static_cast<CharType>(0x98));
5728 write_number(static_cast<uint8_t>(N));
5729 }
5730 else if (N <= 0xffff)
5731 {
5732 oa->write_character(static_cast<CharType>(0x99));
5733 write_number(static_cast<uint16_t>(N));
5734 }
5735 else if (N <= 0xffffffff)
5736 {
5737 oa->write_character(static_cast<CharType>(0x9a));
5738 write_number(static_cast<uint32_t>(N));
5739 }
5740 // LCOV_EXCL_START
5741 else if (N <= 0xffffffffffffffff)
5742 {
5743 oa->write_character(static_cast<CharType>(0x9b));
5744 write_number(static_cast<uint64_t>(N));
5745 }
5746 // LCOV_EXCL_STOP
5747
5748 // step 2: write each element
5749 for (const auto& el : *j.m_value.array)
5750 {
5751 write_cbor(el);
5752 }
5753 break;
5754 }
5755
5756 case value_t::object:
5757 {
5758 // step 1: write control byte and the object size
5759 const auto N = j.m_value.object->size();
5760 if (N <= 0x17)
5761 {
5762 write_number(static_cast<uint8_t>(0xa0 + N));
5763 }
5764 else if (N <= 0xff)
5765 {
5766 oa->write_character(static_cast<CharType>(0xb8));
5767 write_number(static_cast<uint8_t>(N));
5768 }
5769 else if (N <= 0xffff)
5770 {
5771 oa->write_character(static_cast<CharType>(0xb9));
5772 write_number(static_cast<uint16_t>(N));
5773 }
5774 else if (N <= 0xffffffff)
5775 {
5776 oa->write_character(static_cast<CharType>(0xba));
5777 write_number(static_cast<uint32_t>(N));
5778 }
5779 // LCOV_EXCL_START
5780 else if (N <= 0xffffffffffffffff)
5781 {
5782 oa->write_character(static_cast<CharType>(0xbb));
5783 write_number(static_cast<uint64_t>(N));
5784 }
5785 // LCOV_EXCL_STOP
5786
5787 // step 2: write each element
5788 for (const auto& el : *j.m_value.object)
5789 {
5790 write_cbor(el.first);
5791 write_cbor(el.second);
5792 }
5793 break;
5794 }
5795
5796 default:
5797 break;
5798 }
5799 }
5800
5801 /*!
5802 @brief[in] j JSON value to serialize
5803 */
write_msgpack(const BasicJsonType & j)5804 void write_msgpack(const BasicJsonType& j)
5805 {
5806 switch (j.type())
5807 {
5808 case value_t::null: // nil
5809 {
5810 oa->write_character(static_cast<CharType>(0xc0));
5811 break;
5812 }
5813
5814 case value_t::boolean: // true and false
5815 {
5816 oa->write_character(j.m_value.boolean
5817 ? static_cast<CharType>(0xc3)
5818 : static_cast<CharType>(0xc2));
5819 break;
5820 }
5821
5822 case value_t::number_integer:
5823 {
5824 if (j.m_value.number_integer >= 0)
5825 {
5826 // MessagePack does not differentiate between positive
5827 // signed integers and unsigned integers. Therefore, we used
5828 // the code from the value_t::number_unsigned case here.
5829 if (j.m_value.number_unsigned < 128)
5830 {
5831 // positive fixnum
5832 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5833 }
5834 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5835 {
5836 // uint 8
5837 oa->write_character(static_cast<CharType>(0xcc));
5838 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5839 }
5840 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5841 {
5842 // uint 16
5843 oa->write_character(static_cast<CharType>(0xcd));
5844 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5845 }
5846 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5847 {
5848 // uint 32
5849 oa->write_character(static_cast<CharType>(0xce));
5850 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5851 }
5852 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5853 {
5854 // uint 64
5855 oa->write_character(static_cast<CharType>(0xcf));
5856 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5857 }
5858 }
5859 else
5860 {
5861 if (j.m_value.number_integer >= -32)
5862 {
5863 // negative fixnum
5864 write_number(static_cast<int8_t>(j.m_value.number_integer));
5865 }
5866 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
5867 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
5868 {
5869 // int 8
5870 oa->write_character(static_cast<CharType>(0xd0));
5871 write_number(static_cast<int8_t>(j.m_value.number_integer));
5872 }
5873 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
5874 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
5875 {
5876 // int 16
5877 oa->write_character(static_cast<CharType>(0xd1));
5878 write_number(static_cast<int16_t>(j.m_value.number_integer));
5879 }
5880 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
5881 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
5882 {
5883 // int 32
5884 oa->write_character(static_cast<CharType>(0xd2));
5885 write_number(static_cast<int32_t>(j.m_value.number_integer));
5886 }
5887 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
5888 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
5889 {
5890 // int 64
5891 oa->write_character(static_cast<CharType>(0xd3));
5892 write_number(static_cast<int64_t>(j.m_value.number_integer));
5893 }
5894 }
5895 break;
5896 }
5897
5898 case value_t::number_unsigned:
5899 {
5900 if (j.m_value.number_unsigned < 128)
5901 {
5902 // positive fixnum
5903 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5904 }
5905 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5906 {
5907 // uint 8
5908 oa->write_character(static_cast<CharType>(0xcc));
5909 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5910 }
5911 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5912 {
5913 // uint 16
5914 oa->write_character(static_cast<CharType>(0xcd));
5915 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5916 }
5917 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5918 {
5919 // uint 32
5920 oa->write_character(static_cast<CharType>(0xce));
5921 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5922 }
5923 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5924 {
5925 // uint 64
5926 oa->write_character(static_cast<CharType>(0xcf));
5927 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5928 }
5929 break;
5930 }
5931
5932 case value_t::number_float: // float 64
5933 {
5934 oa->write_character(static_cast<CharType>(0xcb));
5935 write_number(j.m_value.number_float);
5936 break;
5937 }
5938
5939 case value_t::string:
5940 {
5941 // step 1: write control byte and the string length
5942 const auto N = j.m_value.string->size();
5943 if (N <= 31)
5944 {
5945 // fixstr
5946 write_number(static_cast<uint8_t>(0xa0 | N));
5947 }
5948 else if (N <= 255)
5949 {
5950 // str 8
5951 oa->write_character(static_cast<CharType>(0xd9));
5952 write_number(static_cast<uint8_t>(N));
5953 }
5954 else if (N <= 65535)
5955 {
5956 // str 16
5957 oa->write_character(static_cast<CharType>(0xda));
5958 write_number(static_cast<uint16_t>(N));
5959 }
5960 else if (N <= 4294967295)
5961 {
5962 // str 32
5963 oa->write_character(static_cast<CharType>(0xdb));
5964 write_number(static_cast<uint32_t>(N));
5965 }
5966
5967 // step 2: write the string
5968 oa->write_characters(
5969 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
5970 j.m_value.string->size());
5971 break;
5972 }
5973
5974 case value_t::array:
5975 {
5976 // step 1: write control byte and the array size
5977 const auto N = j.m_value.array->size();
5978 if (N <= 15)
5979 {
5980 // fixarray
5981 write_number(static_cast<uint8_t>(0x90 | N));
5982 }
5983 else if (N <= 0xffff)
5984 {
5985 // array 16
5986 oa->write_character(static_cast<CharType>(0xdc));
5987 write_number(static_cast<uint16_t>(N));
5988 }
5989 else if (N <= 0xffffffff)
5990 {
5991 // array 32
5992 oa->write_character(static_cast<CharType>(0xdd));
5993 write_number(static_cast<uint32_t>(N));
5994 }
5995
5996 // step 2: write each element
5997 for (const auto& el : *j.m_value.array)
5998 {
5999 write_msgpack(el);
6000 }
6001 break;
6002 }
6003
6004 case value_t::object:
6005 {
6006 // step 1: write control byte and the object size
6007 const auto N = j.m_value.object->size();
6008 if (N <= 15)
6009 {
6010 // fixmap
6011 write_number(static_cast<uint8_t>(0x80 | (N & 0xf)));
6012 }
6013 else if (N <= 65535)
6014 {
6015 // map 16
6016 oa->write_character(static_cast<CharType>(0xde));
6017 write_number(static_cast<uint16_t>(N));
6018 }
6019 else if (N <= 4294967295)
6020 {
6021 // map 32
6022 oa->write_character(static_cast<CharType>(0xdf));
6023 write_number(static_cast<uint32_t>(N));
6024 }
6025
6026 // step 2: write each element
6027 for (const auto& el : *j.m_value.object)
6028 {
6029 write_msgpack(el.first);
6030 write_msgpack(el.second);
6031 }
6032 break;
6033 }
6034
6035 default:
6036 break;
6037 }
6038 }
6039
6040 private:
6041 /*
6042 @brief write a number to output input
6043
6044 @param[in] n number of type @a NumberType
6045 @tparam NumberType the type of the number
6046
6047 @note This function needs to respect the system's endianess, because bytes
6048 in CBOR and MessagePack are stored in network order (big endian) and
6049 therefore need reordering on little endian systems.
6050 */
write_number(NumberType n)6051 template<typename NumberType> void write_number(NumberType n)
6052 {
6053 // step 1: write number to array of length NumberType
6054 std::array<CharType, sizeof(NumberType)> vec;
6055 std::memcpy(vec.data(), &n, sizeof(NumberType));
6056
6057 // step 2: write array to output (with possible reordering)
6058 if (is_little_endian)
6059 {
6060 // reverse byte order prior to conversion if necessary
6061 std::reverse(vec.begin(), vec.end());
6062 }
6063
6064 oa->write_characters(vec.data(), sizeof(NumberType));
6065 }
6066
6067 private:
6068 /// whether we can assume little endianess
6069 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
6070
6071 /// the output
6072 output_adapter_t<CharType> oa = nullptr;
6073 };
6074
6075 ///////////////////
6076 // serialization //
6077 ///////////////////
6078
6079 template<typename BasicJsonType>
6080 class serializer
6081 {
6082 using string_t = typename BasicJsonType::string_t;
6083 using number_float_t = typename BasicJsonType::number_float_t;
6084 using number_integer_t = typename BasicJsonType::number_integer_t;
6085 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6086 public:
6087 /*!
6088 @param[in] s output stream to serialize to
6089 @param[in] ichar indentation character to use
6090 */
serializer(output_adapter_t<char> s,const char ichar)6091 serializer(output_adapter_t<char> s, const char ichar)
6092 : o(std::move(s)), loc(std::localeconv()),
6093 thousands_sep(loc->thousands_sep == nullptr ? '\0' : loc->thousands_sep[0]),
6094 decimal_point(loc->decimal_point == nullptr ? '\0' : loc->decimal_point[0]),
6095 indent_char(ichar), indent_string(512, indent_char) {}
6096
6097 // delete because of pointer members
6098 serializer(const serializer&) = delete;
6099 serializer& operator=(const serializer&) = delete;
6100
6101 /*!
6102 @brief internal implementation of the serialization function
6103
6104 This function is called by the public member function dump and organizes
6105 the serialization internally. The indentation level is propagated as
6106 additional parameter. In case of arrays and objects, the function is
6107 called recursively.
6108
6109 - strings and object keys are escaped using `escape_string()`
6110 - integer numbers are converted implicitly via `operator<<`
6111 - floating-point numbers are converted to a string using `"%g"` format
6112
6113 @param[in] val value to serialize
6114 @param[in] pretty_print whether the output shall be pretty-printed
6115 @param[in] indent_step the indent level
6116 @param[in] current_indent the current indent level (only used internally)
6117 */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)6118 void dump(const BasicJsonType& val, const bool pretty_print,
6119 const bool ensure_ascii,
6120 const unsigned int indent_step,
6121 const unsigned int current_indent = 0)
6122 {
6123 switch (val.m_type)
6124 {
6125 case value_t::object:
6126 {
6127 if (val.m_value.object->empty())
6128 {
6129 o->write_characters("{}", 2);
6130 return;
6131 }
6132
6133 if (pretty_print)
6134 {
6135 o->write_characters("{\n", 2);
6136
6137 // variable to hold indentation for recursive calls
6138 const auto new_indent = current_indent + indent_step;
6139 if (JSON_UNLIKELY(indent_string.size() < new_indent))
6140 {
6141 indent_string.resize(indent_string.size() * 2, ' ');
6142 }
6143
6144 // first n-1 elements
6145 auto i = val.m_value.object->cbegin();
6146 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6147 {
6148 o->write_characters(indent_string.c_str(), new_indent);
6149 o->write_character('\"');
6150 dump_escaped(i->first, ensure_ascii);
6151 o->write_characters("\": ", 3);
6152 dump(i->second, true, ensure_ascii, indent_step, new_indent);
6153 o->write_characters(",\n", 2);
6154 }
6155
6156 // last element
6157 assert(i != val.m_value.object->cend());
6158 assert(std::next(i) == val.m_value.object->cend());
6159 o->write_characters(indent_string.c_str(), new_indent);
6160 o->write_character('\"');
6161 dump_escaped(i->first, ensure_ascii);
6162 o->write_characters("\": ", 3);
6163 dump(i->second, true, ensure_ascii, indent_step, new_indent);
6164
6165 o->write_character('\n');
6166 o->write_characters(indent_string.c_str(), current_indent);
6167 o->write_character('}');
6168 }
6169 else
6170 {
6171 o->write_character('{');
6172
6173 // first n-1 elements
6174 auto i = val.m_value.object->cbegin();
6175 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6176 {
6177 o->write_character('\"');
6178 dump_escaped(i->first, ensure_ascii);
6179 o->write_characters("\":", 2);
6180 dump(i->second, false, ensure_ascii, indent_step, current_indent);
6181 o->write_character(',');
6182 }
6183
6184 // last element
6185 assert(i != val.m_value.object->cend());
6186 assert(std::next(i) == val.m_value.object->cend());
6187 o->write_character('\"');
6188 dump_escaped(i->first, ensure_ascii);
6189 o->write_characters("\":", 2);
6190 dump(i->second, false, ensure_ascii, indent_step, current_indent);
6191
6192 o->write_character('}');
6193 }
6194
6195 return;
6196 }
6197
6198 case value_t::array:
6199 {
6200 if (val.m_value.array->empty())
6201 {
6202 o->write_characters("[]", 2);
6203 return;
6204 }
6205
6206 if (pretty_print)
6207 {
6208 o->write_characters("[\n", 2);
6209
6210 // variable to hold indentation for recursive calls
6211 const auto new_indent = current_indent + indent_step;
6212 if (JSON_UNLIKELY(indent_string.size() < new_indent))
6213 {
6214 indent_string.resize(indent_string.size() * 2, ' ');
6215 }
6216
6217 // first n-1 elements
6218 for (auto i = val.m_value.array->cbegin();
6219 i != val.m_value.array->cend() - 1; ++i)
6220 {
6221 o->write_characters(indent_string.c_str(), new_indent);
6222 dump(*i, true, ensure_ascii, indent_step, new_indent);
6223 o->write_characters(",\n", 2);
6224 }
6225
6226 // last element
6227 assert(not val.m_value.array->empty());
6228 o->write_characters(indent_string.c_str(), new_indent);
6229 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
6230
6231 o->write_character('\n');
6232 o->write_characters(indent_string.c_str(), current_indent);
6233 o->write_character(']');
6234 }
6235 else
6236 {
6237 o->write_character('[');
6238
6239 // first n-1 elements
6240 for (auto i = val.m_value.array->cbegin();
6241 i != val.m_value.array->cend() - 1; ++i)
6242 {
6243 dump(*i, false, ensure_ascii, indent_step, current_indent);
6244 o->write_character(',');
6245 }
6246
6247 // last element
6248 assert(not val.m_value.array->empty());
6249 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
6250
6251 o->write_character(']');
6252 }
6253
6254 return;
6255 }
6256
6257 case value_t::string:
6258 {
6259 o->write_character('\"');
6260 dump_escaped(*val.m_value.string, ensure_ascii);
6261 o->write_character('\"');
6262 return;
6263 }
6264
6265 case value_t::boolean:
6266 {
6267 if (val.m_value.boolean)
6268 {
6269 o->write_characters("true", 4);
6270 }
6271 else
6272 {
6273 o->write_characters("false", 5);
6274 }
6275 return;
6276 }
6277
6278 case value_t::number_integer:
6279 {
6280 dump_integer(val.m_value.number_integer);
6281 return;
6282 }
6283
6284 case value_t::number_unsigned:
6285 {
6286 dump_integer(val.m_value.number_unsigned);
6287 return;
6288 }
6289
6290 case value_t::number_float:
6291 {
6292 dump_float(val.m_value.number_float);
6293 return;
6294 }
6295
6296 case value_t::discarded:
6297 {
6298 o->write_characters("<discarded>", 11);
6299 return;
6300 }
6301
6302 case value_t::null:
6303 {
6304 o->write_characters("null", 4);
6305 return;
6306 }
6307 }
6308 }
6309
6310 private:
6311 /*!
6312 @brief returns the number of expected bytes following in UTF-8 string
6313
6314 @param[in] u the first byte of a UTF-8 string
6315 @return the number of expected bytes following
6316 */
bytes_following(const uint8_t u)6317 static constexpr std::size_t bytes_following(const uint8_t u)
6318 {
6319 return ((u <= 127) ? 0
6320 : ((192 <= u and u <= 223) ? 1
6321 : ((224 <= u and u <= 239) ? 2
6322 : ((240 <= u and u <= 247) ? 3 : std::string::npos))));
6323 }
6324
6325 /*!
6326 @brief calculates the extra space to escape a JSON string
6327
6328 @param[in] s the string to escape
6329 @param[in] ensure_ascii whether to escape non-ASCII characters with
6330 \uXXXX sequences
6331 @return the number of characters required to escape string @a s
6332
6333 @complexity Linear in the length of string @a s.
6334 */
extra_space(const string_t & s,const bool ensure_ascii)6335 static std::size_t extra_space(const string_t& s,
6336 const bool ensure_ascii) noexcept
6337 {
6338 std::size_t res = 0;
6339
6340 for (std::size_t i = 0; i < s.size(); ++i)
6341 {
6342 switch (s[i])
6343 {
6344 // control characters that can be escaped with a backslash
6345 case '"':
6346 case '\\':
6347 case '\b':
6348 case '\f':
6349 case '\n':
6350 case '\r':
6351 case '\t':
6352 {
6353 // from c (1 byte) to \x (2 bytes)
6354 res += 1;
6355 break;
6356 }
6357
6358 // control characters that need \uxxxx escaping
6359 case 0x00:
6360 case 0x01:
6361 case 0x02:
6362 case 0x03:
6363 case 0x04:
6364 case 0x05:
6365 case 0x06:
6366 case 0x07:
6367 case 0x0b:
6368 case 0x0e:
6369 case 0x0f:
6370 case 0x10:
6371 case 0x11:
6372 case 0x12:
6373 case 0x13:
6374 case 0x14:
6375 case 0x15:
6376 case 0x16:
6377 case 0x17:
6378 case 0x18:
6379 case 0x19:
6380 case 0x1a:
6381 case 0x1b:
6382 case 0x1c:
6383 case 0x1d:
6384 case 0x1e:
6385 case 0x1f:
6386 {
6387 // from c (1 byte) to \uxxxx (6 bytes)
6388 res += 5;
6389 break;
6390 }
6391
6392 default:
6393 {
6394 if (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F))
6395 {
6396 const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
6397 if (bytes == std::string::npos)
6398 {
6399 // invalid characters are treated as is, so no
6400 // additional space will be used
6401 break;
6402 }
6403
6404 if (bytes == 3)
6405 {
6406 // codepoints that need 4 bytes (i.e., 3 additional
6407 // bytes) in UTF-8 need a surrogate pair when \u
6408 // escaping is used: from 4 bytes to \uxxxx\uxxxx
6409 // (12 bytes)
6410 res += (12 - bytes - 1);
6411 }
6412 else
6413 {
6414 // from x bytes to \uxxxx (6 bytes)
6415 res += (6 - bytes - 1);
6416 }
6417
6418 // skip the additional bytes
6419 i += bytes;
6420 }
6421 break;
6422 }
6423 }
6424 }
6425
6426 return res;
6427 }
6428
escape_codepoint(int codepoint,string_t & result,std::size_t & pos)6429 static void escape_codepoint(int codepoint, string_t& result, std::size_t& pos)
6430 {
6431 // expecting a proper codepoint
6432 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
6433
6434 // the last written character was the backslash before the 'u'
6435 assert(result[pos] == '\\');
6436
6437 // write the 'u'
6438 result[++pos] = 'u';
6439
6440 // convert a number 0..15 to its hex representation (0..f)
6441 static const std::array<char, 16> hexify =
6442 {
6443 {
6444 '0', '1', '2', '3', '4', '5', '6', '7',
6445 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
6446 }
6447 };
6448
6449 if (codepoint < 0x10000)
6450 {
6451 // codepoints U+0000..U+FFFF can be represented as \uxxxx.
6452 result[++pos] = hexify[(codepoint >> 12) & 0x0F];
6453 result[++pos] = hexify[(codepoint >> 8) & 0x0F];
6454 result[++pos] = hexify[(codepoint >> 4) & 0x0F];
6455 result[++pos] = hexify[codepoint & 0x0F];
6456 }
6457 else
6458 {
6459 // codepoints U+10000..U+10FFFF need a surrogate pair to be
6460 // represented as \uxxxx\uxxxx.
6461 // http://www.unicode.org/faq/utf_bom.html#utf16-4
6462 codepoint -= 0x10000;
6463 const int high_surrogate = 0xD800 | ((codepoint >> 10) & 0x3FF);
6464 const int low_surrogate = 0xDC00 | (codepoint & 0x3FF);
6465 result[++pos] = hexify[(high_surrogate >> 12) & 0x0F];
6466 result[++pos] = hexify[(high_surrogate >> 8) & 0x0F];
6467 result[++pos] = hexify[(high_surrogate >> 4) & 0x0F];
6468 result[++pos] = hexify[high_surrogate & 0x0F];
6469 ++pos; // backslash is already in output
6470 result[++pos] = 'u';
6471 result[++pos] = hexify[(low_surrogate >> 12) & 0x0F];
6472 result[++pos] = hexify[(low_surrogate >> 8) & 0x0F];
6473 result[++pos] = hexify[(low_surrogate >> 4) & 0x0F];
6474 result[++pos] = hexify[low_surrogate & 0x0F];
6475 }
6476
6477 ++pos;
6478 }
6479
6480 /*!
6481 @brief dump escaped string
6482
6483 Escape a string by replacing certain special characters by a sequence of an
6484 escape character (backslash) and another character and other control
6485 characters by a sequence of "\u" followed by a four-digit hex
6486 representation. The escaped string is written to output stream @a o.
6487
6488 @param[in] s the string to escape
6489 @param[in] ensure_ascii whether to escape non-ASCII characters with
6490 \uXXXX sequences
6491
6492 @complexity Linear in the length of string @a s.
6493 */
dump_escaped(const string_t & s,const bool ensure_ascii) const6494 void dump_escaped(const string_t& s, const bool ensure_ascii) const
6495 {
6496 const auto space = extra_space(s, ensure_ascii);
6497 if (space == 0)
6498 {
6499 o->write_characters(s.c_str(), s.size());
6500 return;
6501 }
6502
6503 // create a result string of necessary size
6504 string_t result(s.size() + space, '\\');
6505 std::size_t pos = 0;
6506
6507 for (std::size_t i = 0; i < s.size(); ++i)
6508 {
6509 switch (s[i])
6510 {
6511 case '"': // quotation mark (0x22)
6512 {
6513 result[pos + 1] = '"';
6514 pos += 2;
6515 break;
6516 }
6517
6518 case '\\': // reverse solidus (0x5c)
6519 {
6520 // nothing to change
6521 pos += 2;
6522 break;
6523 }
6524
6525 case '\b': // backspace (0x08)
6526 {
6527 result[pos + 1] = 'b';
6528 pos += 2;
6529 break;
6530 }
6531
6532 case '\f': // formfeed (0x0c)
6533 {
6534 result[pos + 1] = 'f';
6535 pos += 2;
6536 break;
6537 }
6538
6539 case '\n': // newline (0x0a)
6540 {
6541 result[pos + 1] = 'n';
6542 pos += 2;
6543 break;
6544 }
6545
6546 case '\r': // carriage return (0x0d)
6547 {
6548 result[pos + 1] = 'r';
6549 pos += 2;
6550 break;
6551 }
6552
6553 case '\t': // horizontal tab (0x09)
6554 {
6555 result[pos + 1] = 't';
6556 pos += 2;
6557 break;
6558 }
6559
6560 default:
6561 {
6562 // escape control characters (0x00..0x1F) or, if
6563 // ensure_ascii parameter is used, non-ASCII characters
6564 if ((0x00 <= s[i] and s[i] <= 0x1F) or
6565 (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F)))
6566 {
6567 const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
6568 if (bytes == std::string::npos)
6569 {
6570 // copy invalid character as is
6571 result[pos++] = s[i];
6572 break;
6573 }
6574
6575 // check that the additional bytes are present
6576 assert(i + bytes < s.size());
6577
6578 // to use \uxxxx escaping, we first need to caluclate
6579 // the codepoint from the UTF-8 bytes
6580 int codepoint = 0;
6581
6582 assert(0 <= bytes and bytes <= 3);
6583 switch (bytes)
6584 {
6585 case 0:
6586 {
6587 codepoint = s[i] & 0xFF;
6588 break;
6589 }
6590
6591 case 1:
6592 {
6593 codepoint = ((s[i] & 0x3F) << 6)
6594 + (s[i + 1] & 0x7F);
6595 break;
6596 }
6597
6598 case 2:
6599 {
6600 codepoint = ((s[i] & 0x1F) << 12)
6601 + ((s[i + 1] & 0x7F) << 6)
6602 + (s[i + 2] & 0x7F);
6603 break;
6604 }
6605
6606 case 3:
6607 {
6608 codepoint = ((s[i] & 0xF) << 18)
6609 + ((s[i + 1] & 0x7F) << 12)
6610 + ((s[i + 2] & 0x7F) << 6)
6611 + (s[i + 3] & 0x7F);
6612 break;
6613 }
6614
6615 default:
6616 break; // LCOV_EXCL_LINE
6617 }
6618
6619 escape_codepoint(codepoint, result, pos);
6620 i += bytes;
6621 }
6622 else
6623 {
6624 // all other characters are added as-is
6625 result[pos++] = s[i];
6626 }
6627 break;
6628 }
6629 }
6630 }
6631
6632 assert(pos == result.size());
6633 o->write_characters(result.c_str(), result.size());
6634 }
6635
6636 /*!
6637 @brief dump an integer
6638
6639 Dump a given integer to output stream @a o. Works internally with
6640 @a number_buffer.
6641
6642 @param[in] x integer number (signed or unsigned) to dump
6643 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
6644 */
6645 template <
6646 typename NumberType,
6647 detail::enable_if_t<std::is_same<NumberType, number_unsigned_t>::value or
6648 std::is_same<NumberType, number_integer_t>::value,
6649 int> = 0 >
dump_integer(NumberType x)6650 void dump_integer(NumberType x)
6651 {
6652 // special case for "0"
6653 if (x == 0)
6654 {
6655 o->write_character('0');
6656 return;
6657 }
6658
6659 const bool is_negative = (x <= 0) and (x != 0); // see issue #755
6660 std::size_t i = 0;
6661
6662 while (x != 0)
6663 {
6664 // spare 1 byte for '\0'
6665 assert(i < number_buffer.size() - 1);
6666
6667 const auto digit = std::labs(static_cast<long>(x % 10));
6668 number_buffer[i++] = static_cast<char>('0' + digit);
6669 x /= 10;
6670 }
6671
6672 if (is_negative)
6673 {
6674 // make sure there is capacity for the '-'
6675 assert(i < number_buffer.size() - 2);
6676 number_buffer[i++] = '-';
6677 }
6678
6679 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
6680 o->write_characters(number_buffer.data(), i);
6681 }
6682
6683 /*!
6684 @brief dump a floating-point number
6685
6686 Dump a given floating-point number to output stream @a o. Works internally
6687 with @a number_buffer.
6688
6689 @param[in] x floating-point number to dump
6690 */
dump_float(number_float_t x)6691 void dump_float(number_float_t x)
6692 {
6693 // NaN / inf
6694 if (not std::isfinite(x) or std::isnan(x))
6695 {
6696 o->write_characters("null", 4);
6697 return;
6698 }
6699
6700 // get number of digits for a text -> float -> text round-trip
6701 static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
6702
6703 // the actual conversion
6704 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
6705
6706 // negative value indicates an error
6707 assert(len > 0);
6708 // check if buffer was large enough
6709 assert(static_cast<std::size_t>(len) < number_buffer.size());
6710
6711 // erase thousands separator
6712 if (thousands_sep != '\0')
6713 {
6714 const auto end = std::remove(number_buffer.begin(),
6715 number_buffer.begin() + len, thousands_sep);
6716 std::fill(end, number_buffer.end(), '\0');
6717 assert((end - number_buffer.begin()) <= len);
6718 len = (end - number_buffer.begin());
6719 }
6720
6721 // convert decimal point to '.'
6722 if (decimal_point != '\0' and decimal_point != '.')
6723 {
6724 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
6725 if (dec_pos != number_buffer.end())
6726 {
6727 *dec_pos = '.';
6728 }
6729 }
6730
6731 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
6732
6733 // determine if need to append ".0"
6734 const bool value_is_int_like =
6735 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
6736 [](char c)
6737 {
6738 return (c == '.' or c == 'e');
6739 });
6740
6741 if (value_is_int_like)
6742 {
6743 o->write_characters(".0", 2);
6744 }
6745 }
6746
6747 private:
6748 /// the output of the serializer
6749 output_adapter_t<char> o = nullptr;
6750
6751 /// a (hopefully) large enough character buffer
6752 std::array<char, 64> number_buffer{{}};
6753
6754 /// the locale
6755 const std::lconv* loc = nullptr;
6756 /// the locale's thousand separator character
6757 const char thousands_sep = '\0';
6758 /// the locale's decimal point character
6759 const char decimal_point = '\0';
6760
6761 /// the indentation character
6762 const char indent_char;
6763
6764 /// the indentation string
6765 string_t indent_string;
6766 };
6767
6768 template<typename BasicJsonType>
6769 class json_ref
6770 {
6771 public:
6772 using value_type = BasicJsonType;
6773
json_ref(value_type && value)6774 json_ref(value_type&& value)
6775 : owned_value(std::move(value)),
6776 value_ref(&owned_value),
6777 is_rvalue(true)
6778 {}
6779
json_ref(const value_type & value)6780 json_ref(const value_type& value)
6781 : value_ref(const_cast<value_type*>(&value)),
6782 is_rvalue(false)
6783 {}
6784
json_ref(std::initializer_list<json_ref> init)6785 json_ref(std::initializer_list<json_ref> init)
6786 : owned_value(init),
6787 value_ref(&owned_value),
6788 is_rvalue(true)
6789 {}
6790
6791 template <class... Args>
json_ref(Args &&...args)6792 json_ref(Args&&... args)
6793 : owned_value(std::forward<Args>(args)...),
6794 value_ref(&owned_value),
6795 is_rvalue(true)
6796 {}
6797
6798 // class should be movable only
6799 json_ref(json_ref&&) = default;
6800 json_ref(const json_ref&) = delete;
6801 json_ref& operator=(const json_ref&) = delete;
6802
moved_or_copied() const6803 value_type moved_or_copied() const
6804 {
6805 if (is_rvalue)
6806 {
6807 return std::move(*value_ref);
6808 }
6809 return *value_ref;
6810 }
6811
operator *() const6812 value_type const& operator*() const
6813 {
6814 return *static_cast<value_type const*>(value_ref);
6815 }
6816
operator ->() const6817 value_type const* operator->() const
6818 {
6819 return static_cast<value_type const*>(value_ref);
6820 }
6821
6822 private:
6823 mutable value_type owned_value = nullptr;
6824 value_type* value_ref = nullptr;
6825 const bool is_rvalue;
6826 };
6827
6828 } // namespace detail
6829
6830 /// namespace to hold default `to_json` / `from_json` functions
6831 namespace
6832 {
6833 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
6834 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
6835 }
6836
6837
6838 /*!
6839 @brief default JSONSerializer template argument
6840
6841 This serializer ignores the template arguments and uses ADL
6842 ([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
6843 for serialization.
6844 */
6845 template<typename, typename>
6846 struct adl_serializer
6847 {
6848 /*!
6849 @brief convert a JSON value to any value type
6850
6851 This function is usually called by the `get()` function of the
6852 @ref basic_json class (either explicit or via conversion operators).
6853
6854 @param[in] j JSON value to read from
6855 @param[in,out] val value to write to
6856 */
6857 template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer6858 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
6859 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
6860 {
6861 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
6862 }
6863
6864 /*!
6865 @brief convert any value type to a JSON value
6866
6867 This function is usually called by the constructors of the @ref basic_json
6868 class.
6869
6870 @param[in,out] j JSON value to write to
6871 @param[in] val value to read from
6872 */
6873 template<typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer6874 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
6875 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
6876 {
6877 ::nlohmann::to_json(j, std::forward<ValueType>(val));
6878 }
6879 };
6880
6881 /*!
6882 @brief JSON Pointer
6883
6884 A JSON pointer defines a string syntax for identifying a specific value
6885 within a JSON document. It can be used with functions `at` and
6886 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
6887
6888 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
6889
6890 @since version 2.0.0
6891 */
6892 class json_pointer
6893 {
6894 /// allow basic_json to access private members
6895 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6896 friend class basic_json;
6897
6898 public:
6899 /*!
6900 @brief create JSON pointer
6901
6902 Create a JSON pointer according to the syntax described in
6903 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
6904
6905 @param[in] s string representing the JSON pointer; if omitted, the empty
6906 string is assumed which references the whole JSON value
6907
6908 @throw parse_error.107 if the given JSON pointer @a s is nonempty and
6909 does not begin with a slash (`/`); see example below
6910
6911 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s
6912 is not followed by `0` (representing `~`) or `1` (representing `/`);
6913 see example below
6914
6915 @liveexample{The example shows the construction several valid JSON
6916 pointers as well as the exceptional behavior.,json_pointer}
6917
6918 @since version 2.0.0
6919 */
json_pointer(const std::string & s="")6920 explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {}
6921
6922 /*!
6923 @brief return a string representation of the JSON pointer
6924
6925 @invariant For each JSON pointer `ptr`, it holds:
6926 @code {.cpp}
6927 ptr == json_pointer(ptr.to_string());
6928 @endcode
6929
6930 @return a string representation of the JSON pointer
6931
6932 @liveexample{The example shows the result of `to_string`.,
6933 json_pointer__to_string}
6934
6935 @since version 2.0.0
6936 */
to_string() const6937 std::string to_string() const noexcept
6938 {
6939 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
6940 std::string{},
6941 [](const std::string & a, const std::string & b)
6942 {
6943 return a + "/" + escape(b);
6944 });
6945 }
6946
6947 /// @copydoc to_string()
operator std::string() const6948 operator std::string() const
6949 {
6950 return to_string();
6951 }
6952
6953 private:
6954 /*!
6955 @brief remove and return last reference pointer
6956 @throw out_of_range.405 if JSON pointer has no parent
6957 */
pop_back()6958 std::string pop_back()
6959 {
6960 if (JSON_UNLIKELY(is_root()))
6961 {
6962 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
6963 }
6964
6965 auto last = reference_tokens.back();
6966 reference_tokens.pop_back();
6967 return last;
6968 }
6969
6970 /// return whether pointer points to the root document
is_root() const6971 bool is_root() const
6972 {
6973 return reference_tokens.empty();
6974 }
6975
top() const6976 json_pointer top() const
6977 {
6978 if (JSON_UNLIKELY(is_root()))
6979 {
6980 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
6981 }
6982
6983 json_pointer result = *this;
6984 result.reference_tokens = {reference_tokens[0]};
6985 return result;
6986 }
6987
6988
6989 /*!
6990 @brief create and return a reference to the pointed to value
6991
6992 @complexity Linear in the number of reference tokens.
6993
6994 @throw parse_error.109 if array index is not a number
6995 @throw type_error.313 if value cannot be unflattened
6996 */
6997 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6998 NLOHMANN_BASIC_JSON_TPL& get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const;
6999
7000 /*!
7001 @brief return a reference to the pointed to value
7002
7003 @note This version does not throw if a value is not present, but tries to
7004 create nested values instead. For instance, calling this function
7005 with pointer `"/this/that"` on a null value is equivalent to calling
7006 `operator[]("this").operator[]("that")` on that value, effectively
7007 changing the null value to an object.
7008
7009 @param[in] ptr a JSON value
7010
7011 @return reference to the JSON value pointed to by the JSON pointer
7012
7013 @complexity Linear in the length of the JSON pointer.
7014
7015 @throw parse_error.106 if an array index begins with '0'
7016 @throw parse_error.109 if an array index was not a number
7017 @throw out_of_range.404 if the JSON pointer can not be resolved
7018 */
7019 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7020 NLOHMANN_BASIC_JSON_TPL& get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
7021
7022 /*!
7023 @throw parse_error.106 if an array index begins with '0'
7024 @throw parse_error.109 if an array index was not a number
7025 @throw out_of_range.402 if the array index '-' is used
7026 @throw out_of_range.404 if the JSON pointer can not be resolved
7027 */
7028 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7029 NLOHMANN_BASIC_JSON_TPL& get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
7030
7031 /*!
7032 @brief return a const reference to the pointed to value
7033
7034 @param[in] ptr a JSON value
7035
7036 @return const reference to the JSON value pointed to by the JSON
7037 pointer
7038
7039 @throw parse_error.106 if an array index begins with '0'
7040 @throw parse_error.109 if an array index was not a number
7041 @throw out_of_range.402 if the array index '-' is used
7042 @throw out_of_range.404 if the JSON pointer can not be resolved
7043 */
7044 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7045 const NLOHMANN_BASIC_JSON_TPL& get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
7046
7047 /*!
7048 @throw parse_error.106 if an array index begins with '0'
7049 @throw parse_error.109 if an array index was not a number
7050 @throw out_of_range.402 if the array index '-' is used
7051 @throw out_of_range.404 if the JSON pointer can not be resolved
7052 */
7053 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7054 const NLOHMANN_BASIC_JSON_TPL& get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
7055
7056 /*!
7057 @brief split the string input to reference tokens
7058
7059 @note This function is only called by the json_pointer constructor.
7060 All exceptions below are documented there.
7061
7062 @throw parse_error.107 if the pointer is not empty or begins with '/'
7063 @throw parse_error.108 if character '~' is not followed by '0' or '1'
7064 */
split(const std::string & reference_string)7065 static std::vector<std::string> split(const std::string& reference_string)
7066 {
7067 std::vector<std::string> result;
7068
7069 // special case: empty reference string -> no reference tokens
7070 if (reference_string.empty())
7071 {
7072 return result;
7073 }
7074
7075 // check if nonempty reference string begins with slash
7076 if (JSON_UNLIKELY(reference_string[0] != '/'))
7077 {
7078 JSON_THROW(detail::parse_error::create(107, 1,
7079 "JSON pointer must be empty or begin with '/' - was: '" +
7080 reference_string + "'"));
7081 }
7082
7083 // extract the reference tokens:
7084 // - slash: position of the last read slash (or end of string)
7085 // - start: position after the previous slash
7086 for (
7087 // search for the first slash after the first character
7088 std::size_t slash = reference_string.find_first_of('/', 1),
7089 // set the beginning of the first reference token
7090 start = 1;
7091 // we can stop if start == string::npos+1 = 0
7092 start != 0;
7093 // set the beginning of the next reference token
7094 // (will eventually be 0 if slash == std::string::npos)
7095 start = slash + 1,
7096 // find next slash
7097 slash = reference_string.find_first_of('/', start))
7098 {
7099 // use the text between the beginning of the reference token
7100 // (start) and the last slash (slash).
7101 auto reference_token = reference_string.substr(start, slash - start);
7102
7103 // check reference tokens are properly escaped
7104 for (std::size_t pos = reference_token.find_first_of('~');
7105 pos != std::string::npos;
7106 pos = reference_token.find_first_of('~', pos + 1))
7107 {
7108 assert(reference_token[pos] == '~');
7109
7110 // ~ must be followed by 0 or 1
7111 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
7112 (reference_token[pos + 1] != '0' and
7113 reference_token[pos + 1] != '1')))
7114 {
7115 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
7116 }
7117 }
7118
7119 // finally, store the reference token
7120 unescape(reference_token);
7121 result.push_back(reference_token);
7122 }
7123
7124 return result;
7125 }
7126
7127 /*!
7128 @brief replace all occurrences of a substring by another string
7129
7130 @param[in,out] s the string to manipulate; changed so that all
7131 occurrences of @a f are replaced with @a t
7132 @param[in] f the substring to replace with @a t
7133 @param[in] t the string to replace @a f
7134
7135 @pre The search string @a f must not be empty. **This precondition is
7136 enforced with an assertion.**
7137
7138 @since version 2.0.0
7139 */
replace_substring(std::string & s,const std::string & f,const std::string & t)7140 static void replace_substring(std::string& s, const std::string& f,
7141 const std::string& t)
7142 {
7143 assert(not f.empty());
7144 for (auto pos = s.find(f); // find first occurrence of f
7145 pos != std::string::npos; // make sure f was found
7146 s.replace(pos, f.size(), t), // replace with t, and
7147 pos = s.find(f, pos + t.size())) // find next occurrence of f
7148 {}
7149 }
7150
7151 /// escape "~"" to "~0" and "/" to "~1"
escape(std::string s)7152 static std::string escape(std::string s)
7153 {
7154 replace_substring(s, "~", "~0");
7155 replace_substring(s, "/", "~1");
7156 return s;
7157 }
7158
7159 /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)7160 static void unescape(std::string& s)
7161 {
7162 replace_substring(s, "~1", "/");
7163 replace_substring(s, "~0", "~");
7164 }
7165
7166 /*!
7167 @param[in] reference_string the reference string to the current value
7168 @param[in] value the value to consider
7169 @param[in,out] result the result object to insert values to
7170
7171 @note Empty objects or arrays are flattened to `null`.
7172 */
7173 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7174 static void flatten(const std::string& reference_string,
7175 const NLOHMANN_BASIC_JSON_TPL& value,
7176 NLOHMANN_BASIC_JSON_TPL& result);
7177
7178 /*!
7179 @param[in] value flattened JSON
7180
7181 @return unflattened JSON
7182
7183 @throw parse_error.109 if array index is not a number
7184 @throw type_error.314 if value is not an object
7185 @throw type_error.315 if object values are not primitive
7186 @throw type_error.313 if value cannot be unflattened
7187 */
7188 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7189 static NLOHMANN_BASIC_JSON_TPL
7190 unflatten(const NLOHMANN_BASIC_JSON_TPL& value);
7191
7192 friend bool operator==(json_pointer const& lhs,
7193 json_pointer const& rhs) noexcept;
7194
7195 friend bool operator!=(json_pointer const& lhs,
7196 json_pointer const& rhs) noexcept;
7197
7198 /// the reference tokens
7199 std::vector<std::string> reference_tokens;
7200 };
7201
7202 /*!
7203 @brief a class to store JSON values
7204
7205 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
7206 in @ref object_t)
7207 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
7208 in @ref array_t)
7209 @tparam StringType type for JSON strings and object keys (`std::string` by
7210 default; will be used in @ref string_t)
7211 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
7212 in @ref boolean_t)
7213 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
7214 default; will be used in @ref number_integer_t)
7215 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
7216 `uint64_t` by default; will be used in @ref number_unsigned_t)
7217 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
7218 default; will be used in @ref number_float_t)
7219 @tparam AllocatorType type of the allocator to use (`std::allocator` by
7220 default)
7221 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
7222 and `from_json()` (@ref adl_serializer by default)
7223
7224 @requirement The class satisfies the following concept requirements:
7225 - Basic
7226 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
7227 JSON values can be default constructed. The result will be a JSON null
7228 value.
7229 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
7230 A JSON value can be constructed from an rvalue argument.
7231 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
7232 A JSON value can be copy-constructed from an lvalue expression.
7233 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
7234 A JSON value van be assigned from an rvalue argument.
7235 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
7236 A JSON value can be copy-assigned from an lvalue expression.
7237 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
7238 JSON values can be destructed.
7239 - Layout
7240 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
7241 JSON values have
7242 [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
7243 All non-static data members are private and standard layout types, the
7244 class has no virtual functions or (virtual) base classes.
7245 - Library-wide
7246 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
7247 JSON values can be compared with `==`, see @ref
7248 operator==(const_reference,const_reference).
7249 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
7250 JSON values can be compared with `<`, see @ref
7251 operator<(const_reference,const_reference).
7252 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
7253 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
7254 other compatible types, using unqualified function call @ref swap().
7255 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
7256 JSON values can be compared against `std::nullptr_t` objects which are used
7257 to model the `null` value.
7258 - Container
7259 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
7260 JSON values can be used like STL containers and provide iterator access.
7261 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
7262 JSON values can be used like STL containers and provide reverse iterator
7263 access.
7264
7265 @invariant The member variables @a m_value and @a m_type have the following
7266 relationship:
7267 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
7268 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
7269 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
7270 The invariants are checked by member function assert_invariant().
7271
7272 @internal
7273 @note ObjectType trick from http://stackoverflow.com/a/9860911
7274 @endinternal
7275
7276 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
7277 Format](http://rfc7159.net/rfc7159)
7278
7279 @since version 1.0.0
7280
7281 @nosubgrouping
7282 */
7283 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7284 class basic_json
7285 {
7286 private:
7287 template<detail::value_t> friend struct detail::external_constructor;
7288 friend ::nlohmann::json_pointer;
7289 friend ::nlohmann::detail::parser<basic_json>;
7290 friend ::nlohmann::detail::serializer<basic_json>;
7291 template<typename BasicJsonType>
7292 friend class ::nlohmann::detail::iter_impl;
7293 template<typename BasicJsonType, typename CharType>
7294 friend class ::nlohmann::detail::binary_writer;
7295 template<typename BasicJsonType>
7296 friend class ::nlohmann::detail::binary_reader;
7297
7298 /// workaround type for MSVC
7299 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
7300
7301 // convenience aliases for types residing in namespace detail;
7302 using lexer = ::nlohmann::detail::lexer<basic_json>;
7303 using parser = ::nlohmann::detail::parser<basic_json>;
7304
7305 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
7306 template<typename BasicJsonType>
7307 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
7308 template<typename BasicJsonType>
7309 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
7310 template<typename Iterator>
7311 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
7312 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
7313
7314 template<typename CharType>
7315 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
7316
7317 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
7318 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
7319
7320 using serializer = ::nlohmann::detail::serializer<basic_json>;
7321
7322 public:
7323 using value_t = detail::value_t;
7324 // forward declarations
7325 using json_pointer = ::nlohmann::json_pointer;
7326 template<typename T, typename SFINAE>
7327 using json_serializer = JSONSerializer<T, SFINAE>;
7328
7329 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
7330
7331 ////////////////
7332 // exceptions //
7333 ////////////////
7334
7335 /// @name exceptions
7336 /// Classes to implement user-defined exceptions.
7337 /// @{
7338
7339 /// @copydoc detail::exception
7340 using exception = detail::exception;
7341 /// @copydoc detail::parse_error
7342 using parse_error = detail::parse_error;
7343 /// @copydoc detail::invalid_iterator
7344 using invalid_iterator = detail::invalid_iterator;
7345 /// @copydoc detail::type_error
7346 using type_error = detail::type_error;
7347 /// @copydoc detail::out_of_range
7348 using out_of_range = detail::out_of_range;
7349 /// @copydoc detail::other_error
7350 using other_error = detail::other_error;
7351
7352 /// @}
7353
7354
7355 /////////////////////
7356 // container types //
7357 /////////////////////
7358
7359 /// @name container types
7360 /// The canonic container types to use @ref basic_json like any other STL
7361 /// container.
7362 /// @{
7363
7364 /// the type of elements in a basic_json container
7365 using value_type = basic_json;
7366
7367 /// the type of an element reference
7368 using reference = value_type&;
7369 /// the type of an element const reference
7370 using const_reference = const value_type&;
7371
7372 /// a type to represent differences between iterators
7373 using difference_type = std::ptrdiff_t;
7374 /// a type to represent container sizes
7375 using size_type = std::size_t;
7376
7377 /// the allocator type
7378 using allocator_type = AllocatorType<basic_json>;
7379
7380 /// the type of an element pointer
7381 using pointer = typename std::allocator_traits<allocator_type>::pointer;
7382 /// the type of an element const pointer
7383 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
7384
7385 /// an iterator for a basic_json container
7386 using iterator = iter_impl<basic_json>;
7387 /// a const iterator for a basic_json container
7388 using const_iterator = iter_impl<const basic_json>;
7389 /// a reverse iterator for a basic_json container
7390 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
7391 /// a const reverse iterator for a basic_json container
7392 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
7393
7394 /// @}
7395
7396
7397 /*!
7398 @brief returns the allocator associated with the container
7399 */
get_allocator()7400 static allocator_type get_allocator()
7401 {
7402 return allocator_type();
7403 }
7404
7405 /*!
7406 @brief returns version information on the library
7407
7408 This function returns a JSON object with information about the library,
7409 including the version number and information on the platform and compiler.
7410
7411 @return JSON object holding version information
7412 key | description
7413 ----------- | ---------------
7414 `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).
7415 `copyright` | The copyright line for the library as string.
7416 `name` | The name of the library as string.
7417 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
7418 `url` | The URL of the project as string.
7419 `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).
7420
7421 @liveexample{The following code shows an example output of the `meta()`
7422 function.,meta}
7423
7424 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7425 changes to any JSON value.
7426
7427 @complexity Constant.
7428
7429 @since 2.1.0
7430 */
meta()7431 static basic_json meta()
7432 {
7433 basic_json result;
7434
7435 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
7436 result["name"] = "JSON for Modern C++";
7437 result["url"] = "https://github.com/nlohmann/json";
7438 result["version"] =
7439 {
7440 {"string", "2.1.1"}, {"major", 2}, {"minor", 1}, {"patch", 1}
7441 };
7442
7443 #ifdef _WIN32
7444 result["platform"] = "win32";
7445 #elif defined __linux__
7446 result["platform"] = "linux";
7447 #elif defined __APPLE__
7448 result["platform"] = "apple";
7449 #elif defined __unix__
7450 result["platform"] = "unix";
7451 #else
7452 result["platform"] = "unknown";
7453 #endif
7454
7455 #if defined(__ICC) || defined(__INTEL_COMPILER)
7456 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
7457 #elif defined(__clang__)
7458 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
7459 #elif defined(__GNUC__) || defined(__GNUG__)
7460 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
7461 #elif defined(__HP_cc) || defined(__HP_aCC)
7462 result["compiler"] = "hp"
7463 #elif defined(__IBMCPP__)
7464 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
7465 #elif defined(_MSC_VER)
7466 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
7467 #elif defined(__PGI)
7468 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
7469 #elif defined(__SUNPRO_CC)
7470 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
7471 #else
7472 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
7473 #endif
7474
7475 #ifdef __cplusplus
7476 result["compiler"]["c++"] = std::to_string(__cplusplus);
7477 #else
7478 result["compiler"]["c++"] = "unknown";
7479 #endif
7480 return result;
7481 }
7482
7483
7484 ///////////////////////////
7485 // JSON value data types //
7486 ///////////////////////////
7487
7488 /// @name JSON value data types
7489 /// The data types to store a JSON value. These types are derived from
7490 /// the template arguments passed to class @ref basic_json.
7491 /// @{
7492
7493 /*!
7494 @brief a type for an object
7495
7496 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
7497 > An object is an unordered collection of zero or more name/value pairs,
7498 > where a name is a string and a value is a string, number, boolean, null,
7499 > object, or array.
7500
7501 To store objects in C++, a type is defined by the template parameters
7502 described below.
7503
7504 @tparam ObjectType the container to store objects (e.g., `std::map` or
7505 `std::unordered_map`)
7506 @tparam StringType the type of the keys or names (e.g., `std::string`).
7507 The comparison function `std::less<StringType>` is used to order elements
7508 inside the container.
7509 @tparam AllocatorType the allocator to use for objects (e.g.,
7510 `std::allocator`)
7511
7512 #### Default type
7513
7514 With the default values for @a ObjectType (`std::map`), @a StringType
7515 (`std::string`), and @a AllocatorType (`std::allocator`), the default
7516 value for @a object_t is:
7517
7518 @code {.cpp}
7519 std::map<
7520 std::string, // key_type
7521 basic_json, // value_type
7522 std::less<std::string>, // key_compare
7523 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
7524 >
7525 @endcode
7526
7527 #### Behavior
7528
7529 The choice of @a object_t influences the behavior of the JSON class. With
7530 the default type, objects have the following behavior:
7531
7532 - When all names are unique, objects will be interoperable in the sense
7533 that all software implementations receiving that object will agree on
7534 the name-value mappings.
7535 - When the names within an object are not unique, later stored name/value
7536 pairs overwrite previously stored name/value pairs, leaving the used
7537 names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
7538 be treated as equal and both stored as `{"key": 1}`.
7539 - Internally, name/value pairs are stored in lexicographical order of the
7540 names. Objects will also be serialized (see @ref dump) in this order.
7541 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
7542 and serialized as `{"a": 2, "b": 1}`.
7543 - When comparing objects, the order of the name/value pairs is irrelevant.
7544 This makes objects interoperable in the sense that they will not be
7545 affected by these differences. For instance, `{"b": 1, "a": 2}` and
7546 `{"a": 2, "b": 1}` will be treated as equal.
7547
7548 #### Limits
7549
7550 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7551 > An implementation may set limits on the maximum depth of nesting.
7552
7553 In this class, the object's limit of nesting is not explicitly constrained.
7554 However, a maximum depth of nesting may be introduced by the compiler or
7555 runtime environment. A theoretical limit can be queried by calling the
7556 @ref max_size function of a JSON object.
7557
7558 #### Storage
7559
7560 Objects are stored as pointers in a @ref basic_json type. That is, for any
7561 access to object values, a pointer of type `object_t*` must be
7562 dereferenced.
7563
7564 @sa @ref array_t -- type for an array value
7565
7566 @since version 1.0.0
7567
7568 @note The order name/value pairs are added to the object is *not*
7569 preserved by the library. Therefore, iterating an object may return
7570 name/value pairs in a different order than they were originally stored. In
7571 fact, keys will be traversed in alphabetical order as `std::map` with
7572 `std::less` is used by default. Please note this behavior conforms to [RFC
7573 7159](http://rfc7159.net/rfc7159), because any order implements the
7574 specified "unordered" nature of JSON objects.
7575 */
7576
7577 #if defined(JSON_HAS_CPP_14)
7578 // Use transparent comparator if possible, combined with perfect forwarding
7579 // on find() and count() calls prevents unnecessary string construction.
7580 using object_comparator_t = std::less<>;
7581 #else
7582 using object_comparator_t = std::less<StringType>;
7583 #endif
7584 using object_t = ObjectType<StringType,
7585 basic_json,
7586 object_comparator_t,
7587 AllocatorType<std::pair<const StringType,
7588 basic_json>>>;
7589
7590 /*!
7591 @brief a type for an array
7592
7593 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
7594 > An array is an ordered sequence of zero or more values.
7595
7596 To store objects in C++, a type is defined by the template parameters
7597 explained below.
7598
7599 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
7600 `std::list`)
7601 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
7602
7603 #### Default type
7604
7605 With the default values for @a ArrayType (`std::vector`) and @a
7606 AllocatorType (`std::allocator`), the default value for @a array_t is:
7607
7608 @code {.cpp}
7609 std::vector<
7610 basic_json, // value_type
7611 std::allocator<basic_json> // allocator_type
7612 >
7613 @endcode
7614
7615 #### Limits
7616
7617 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7618 > An implementation may set limits on the maximum depth of nesting.
7619
7620 In this class, the array's limit of nesting is not explicitly constrained.
7621 However, a maximum depth of nesting may be introduced by the compiler or
7622 runtime environment. A theoretical limit can be queried by calling the
7623 @ref max_size function of a JSON array.
7624
7625 #### Storage
7626
7627 Arrays are stored as pointers in a @ref basic_json type. That is, for any
7628 access to array values, a pointer of type `array_t*` must be dereferenced.
7629
7630 @sa @ref object_t -- type for an object value
7631
7632 @since version 1.0.0
7633 */
7634 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
7635
7636 /*!
7637 @brief a type for a string
7638
7639 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
7640 > A string is a sequence of zero or more Unicode characters.
7641
7642 To store objects in C++, a type is defined by the template parameter
7643 described below. Unicode values are split by the JSON class into
7644 byte-sized characters during deserialization.
7645
7646 @tparam StringType the container to store strings (e.g., `std::string`).
7647 Note this container is used for keys/names in objects, see @ref object_t.
7648
7649 #### Default type
7650
7651 With the default values for @a StringType (`std::string`), the default
7652 value for @a string_t is:
7653
7654 @code {.cpp}
7655 std::string
7656 @endcode
7657
7658 #### Encoding
7659
7660 Strings are stored in UTF-8 encoding. Therefore, functions like
7661 `std::string::size()` or `std::string::length()` return the number of
7662 bytes in the string rather than the number of characters or glyphs.
7663
7664 #### String comparison
7665
7666 [RFC 7159](http://rfc7159.net/rfc7159) states:
7667 > Software implementations are typically required to test names of object
7668 > members for equality. Implementations that transform the textual
7669 > representation into sequences of Unicode code units and then perform the
7670 > comparison numerically, code unit by code unit, are interoperable in the
7671 > sense that implementations will agree in all cases on equality or
7672 > inequality of two strings. For example, implementations that compare
7673 > strings with escaped characters unconverted may incorrectly find that
7674 > `"a\\b"` and `"a\u005Cb"` are not equal.
7675
7676 This implementation is interoperable as it does compare strings code unit
7677 by code unit.
7678
7679 #### Storage
7680
7681 String values are stored as pointers in a @ref basic_json type. That is,
7682 for any access to string values, a pointer of type `string_t*` must be
7683 dereferenced.
7684
7685 @since version 1.0.0
7686 */
7687 using string_t = StringType;
7688
7689 /*!
7690 @brief a type for a boolean
7691
7692 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
7693 type which differentiates the two literals `true` and `false`.
7694
7695 To store objects in C++, a type is defined by the template parameter @a
7696 BooleanType which chooses the type to use.
7697
7698 #### Default type
7699
7700 With the default values for @a BooleanType (`bool`), the default value for
7701 @a boolean_t is:
7702
7703 @code {.cpp}
7704 bool
7705 @endcode
7706
7707 #### Storage
7708
7709 Boolean values are stored directly inside a @ref basic_json type.
7710
7711 @since version 1.0.0
7712 */
7713 using boolean_t = BooleanType;
7714
7715 /*!
7716 @brief a type for a number (integer)
7717
7718 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7719 > The representation of numbers is similar to that used in most
7720 > programming languages. A number is represented in base 10 using decimal
7721 > digits. It contains an integer component that may be prefixed with an
7722 > optional minus sign, which may be followed by a fraction part and/or an
7723 > exponent part. Leading zeros are not allowed. (...) Numeric values that
7724 > cannot be represented in the grammar below (such as Infinity and NaN)
7725 > are not permitted.
7726
7727 This description includes both integer and floating-point numbers.
7728 However, C++ allows more precise storage if it is known whether the number
7729 is a signed integer, an unsigned integer or a floating-point number.
7730 Therefore, three different types, @ref number_integer_t, @ref
7731 number_unsigned_t and @ref number_float_t are used.
7732
7733 To store integer numbers in C++, a type is defined by the template
7734 parameter @a NumberIntegerType which chooses the type to use.
7735
7736 #### Default type
7737
7738 With the default values for @a NumberIntegerType (`int64_t`), the default
7739 value for @a number_integer_t is:
7740
7741 @code {.cpp}
7742 int64_t
7743 @endcode
7744
7745 #### Default behavior
7746
7747 - The restrictions about leading zeros is not enforced in C++. Instead,
7748 leading zeros in integer literals lead to an interpretation as octal
7749 number. Internally, the value will be stored as decimal number. For
7750 instance, the C++ integer literal `010` will be serialized to `8`.
7751 During deserialization, leading zeros yield an error.
7752 - Not-a-number (NaN) values will be serialized to `null`.
7753
7754 #### Limits
7755
7756 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7757 > An implementation may set limits on the range and precision of numbers.
7758
7759 When the default type is used, the maximal integer number that can be
7760 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
7761 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
7762 that are out of range will yield over/underflow when used in a
7763 constructor. During deserialization, too large or small integer numbers
7764 will be automatically be stored as @ref number_unsigned_t or @ref
7765 number_float_t.
7766
7767 [RFC 7159](http://rfc7159.net/rfc7159) further states:
7768 > Note that when such software is used, numbers that are integers and are
7769 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
7770 > that implementations will agree exactly on their numeric values.
7771
7772 As this range is a subrange of the exactly supported range [INT64_MIN,
7773 INT64_MAX], this class's integer type is interoperable.
7774
7775 #### Storage
7776
7777 Integer number values are stored directly inside a @ref basic_json type.
7778
7779 @sa @ref number_float_t -- type for number values (floating-point)
7780
7781 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
7782
7783 @since version 1.0.0
7784 */
7785 using number_integer_t = NumberIntegerType;
7786
7787 /*!
7788 @brief a type for a number (unsigned)
7789
7790 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7791 > The representation of numbers is similar to that used in most
7792 > programming languages. A number is represented in base 10 using decimal
7793 > digits. It contains an integer component that may be prefixed with an
7794 > optional minus sign, which may be followed by a fraction part and/or an
7795 > exponent part. Leading zeros are not allowed. (...) Numeric values that
7796 > cannot be represented in the grammar below (such as Infinity and NaN)
7797 > are not permitted.
7798
7799 This description includes both integer and floating-point numbers.
7800 However, C++ allows more precise storage if it is known whether the number
7801 is a signed integer, an unsigned integer or a floating-point number.
7802 Therefore, three different types, @ref number_integer_t, @ref
7803 number_unsigned_t and @ref number_float_t are used.
7804
7805 To store unsigned integer numbers in C++, a type is defined by the
7806 template parameter @a NumberUnsignedType which chooses the type to use.
7807
7808 #### Default type
7809
7810 With the default values for @a NumberUnsignedType (`uint64_t`), the
7811 default value for @a number_unsigned_t is:
7812
7813 @code {.cpp}
7814 uint64_t
7815 @endcode
7816
7817 #### Default behavior
7818
7819 - The restrictions about leading zeros is not enforced in C++. Instead,
7820 leading zeros in integer literals lead to an interpretation as octal
7821 number. Internally, the value will be stored as decimal number. For
7822 instance, the C++ integer literal `010` will be serialized to `8`.
7823 During deserialization, leading zeros yield an error.
7824 - Not-a-number (NaN) values will be serialized to `null`.
7825
7826 #### Limits
7827
7828 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7829 > An implementation may set limits on the range and precision of numbers.
7830
7831 When the default type is used, the maximal integer number that can be
7832 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
7833 number that can be stored is `0`. Integer numbers that are out of range
7834 will yield over/underflow when used in a constructor. During
7835 deserialization, too large or small integer numbers will be automatically
7836 be stored as @ref number_integer_t or @ref number_float_t.
7837
7838 [RFC 7159](http://rfc7159.net/rfc7159) further states:
7839 > Note that when such software is used, numbers that are integers and are
7840 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
7841 > that implementations will agree exactly on their numeric values.
7842
7843 As this range is a subrange (when considered in conjunction with the
7844 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
7845 this class's integer type is interoperable.
7846
7847 #### Storage
7848
7849 Integer number values are stored directly inside a @ref basic_json type.
7850
7851 @sa @ref number_float_t -- type for number values (floating-point)
7852 @sa @ref number_integer_t -- type for number values (integer)
7853
7854 @since version 2.0.0
7855 */
7856 using number_unsigned_t = NumberUnsignedType;
7857
7858 /*!
7859 @brief a type for a number (floating-point)
7860
7861 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7862 > The representation of numbers is similar to that used in most
7863 > programming languages. A number is represented in base 10 using decimal
7864 > digits. It contains an integer component that may be prefixed with an
7865 > optional minus sign, which may be followed by a fraction part and/or an
7866 > exponent part. Leading zeros are not allowed. (...) Numeric values that
7867 > cannot be represented in the grammar below (such as Infinity and NaN)
7868 > are not permitted.
7869
7870 This description includes both integer and floating-point numbers.
7871 However, C++ allows more precise storage if it is known whether the number
7872 is a signed integer, an unsigned integer or a floating-point number.
7873 Therefore, three different types, @ref number_integer_t, @ref
7874 number_unsigned_t and @ref number_float_t are used.
7875
7876 To store floating-point numbers in C++, a type is defined by the template
7877 parameter @a NumberFloatType which chooses the type to use.
7878
7879 #### Default type
7880
7881 With the default values for @a NumberFloatType (`double`), the default
7882 value for @a number_float_t is:
7883
7884 @code {.cpp}
7885 double
7886 @endcode
7887
7888 #### Default behavior
7889
7890 - The restrictions about leading zeros is not enforced in C++. Instead,
7891 leading zeros in floating-point literals will be ignored. Internally,
7892 the value will be stored as decimal number. For instance, the C++
7893 floating-point literal `01.2` will be serialized to `1.2`. During
7894 deserialization, leading zeros yield an error.
7895 - Not-a-number (NaN) values will be serialized to `null`.
7896
7897 #### Limits
7898
7899 [RFC 7159](http://rfc7159.net/rfc7159) states:
7900 > This specification allows implementations to set limits on the range and
7901 > precision of numbers accepted. Since software that implements IEEE
7902 > 754-2008 binary64 (double precision) numbers is generally available and
7903 > widely used, good interoperability can be achieved by implementations
7904 > that expect no more precision or range than these provide, in the sense
7905 > that implementations will approximate JSON numbers within the expected
7906 > precision.
7907
7908 This implementation does exactly follow this approach, as it uses double
7909 precision floating-point numbers. Note values smaller than
7910 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
7911 will be stored as NaN internally and be serialized to `null`.
7912
7913 #### Storage
7914
7915 Floating-point number values are stored directly inside a @ref basic_json
7916 type.
7917
7918 @sa @ref number_integer_t -- type for number values (integer)
7919
7920 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
7921
7922 @since version 1.0.0
7923 */
7924 using number_float_t = NumberFloatType;
7925
7926 /// @}
7927
7928 private:
7929
7930 /// helper for exception-safe object creation
7931 template<typename T, typename... Args>
create(Args &&...args)7932 static T* create(Args&& ... args)
7933 {
7934 AllocatorType<T> alloc;
7935 auto deleter = [&](T * object)
7936 {
7937 alloc.deallocate(object, 1);
7938 };
7939 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
7940 alloc.construct(object.get(), std::forward<Args>(args)...);
7941 assert(object != nullptr);
7942 return object.release();
7943 }
7944
7945 ////////////////////////
7946 // JSON value storage //
7947 ////////////////////////
7948
7949 /*!
7950 @brief a JSON value
7951
7952 The actual storage for a JSON value of the @ref basic_json class. This
7953 union combines the different storage types for the JSON value types
7954 defined in @ref value_t.
7955
7956 JSON type | value_t type | used type
7957 --------- | --------------- | ------------------------
7958 object | object | pointer to @ref object_t
7959 array | array | pointer to @ref array_t
7960 string | string | pointer to @ref string_t
7961 boolean | boolean | @ref boolean_t
7962 number | number_integer | @ref number_integer_t
7963 number | number_unsigned | @ref number_unsigned_t
7964 number | number_float | @ref number_float_t
7965 null | null | *no value is stored*
7966
7967 @note Variable-length types (objects, arrays, and strings) are stored as
7968 pointers. The size of the union should not exceed 64 bits if the default
7969 value types are used.
7970
7971 @since version 1.0.0
7972 */
7973 union json_value
7974 {
7975 /// object (stored with pointer to save storage)
7976 object_t* object;
7977 /// array (stored with pointer to save storage)
7978 array_t* array;
7979 /// string (stored with pointer to save storage)
7980 string_t* string;
7981 /// boolean
7982 boolean_t boolean;
7983 /// number (integer)
7984 number_integer_t number_integer;
7985 /// number (unsigned integer)
7986 number_unsigned_t number_unsigned;
7987 /// number (floating-point)
7988 number_float_t number_float;
7989
7990 /// default constructor (for null values)
7991 json_value() = default;
7992 /// constructor for booleans
json_value(boolean_t v)7993 json_value(boolean_t v) noexcept : boolean(v) {}
7994 /// constructor for numbers (integer)
json_value(number_integer_t v)7995 json_value(number_integer_t v) noexcept : number_integer(v) {}
7996 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)7997 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
7998 /// constructor for numbers (floating-point)
json_value(number_float_t v)7999 json_value(number_float_t v) noexcept : number_float(v) {}
8000 /// constructor for empty values of a given type
json_value(value_t t)8001 json_value(value_t t)
8002 {
8003 switch (t)
8004 {
8005 case value_t::object:
8006 {
8007 object = create<object_t>();
8008 break;
8009 }
8010
8011 case value_t::array:
8012 {
8013 array = create<array_t>();
8014 break;
8015 }
8016
8017 case value_t::string:
8018 {
8019 string = create<string_t>("");
8020 break;
8021 }
8022
8023 case value_t::boolean:
8024 {
8025 boolean = boolean_t(false);
8026 break;
8027 }
8028
8029 case value_t::number_integer:
8030 {
8031 number_integer = number_integer_t(0);
8032 break;
8033 }
8034
8035 case value_t::number_unsigned:
8036 {
8037 number_unsigned = number_unsigned_t(0);
8038 break;
8039 }
8040
8041 case value_t::number_float:
8042 {
8043 number_float = number_float_t(0.0);
8044 break;
8045 }
8046
8047 case value_t::null:
8048 {
8049 break;
8050 }
8051
8052 default:
8053 {
8054 if (JSON_UNLIKELY(t == value_t::null))
8055 {
8056 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
8057 }
8058 break;
8059 }
8060 }
8061 }
8062
8063 /// constructor for strings
json_value(const string_t & value)8064 json_value(const string_t& value)
8065 {
8066 string = create<string_t>(value);
8067 }
8068
8069 /// constructor for rvalue strings
json_value(string_t && value)8070 json_value(string_t&& value)
8071 {
8072 string = create<string_t>(std::move(value));
8073 }
8074
8075 /// constructor for objects
json_value(const object_t & value)8076 json_value(const object_t& value)
8077 {
8078 object = create<object_t>(value);
8079 }
8080
8081 /// constructor for rvalue objects
json_value(object_t && value)8082 json_value(object_t&& value)
8083 {
8084 object = create<object_t>(std::move(value));
8085 }
8086
8087 /// constructor for arrays
json_value(const array_t & value)8088 json_value(const array_t& value)
8089 {
8090 array = create<array_t>(value);
8091 }
8092
8093 /// constructor for rvalue arrays
json_value(array_t && value)8094 json_value(array_t&& value)
8095 {
8096 array = create<array_t>(std::move(value));
8097 }
8098
destroy(value_t t)8099 void destroy(value_t t)
8100 {
8101 switch (t)
8102 {
8103 case value_t::object:
8104 {
8105 AllocatorType<object_t> alloc;
8106 alloc.destroy(object);
8107 alloc.deallocate(object, 1);
8108 break;
8109 }
8110
8111 case value_t::array:
8112 {
8113 AllocatorType<array_t> alloc;
8114 alloc.destroy(array);
8115 alloc.deallocate(array, 1);
8116 break;
8117 }
8118
8119 case value_t::string:
8120 {
8121 AllocatorType<string_t> alloc;
8122 alloc.destroy(string);
8123 alloc.deallocate(string, 1);
8124 break;
8125 }
8126
8127 default:
8128 {
8129 break;
8130 }
8131 }
8132 }
8133 };
8134
8135 /*!
8136 @brief checks the class invariants
8137
8138 This function asserts the class invariants. It needs to be called at the
8139 end of every constructor to make sure that created objects respect the
8140 invariant. Furthermore, it has to be called each time the type of a JSON
8141 value is changed, because the invariant expresses a relationship between
8142 @a m_type and @a m_value.
8143 */
assert_invariant() const8144 void assert_invariant() const
8145 {
8146 assert(m_type != value_t::object or m_value.object != nullptr);
8147 assert(m_type != value_t::array or m_value.array != nullptr);
8148 assert(m_type != value_t::string or m_value.string != nullptr);
8149 }
8150
8151 public:
8152 //////////////////////////
8153 // JSON parser callback //
8154 //////////////////////////
8155
8156 using parse_event_t = typename parser::parse_event_t;
8157
8158 /*!
8159 @brief per-element parser callback type
8160
8161 With a parser callback function, the result of parsing a JSON text can be
8162 influenced. When passed to @ref parse, it is called on certain events
8163 (passed as @ref parse_event_t via parameter @a event) with a set recursion
8164 depth @a depth and context JSON value @a parsed. The return value of the
8165 callback function is a boolean indicating whether the element that emitted
8166 the callback shall be kept or not.
8167
8168 We distinguish six scenarios (determined by the event type) in which the
8169 callback function can be called. The following table describes the values
8170 of the parameters @a depth, @a event, and @a parsed.
8171
8172 parameter @a event | description | parameter @a depth | parameter @a parsed
8173 ------------------ | ----------- | ------------------ | -------------------
8174 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
8175 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
8176 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
8177 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
8178 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
8179 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
8180
8181 @image html callback_events.png "Example when certain parse events are triggered"
8182
8183 Discarding a value (i.e., returning `false`) has different effects
8184 depending on the context in which function was called:
8185
8186 - Discarded values in structured types are skipped. That is, the parser
8187 will behave as if the discarded value was never read.
8188 - In case a value outside a structured type is skipped, it is replaced
8189 with `null`. This case happens if the top-level element is skipped.
8190
8191 @param[in] depth the depth of the recursion during parsing
8192
8193 @param[in] event an event of type parse_event_t indicating the context in
8194 the callback function has been called
8195
8196 @param[in,out] parsed the current intermediate parse result; note that
8197 writing to this value has no effect for parse_event_t::key events
8198
8199 @return Whether the JSON value which called the function during parsing
8200 should be kept (`true`) or not (`false`). In the latter case, it is either
8201 skipped completely or replaced by an empty discarded object.
8202
8203 @sa @ref parse for examples
8204
8205 @since version 1.0.0
8206 */
8207 using parser_callback_t = typename parser::parser_callback_t;
8208
8209
8210 //////////////////
8211 // constructors //
8212 //////////////////
8213
8214 /// @name constructors and destructors
8215 /// Constructors of class @ref basic_json, copy/move constructor, copy
8216 /// assignment, static functions creating objects, and the destructor.
8217 /// @{
8218
8219 /*!
8220 @brief create an empty value with a given type
8221
8222 Create an empty JSON value with a given type. The value will be default
8223 initialized with an empty value which depends on the type:
8224
8225 Value type | initial value
8226 ----------- | -------------
8227 null | `null`
8228 boolean | `false`
8229 string | `""`
8230 number | `0`
8231 object | `{}`
8232 array | `[]`
8233
8234 @param[in] v the type of the value to create
8235
8236 @complexity Constant.
8237
8238 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8239 changes to any JSON value.
8240
8241 @liveexample{The following code shows the constructor for different @ref
8242 value_t values,basic_json__value_t}
8243
8244 @sa @ref clear() -- restores the postcondition of this constructor
8245
8246 @since version 1.0.0
8247 */
basic_json(const value_t v)8248 basic_json(const value_t v)
8249 : m_type(v), m_value(v)
8250 {
8251 assert_invariant();
8252 }
8253
8254 /*!
8255 @brief create a null object
8256
8257 Create a `null` JSON value. It either takes a null pointer as parameter
8258 (explicitly creating `null`) or no parameter (implicitly creating `null`).
8259 The passed null pointer itself is not read -- it is only used to choose
8260 the right constructor.
8261
8262 @complexity Constant.
8263
8264 @exceptionsafety No-throw guarantee: this constructor never throws
8265 exceptions.
8266
8267 @liveexample{The following code shows the constructor with and without a
8268 null pointer parameter.,basic_json__nullptr_t}
8269
8270 @since version 1.0.0
8271 */
basic_json(std::nullptr_t=nullptr)8272 basic_json(std::nullptr_t = nullptr) noexcept
8273 : basic_json(value_t::null)
8274 {
8275 assert_invariant();
8276 }
8277
8278 /*!
8279 @brief create a JSON value
8280
8281 This is a "catch all" constructor for all compatible JSON types; that is,
8282 types for which a `to_json()` method exsits. The constructor forwards the
8283 parameter @a val to that method (to `json_serializer<U>::to_json` method
8284 with `U = uncvref_t<CompatibleType>`, to be exact).
8285
8286 Template type @a CompatibleType includes, but is not limited to, the
8287 following types:
8288 - **arrays**: @ref array_t and all kinds of compatible containers such as
8289 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
8290 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
8291 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
8292 which a @ref basic_json value can be constructed.
8293 - **objects**: @ref object_t and all kinds of compatible associative
8294 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
8295 and `std::unordered_multimap` with a `key_type` compatible to
8296 @ref string_t and a `value_type` from which a @ref basic_json value can
8297 be constructed.
8298 - **strings**: @ref string_t, string literals, and all compatible string
8299 containers can be used.
8300 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
8301 @ref number_float_t, and all convertible number types such as `int`,
8302 `size_t`, `int64_t`, `float` or `double` can be used.
8303 - **boolean**: @ref boolean_t / `bool` can be used.
8304
8305 See the examples below.
8306
8307 @tparam CompatibleType a type such that:
8308 - @a CompatibleType is not derived from `std::istream`,
8309 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
8310 constructors),
8311 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
8312 @ref json_pointer, @ref iterator, etc ...)
8313 - @ref @ref json_serializer<U> has a
8314 `to_json(basic_json_t&, CompatibleType&&)` method
8315
8316 @tparam U = `uncvref_t<CompatibleType>`
8317
8318 @param[in] val the value to be forwarded to the respective constructor
8319
8320 @complexity Usually linear in the size of the passed @a val, also
8321 depending on the implementation of the called `to_json()`
8322 method.
8323
8324 @exceptionsafety Depends on the called constructor. For types directly
8325 supported by the library (i.e., all types for which no `to_json()` function
8326 was provided), strong guarantee holds: if an exception is thrown, there are
8327 no changes to any JSON value.
8328
8329 @liveexample{The following code shows the constructor with several
8330 compatible types.,basic_json__CompatibleType}
8331
8332 @since version 2.1.0
8333 */
8334 template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
8335 detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
8336 not std::is_same<U, basic_json_t>::value and
8337 not detail::is_basic_json_nested_type<
8338 basic_json_t, U>::value and
8339 detail::has_to_json<basic_json, U>::value,
8340 int> = 0>
basic_json(CompatibleType && val)8341 basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
8342 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
8343 {
8344 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
8345 assert_invariant();
8346 }
8347
8348 /*!
8349 @brief create a container (array or object) from an initializer list
8350
8351 Creates a JSON value of type array or object from the passed initializer
8352 list @a init. In case @a type_deduction is `true` (default), the type of
8353 the JSON value to be created is deducted from the initializer list @a init
8354 according to the following rules:
8355
8356 1. If the list is empty, an empty JSON object value `{}` is created.
8357 2. If the list consists of pairs whose first element is a string, a JSON
8358 object value is created where the first elements of the pairs are
8359 treated as keys and the second elements are as values.
8360 3. In all other cases, an array is created.
8361
8362 The rules aim to create the best fit between a C++ initializer list and
8363 JSON values. The rationale is as follows:
8364
8365 1. The empty initializer list is written as `{}` which is exactly an empty
8366 JSON object.
8367 2. C++ has no way of describing mapped types other than to list a list of
8368 pairs. As JSON requires that keys must be of type string, rule 2 is the
8369 weakest constraint one can pose on initializer lists to interpret them
8370 as an object.
8371 3. In all other cases, the initializer list could not be interpreted as
8372 JSON object type, so interpreting it as JSON array type is safe.
8373
8374 With the rules described above, the following JSON values cannot be
8375 expressed by an initializer list:
8376
8377 - the empty array (`[]`): use @ref array(initializer_list_t)
8378 with an empty initializer list in this case
8379 - arrays whose elements satisfy rule 2: use @ref
8380 array(initializer_list_t) with the same initializer list
8381 in this case
8382
8383 @note When used without parentheses around an empty initializer list, @ref
8384 basic_json() is called instead of this function, yielding the JSON null
8385 value.
8386
8387 @param[in] init initializer list with JSON values
8388
8389 @param[in] type_deduction internal parameter; when set to `true`, the type
8390 of the JSON value is deducted from the initializer list @a init; when set
8391 to `false`, the type provided via @a manual_type is forced. This mode is
8392 used by the functions @ref array(initializer_list_t) and
8393 @ref object(initializer_list_t).
8394
8395 @param[in] manual_type internal parameter; when @a type_deduction is set
8396 to `false`, the created JSON value will use the provided type (only @ref
8397 value_t::array and @ref value_t::object are valid); when @a type_deduction
8398 is set to `true`, this parameter has no effect
8399
8400 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
8401 `value_t::object`, but @a init contains an element which is not a pair
8402 whose first element is a string. In this case, the constructor could not
8403 create an object. If @a type_deduction would have be `true`, an array
8404 would have been created. See @ref object(initializer_list_t)
8405 for an example.
8406
8407 @complexity Linear in the size of the initializer list @a init.
8408
8409 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8410 changes to any JSON value.
8411
8412 @liveexample{The example below shows how JSON values are created from
8413 initializer lists.,basic_json__list_init_t}
8414
8415 @sa @ref array(initializer_list_t) -- create a JSON array
8416 value from an initializer list
8417 @sa @ref object(initializer_list_t) -- create a JSON object
8418 value from an initializer list
8419
8420 @since version 1.0.0
8421 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)8422 basic_json(initializer_list_t init,
8423 bool type_deduction = true,
8424 value_t manual_type = value_t::array)
8425 {
8426 // check if each element is an array with two elements whose first
8427 // element is a string
8428 bool is_an_object = std::all_of(init.begin(), init.end(),
8429 [](const detail::json_ref<basic_json>& element_ref)
8430 {
8431 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
8432 });
8433
8434 // adjust type if type deduction is not wanted
8435 if (not type_deduction)
8436 {
8437 // if array is wanted, do not create an object though possible
8438 if (manual_type == value_t::array)
8439 {
8440 is_an_object = false;
8441 }
8442
8443 // if object is wanted but impossible, throw an exception
8444 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
8445 {
8446 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
8447 }
8448 }
8449
8450 if (is_an_object)
8451 {
8452 // the initializer list is a list of pairs -> create object
8453 m_type = value_t::object;
8454 m_value = value_t::object;
8455
8456 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
8457 {
8458 auto element = element_ref.moved_or_copied();
8459 m_value.object->emplace(
8460 std::move(*((*element.m_value.array)[0].m_value.string)),
8461 std::move((*element.m_value.array)[1]));
8462 });
8463 }
8464 else
8465 {
8466 // the initializer list describes an array -> create array
8467 m_type = value_t::array;
8468 m_value.array = create<array_t>(init.begin(), init.end());
8469 }
8470
8471 assert_invariant();
8472 }
8473
8474 /*!
8475 @brief explicitly create an array from an initializer list
8476
8477 Creates a JSON array value from a given initializer list. That is, given a
8478 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
8479 initializer list is empty, the empty array `[]` is created.
8480
8481 @note This function is only needed to express two edge cases that cannot
8482 be realized with the initializer list constructor (@ref
8483 basic_json(initializer_list_t, bool, value_t)). These cases
8484 are:
8485 1. creating an array whose elements are all pairs whose first element is a
8486 string -- in this case, the initializer list constructor would create an
8487 object, taking the first elements as keys
8488 2. creating an empty array -- passing the empty initializer list to the
8489 initializer list constructor yields an empty object
8490
8491 @param[in] init initializer list with JSON values to create an array from
8492 (optional)
8493
8494 @return JSON array value
8495
8496 @complexity Linear in the size of @a init.
8497
8498 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8499 changes to any JSON value.
8500
8501 @liveexample{The following code shows an example for the `array`
8502 function.,array}
8503
8504 @sa @ref basic_json(initializer_list_t, bool, value_t) --
8505 create a JSON value from an initializer list
8506 @sa @ref object(initializer_list_t) -- create a JSON object
8507 value from an initializer list
8508
8509 @since version 1.0.0
8510 */
array(initializer_list_t init={})8511 static basic_json array(initializer_list_t init = {})
8512 {
8513 return basic_json(init, false, value_t::array);
8514 }
8515
8516 /*!
8517 @brief explicitly create an object from an initializer list
8518
8519 Creates a JSON object value from a given initializer list. The initializer
8520 lists elements must be pairs, and their first elements must be strings. If
8521 the initializer list is empty, the empty object `{}` is created.
8522
8523 @note This function is only added for symmetry reasons. In contrast to the
8524 related function @ref array(initializer_list_t), there are
8525 no cases which can only be expressed by this function. That is, any
8526 initializer list @a init can also be passed to the initializer list
8527 constructor @ref basic_json(initializer_list_t, bool, value_t).
8528
8529 @param[in] init initializer list to create an object from (optional)
8530
8531 @return JSON object value
8532
8533 @throw type_error.301 if @a init is not a list of pairs whose first
8534 elements are strings. In this case, no object can be created. When such a
8535 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
8536 an array would have been created from the passed initializer list @a init.
8537 See example below.
8538
8539 @complexity Linear in the size of @a init.
8540
8541 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8542 changes to any JSON value.
8543
8544 @liveexample{The following code shows an example for the `object`
8545 function.,object}
8546
8547 @sa @ref basic_json(initializer_list_t, bool, value_t) --
8548 create a JSON value from an initializer list
8549 @sa @ref array(initializer_list_t) -- create a JSON array
8550 value from an initializer list
8551
8552 @since version 1.0.0
8553 */
object(initializer_list_t init={})8554 static basic_json object(initializer_list_t init = {})
8555 {
8556 return basic_json(init, false, value_t::object);
8557 }
8558
8559 /*!
8560 @brief construct an array with count copies of given value
8561
8562 Constructs a JSON array value by creating @a cnt copies of a passed value.
8563 In case @a cnt is `0`, an empty array is created.
8564
8565 @param[in] cnt the number of JSON copies of @a val to create
8566 @param[in] val the JSON value to copy
8567
8568 @post `std::distance(begin(),end()) == cnt` holds.
8569
8570 @complexity Linear in @a cnt.
8571
8572 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8573 changes to any JSON value.
8574
8575 @liveexample{The following code shows examples for the @ref
8576 basic_json(size_type\, const basic_json&)
8577 constructor.,basic_json__size_type_basic_json}
8578
8579 @since version 1.0.0
8580 */
basic_json(size_type cnt,const basic_json & val)8581 basic_json(size_type cnt, const basic_json& val)
8582 : m_type(value_t::array)
8583 {
8584 m_value.array = create<array_t>(cnt, val);
8585 assert_invariant();
8586 }
8587
8588 /*!
8589 @brief construct a JSON container given an iterator range
8590
8591 Constructs the JSON value with the contents of the range `[first, last)`.
8592 The semantics depends on the different types a JSON value can have:
8593 - In case of a null type, invalid_iterator.206 is thrown.
8594 - In case of other primitive types (number, boolean, or string), @a first
8595 must be `begin()` and @a last must be `end()`. In this case, the value is
8596 copied. Otherwise, invalid_iterator.204 is thrown.
8597 - In case of structured types (array, object), the constructor behaves as
8598 similar versions for `std::vector` or `std::map`; that is, a JSON array
8599 or object is constructed from the values in the range.
8600
8601 @tparam InputIT an input iterator type (@ref iterator or @ref
8602 const_iterator)
8603
8604 @param[in] first begin of the range to copy from (included)
8605 @param[in] last end of the range to copy from (excluded)
8606
8607 @pre Iterators @a first and @a last must be initialized. **This
8608 precondition is enforced with an assertion (see warning).** If
8609 assertions are switched off, a violation of this precondition yields
8610 undefined behavior.
8611
8612 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
8613 checked efficiently. Only certain edge cases are detected; see the
8614 description of the exceptions below. A violation of this precondition
8615 yields undefined behavior.
8616
8617 @warning A precondition is enforced with a runtime assertion that will
8618 result in calling `std::abort` if this precondition is not met.
8619 Assertions can be disabled by defining `NDEBUG` at compile time.
8620 See http://en.cppreference.com/w/cpp/error/assert for more
8621 information.
8622
8623 @throw invalid_iterator.201 if iterators @a first and @a last are not
8624 compatible (i.e., do not belong to the same JSON value). In this case,
8625 the range `[first, last)` is undefined.
8626 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
8627 primitive type (number, boolean, or string), but @a first does not point
8628 to the first element any more. In this case, the range `[first, last)` is
8629 undefined. See example code below.
8630 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
8631 null value. In this case, the range `[first, last)` is undefined.
8632
8633 @complexity Linear in distance between @a first and @a last.
8634
8635 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8636 changes to any JSON value.
8637
8638 @liveexample{The example below shows several ways to create JSON values by
8639 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
8640
8641 @since version 1.0.0
8642 */
8643 template<class InputIT, typename std::enable_if<
8644 std::is_same<InputIT, typename basic_json_t::iterator>::value or
8645 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)8646 basic_json(InputIT first, InputIT last)
8647 {
8648 assert(first.m_object != nullptr);
8649 assert(last.m_object != nullptr);
8650
8651 // make sure iterator fits the current value
8652 if (JSON_UNLIKELY(first.m_object != last.m_object))
8653 {
8654 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
8655 }
8656
8657 // copy type from first iterator
8658 m_type = first.m_object->m_type;
8659
8660 // check if iterator range is complete for primitive values
8661 switch (m_type)
8662 {
8663 case value_t::boolean:
8664 case value_t::number_float:
8665 case value_t::number_integer:
8666 case value_t::number_unsigned:
8667 case value_t::string:
8668 {
8669 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
8670 or not last.m_it.primitive_iterator.is_end()))
8671 {
8672 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
8673 }
8674 break;
8675 }
8676
8677 default:
8678 break;
8679 }
8680
8681 switch (m_type)
8682 {
8683 case value_t::number_integer:
8684 {
8685 m_value.number_integer = first.m_object->m_value.number_integer;
8686 break;
8687 }
8688
8689 case value_t::number_unsigned:
8690 {
8691 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
8692 break;
8693 }
8694
8695 case value_t::number_float:
8696 {
8697 m_value.number_float = first.m_object->m_value.number_float;
8698 break;
8699 }
8700
8701 case value_t::boolean:
8702 {
8703 m_value.boolean = first.m_object->m_value.boolean;
8704 break;
8705 }
8706
8707 case value_t::string:
8708 {
8709 m_value = *first.m_object->m_value.string;
8710 break;
8711 }
8712
8713 case value_t::object:
8714 {
8715 m_value.object = create<object_t>(first.m_it.object_iterator,
8716 last.m_it.object_iterator);
8717 break;
8718 }
8719
8720 case value_t::array:
8721 {
8722 m_value.array = create<array_t>(first.m_it.array_iterator,
8723 last.m_it.array_iterator);
8724 break;
8725 }
8726
8727 default:
8728 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
8729 std::string(first.m_object->type_name())));
8730 }
8731
8732 assert_invariant();
8733 }
8734
8735
8736 ///////////////////////////////////////
8737 // other constructors and destructor //
8738 ///////////////////////////////////////
8739
8740 /// @private
basic_json(const detail::json_ref<basic_json> & ref)8741 basic_json(const detail::json_ref<basic_json>& ref)
8742 : basic_json(ref.moved_or_copied())
8743 {}
8744
8745 /*!
8746 @brief copy constructor
8747
8748 Creates a copy of a given JSON value.
8749
8750 @param[in] other the JSON value to copy
8751
8752 @post `*this == other`
8753
8754 @complexity Linear in the size of @a other.
8755
8756 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8757 changes to any JSON value.
8758
8759 @requirement This function helps `basic_json` satisfying the
8760 [Container](http://en.cppreference.com/w/cpp/concept/Container)
8761 requirements:
8762 - The complexity is linear.
8763 - As postcondition, it holds: `other == basic_json(other)`.
8764
8765 @liveexample{The following code shows an example for the copy
8766 constructor.,basic_json__basic_json}
8767
8768 @since version 1.0.0
8769 */
basic_json(const basic_json & other)8770 basic_json(const basic_json& other)
8771 : m_type(other.m_type)
8772 {
8773 // check of passed value is valid
8774 other.assert_invariant();
8775
8776 switch (m_type)
8777 {
8778 case value_t::object:
8779 {
8780 m_value = *other.m_value.object;
8781 break;
8782 }
8783
8784 case value_t::array:
8785 {
8786 m_value = *other.m_value.array;
8787 break;
8788 }
8789
8790 case value_t::string:
8791 {
8792 m_value = *other.m_value.string;
8793 break;
8794 }
8795
8796 case value_t::boolean:
8797 {
8798 m_value = other.m_value.boolean;
8799 break;
8800 }
8801
8802 case value_t::number_integer:
8803 {
8804 m_value = other.m_value.number_integer;
8805 break;
8806 }
8807
8808 case value_t::number_unsigned:
8809 {
8810 m_value = other.m_value.number_unsigned;
8811 break;
8812 }
8813
8814 case value_t::number_float:
8815 {
8816 m_value = other.m_value.number_float;
8817 break;
8818 }
8819
8820 default:
8821 break;
8822 }
8823
8824 assert_invariant();
8825 }
8826
8827 /*!
8828 @brief move constructor
8829
8830 Move constructor. Constructs a JSON value with the contents of the given
8831 value @a other using move semantics. It "steals" the resources from @a
8832 other and leaves it as JSON null value.
8833
8834 @param[in,out] other value to move to this object
8835
8836 @post `*this` has the same value as @a other before the call.
8837 @post @a other is a JSON null value.
8838
8839 @complexity Constant.
8840
8841 @exceptionsafety No-throw guarantee: this constructor never throws
8842 exceptions.
8843
8844 @requirement This function helps `basic_json` satisfying the
8845 [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible)
8846 requirements.
8847
8848 @liveexample{The code below shows the move constructor explicitly called
8849 via std::move.,basic_json__moveconstructor}
8850
8851 @since version 1.0.0
8852 */
basic_json(basic_json && other)8853 basic_json(basic_json&& other) noexcept
8854 : m_type(std::move(other.m_type)),
8855 m_value(std::move(other.m_value))
8856 {
8857 // check that passed value is valid
8858 other.assert_invariant();
8859
8860 // invalidate payload
8861 other.m_type = value_t::null;
8862 other.m_value = {};
8863
8864 assert_invariant();
8865 }
8866
8867 /*!
8868 @brief copy assignment
8869
8870 Copy assignment operator. Copies a JSON value via the "copy and swap"
8871 strategy: It is expressed in terms of the copy constructor, destructor,
8872 and the `swap()` member function.
8873
8874 @param[in] other value to copy from
8875
8876 @complexity Linear.
8877
8878 @requirement This function helps `basic_json` satisfying the
8879 [Container](http://en.cppreference.com/w/cpp/concept/Container)
8880 requirements:
8881 - The complexity is linear.
8882
8883 @liveexample{The code below shows and example for the copy assignment. It
8884 creates a copy of value `a` which is then swapped with `b`. Finally\, the
8885 copy of `a` (which is the null value after the swap) is
8886 destroyed.,basic_json__copyassignment}
8887
8888 @since version 1.0.0
8889 */
operator =(basic_json other)8890 reference& operator=(basic_json other) noexcept (
8891 std::is_nothrow_move_constructible<value_t>::value and
8892 std::is_nothrow_move_assignable<value_t>::value and
8893 std::is_nothrow_move_constructible<json_value>::value and
8894 std::is_nothrow_move_assignable<json_value>::value
8895 )
8896 {
8897 // check that passed value is valid
8898 other.assert_invariant();
8899
8900 using std::swap;
8901 swap(m_type, other.m_type);
8902 swap(m_value, other.m_value);
8903
8904 assert_invariant();
8905 return *this;
8906 }
8907
8908 /*!
8909 @brief destructor
8910
8911 Destroys the JSON value and frees all allocated memory.
8912
8913 @complexity Linear.
8914
8915 @requirement This function helps `basic_json` satisfying the
8916 [Container](http://en.cppreference.com/w/cpp/concept/Container)
8917 requirements:
8918 - The complexity is linear.
8919 - All stored elements are destroyed and all memory is freed.
8920
8921 @since version 1.0.0
8922 */
~basic_json()8923 ~basic_json()
8924 {
8925 assert_invariant();
8926 m_value.destroy(m_type);
8927 }
8928
8929 /// @}
8930
8931 public:
8932 ///////////////////////
8933 // object inspection //
8934 ///////////////////////
8935
8936 /// @name object inspection
8937 /// Functions to inspect the type of a JSON value.
8938 /// @{
8939
8940 /*!
8941 @brief serialization
8942
8943 Serialization function for JSON values. The function tries to mimic
8944 Python's `json.dumps()` function, and currently supports its @a indent
8945 and @a ensure_ascii parameters.
8946
8947 @param[in] indent If indent is nonnegative, then array elements and object
8948 members will be pretty-printed with that indent level. An indent level of
8949 `0` will only insert newlines. `-1` (the default) selects the most compact
8950 representation.
8951 @param[in] indent_char The character to use for indentation if @a indent is
8952 greater than `0`. The default is ` ` (space).
8953 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
8954 in the output are escaped with \uXXXX sequences, and the result consists
8955 of ASCII characters only.
8956
8957 @return string containing the serialization of the JSON value
8958
8959 @complexity Linear.
8960
8961 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8962 changes in the JSON value.
8963
8964 @liveexample{The following example shows the effect of different @a indent\,
8965 @a indent_char\, and @a ensure_ascii parameters to the result of the
8966 serialization.,dump}
8967
8968 @see https://docs.python.org/2/library/json.html#json.dump
8969
8970 @since version 1.0.0; indentation character @a indent_char and option
8971 @a ensure_ascii added in version 3.0.0
8972 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false) const8973 string_t dump(const int indent = -1, const char indent_char = ' ',
8974 const bool ensure_ascii = false) const
8975 {
8976 string_t result;
8977 serializer s(detail::output_adapter<char>(result), indent_char);
8978
8979 if (indent >= 0)
8980 {
8981 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
8982 }
8983 else
8984 {
8985 s.dump(*this, false, ensure_ascii, 0);
8986 }
8987
8988 return result;
8989 }
8990
8991 /*!
8992 @brief return the type of the JSON value (explicit)
8993
8994 Return the type of the JSON value as a value from the @ref value_t
8995 enumeration.
8996
8997 @return the type of the JSON value
8998 Value type | return value
8999 ------------------------- | -------------------------
9000 null | value_t::null
9001 boolean | value_t::boolean
9002 string | value_t::string
9003 number (integer) | value_t::number_integer
9004 number (unsigned integer) | value_t::number_unsigned
9005 number (foating-point) | value_t::number_float
9006 object | value_t::object
9007 array | value_t::array
9008 discarded | value_t::discarded
9009
9010 @complexity Constant.
9011
9012 @exceptionsafety No-throw guarantee: this member function never throws
9013 exceptions.
9014
9015 @liveexample{The following code exemplifies `type()` for all JSON
9016 types.,type}
9017
9018 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
9019 @sa @ref type_name() -- return the type as string
9020
9021 @since version 1.0.0
9022 */
type() const9023 constexpr value_t type() const noexcept
9024 {
9025 return m_type;
9026 }
9027
9028 /*!
9029 @brief return whether type is primitive
9030
9031 This function returns true if and only if the JSON type is primitive
9032 (string, number, boolean, or null).
9033
9034 @return `true` if type is primitive (string, number, boolean, or null),
9035 `false` otherwise.
9036
9037 @complexity Constant.
9038
9039 @exceptionsafety No-throw guarantee: this member function never throws
9040 exceptions.
9041
9042 @liveexample{The following code exemplifies `is_primitive()` for all JSON
9043 types.,is_primitive}
9044
9045 @sa @ref is_structured() -- returns whether JSON value is structured
9046 @sa @ref is_null() -- returns whether JSON value is `null`
9047 @sa @ref is_string() -- returns whether JSON value is a string
9048 @sa @ref is_boolean() -- returns whether JSON value is a boolean
9049 @sa @ref is_number() -- returns whether JSON value is a number
9050
9051 @since version 1.0.0
9052 */
is_primitive() const9053 constexpr bool is_primitive() const noexcept
9054 {
9055 return is_null() or is_string() or is_boolean() or is_number();
9056 }
9057
9058 /*!
9059 @brief return whether type is structured
9060
9061 This function returns true if and only if the JSON type is structured
9062 (array or object).
9063
9064 @return `true` if type is structured (array or object), `false` otherwise.
9065
9066 @complexity Constant.
9067
9068 @exceptionsafety No-throw guarantee: this member function never throws
9069 exceptions.
9070
9071 @liveexample{The following code exemplifies `is_structured()` for all JSON
9072 types.,is_structured}
9073
9074 @sa @ref is_primitive() -- returns whether value is primitive
9075 @sa @ref is_array() -- returns whether value is an array
9076 @sa @ref is_object() -- returns whether value is an object
9077
9078 @since version 1.0.0
9079 */
is_structured() const9080 constexpr bool is_structured() const noexcept
9081 {
9082 return is_array() or is_object();
9083 }
9084
9085 /*!
9086 @brief return whether value is null
9087
9088 This function returns true if and only if the JSON value is null.
9089
9090 @return `true` if type is null, `false` otherwise.
9091
9092 @complexity Constant.
9093
9094 @exceptionsafety No-throw guarantee: this member function never throws
9095 exceptions.
9096
9097 @liveexample{The following code exemplifies `is_null()` for all JSON
9098 types.,is_null}
9099
9100 @since version 1.0.0
9101 */
is_null() const9102 constexpr bool is_null() const noexcept
9103 {
9104 return (m_type == value_t::null);
9105 }
9106
9107 /*!
9108 @brief return whether value is a boolean
9109
9110 This function returns true if and only if the JSON value is a boolean.
9111
9112 @return `true` if type is boolean, `false` otherwise.
9113
9114 @complexity Constant.
9115
9116 @exceptionsafety No-throw guarantee: this member function never throws
9117 exceptions.
9118
9119 @liveexample{The following code exemplifies `is_boolean()` for all JSON
9120 types.,is_boolean}
9121
9122 @since version 1.0.0
9123 */
is_boolean() const9124 constexpr bool is_boolean() const noexcept
9125 {
9126 return (m_type == value_t::boolean);
9127 }
9128
9129 /*!
9130 @brief return whether value is a number
9131
9132 This function returns true if and only if the JSON value is a number. This
9133 includes both integer (signed and unsigned) and floating-point values.
9134
9135 @return `true` if type is number (regardless whether integer, unsigned
9136 integer or floating-type), `false` otherwise.
9137
9138 @complexity Constant.
9139
9140 @exceptionsafety No-throw guarantee: this member function never throws
9141 exceptions.
9142
9143 @liveexample{The following code exemplifies `is_number()` for all JSON
9144 types.,is_number}
9145
9146 @sa @ref is_number_integer() -- check if value is an integer or unsigned
9147 integer number
9148 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
9149 number
9150 @sa @ref is_number_float() -- check if value is a floating-point number
9151
9152 @since version 1.0.0
9153 */
is_number() const9154 constexpr bool is_number() const noexcept
9155 {
9156 return is_number_integer() or is_number_float();
9157 }
9158
9159 /*!
9160 @brief return whether value is an integer number
9161
9162 This function returns true if and only if the JSON value is a signed or
9163 unsigned integer number. This excludes floating-point values.
9164
9165 @return `true` if type is an integer or unsigned integer number, `false`
9166 otherwise.
9167
9168 @complexity Constant.
9169
9170 @exceptionsafety No-throw guarantee: this member function never throws
9171 exceptions.
9172
9173 @liveexample{The following code exemplifies `is_number_integer()` for all
9174 JSON types.,is_number_integer}
9175
9176 @sa @ref is_number() -- check if value is a number
9177 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
9178 number
9179 @sa @ref is_number_float() -- check if value is a floating-point number
9180
9181 @since version 1.0.0
9182 */
is_number_integer() const9183 constexpr bool is_number_integer() const noexcept
9184 {
9185 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
9186 }
9187
9188 /*!
9189 @brief return whether value is an unsigned integer number
9190
9191 This function returns true if and only if the JSON value is an unsigned
9192 integer number. This excludes floating-point and signed integer values.
9193
9194 @return `true` if type is an unsigned integer number, `false` otherwise.
9195
9196 @complexity Constant.
9197
9198 @exceptionsafety No-throw guarantee: this member function never throws
9199 exceptions.
9200
9201 @liveexample{The following code exemplifies `is_number_unsigned()` for all
9202 JSON types.,is_number_unsigned}
9203
9204 @sa @ref is_number() -- check if value is a number
9205 @sa @ref is_number_integer() -- check if value is an integer or unsigned
9206 integer number
9207 @sa @ref is_number_float() -- check if value is a floating-point number
9208
9209 @since version 2.0.0
9210 */
is_number_unsigned() const9211 constexpr bool is_number_unsigned() const noexcept
9212 {
9213 return (m_type == value_t::number_unsigned);
9214 }
9215
9216 /*!
9217 @brief return whether value is a floating-point number
9218
9219 This function returns true if and only if the JSON value is a
9220 floating-point number. This excludes signed and unsigned integer values.
9221
9222 @return `true` if type is a floating-point number, `false` otherwise.
9223
9224 @complexity Constant.
9225
9226 @exceptionsafety No-throw guarantee: this member function never throws
9227 exceptions.
9228
9229 @liveexample{The following code exemplifies `is_number_float()` for all
9230 JSON types.,is_number_float}
9231
9232 @sa @ref is_number() -- check if value is number
9233 @sa @ref is_number_integer() -- check if value is an integer number
9234 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
9235 number
9236
9237 @since version 1.0.0
9238 */
is_number_float() const9239 constexpr bool is_number_float() const noexcept
9240 {
9241 return (m_type == value_t::number_float);
9242 }
9243
9244 /*!
9245 @brief return whether value is an object
9246
9247 This function returns true if and only if the JSON value is an object.
9248
9249 @return `true` if type is object, `false` otherwise.
9250
9251 @complexity Constant.
9252
9253 @exceptionsafety No-throw guarantee: this member function never throws
9254 exceptions.
9255
9256 @liveexample{The following code exemplifies `is_object()` for all JSON
9257 types.,is_object}
9258
9259 @since version 1.0.0
9260 */
is_object() const9261 constexpr bool is_object() const noexcept
9262 {
9263 return (m_type == value_t::object);
9264 }
9265
9266 /*!
9267 @brief return whether value is an array
9268
9269 This function returns true if and only if the JSON value is an array.
9270
9271 @return `true` if type is array, `false` otherwise.
9272
9273 @complexity Constant.
9274
9275 @exceptionsafety No-throw guarantee: this member function never throws
9276 exceptions.
9277
9278 @liveexample{The following code exemplifies `is_array()` for all JSON
9279 types.,is_array}
9280
9281 @since version 1.0.0
9282 */
is_array() const9283 constexpr bool is_array() const noexcept
9284 {
9285 return (m_type == value_t::array);
9286 }
9287
9288 /*!
9289 @brief return whether value is a string
9290
9291 This function returns true if and only if the JSON value is a string.
9292
9293 @return `true` if type is string, `false` otherwise.
9294
9295 @complexity Constant.
9296
9297 @exceptionsafety No-throw guarantee: this member function never throws
9298 exceptions.
9299
9300 @liveexample{The following code exemplifies `is_string()` for all JSON
9301 types.,is_string}
9302
9303 @since version 1.0.0
9304 */
is_string() const9305 constexpr bool is_string() const noexcept
9306 {
9307 return (m_type == value_t::string);
9308 }
9309
9310 /*!
9311 @brief return whether value is discarded
9312
9313 This function returns true if and only if the JSON value was discarded
9314 during parsing with a callback function (see @ref parser_callback_t).
9315
9316 @note This function will always be `false` for JSON values after parsing.
9317 That is, discarded values can only occur during parsing, but will be
9318 removed when inside a structured value or replaced by null in other cases.
9319
9320 @return `true` if type is discarded, `false` otherwise.
9321
9322 @complexity Constant.
9323
9324 @exceptionsafety No-throw guarantee: this member function never throws
9325 exceptions.
9326
9327 @liveexample{The following code exemplifies `is_discarded()` for all JSON
9328 types.,is_discarded}
9329
9330 @since version 1.0.0
9331 */
is_discarded() const9332 constexpr bool is_discarded() const noexcept
9333 {
9334 return (m_type == value_t::discarded);
9335 }
9336
9337 /*!
9338 @brief return the type of the JSON value (implicit)
9339
9340 Implicitly return the type of the JSON value as a value from the @ref
9341 value_t enumeration.
9342
9343 @return the type of the JSON value
9344
9345 @complexity Constant.
9346
9347 @exceptionsafety No-throw guarantee: this member function never throws
9348 exceptions.
9349
9350 @liveexample{The following code exemplifies the @ref value_t operator for
9351 all JSON types.,operator__value_t}
9352
9353 @sa @ref type() -- return the type of the JSON value (explicit)
9354 @sa @ref type_name() -- return the type as string
9355
9356 @since version 1.0.0
9357 */
operator value_t() const9358 constexpr operator value_t() const noexcept
9359 {
9360 return m_type;
9361 }
9362
9363 /// @}
9364
9365 private:
9366 //////////////////
9367 // value access //
9368 //////////////////
9369
9370 /// get a boolean (explicit)
get_impl(boolean_t *) const9371 boolean_t get_impl(boolean_t* /*unused*/) const
9372 {
9373 if (JSON_LIKELY(is_boolean()))
9374 {
9375 return m_value.boolean;
9376 }
9377
9378 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
9379 }
9380
9381 /// get a pointer to the value (object)
get_impl_ptr(object_t *)9382 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
9383 {
9384 return is_object() ? m_value.object : nullptr;
9385 }
9386
9387 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const9388 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
9389 {
9390 return is_object() ? m_value.object : nullptr;
9391 }
9392
9393 /// get a pointer to the value (array)
get_impl_ptr(array_t *)9394 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
9395 {
9396 return is_array() ? m_value.array : nullptr;
9397 }
9398
9399 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const9400 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
9401 {
9402 return is_array() ? m_value.array : nullptr;
9403 }
9404
9405 /// get a pointer to the value (string)
get_impl_ptr(string_t *)9406 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
9407 {
9408 return is_string() ? m_value.string : nullptr;
9409 }
9410
9411 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const9412 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
9413 {
9414 return is_string() ? m_value.string : nullptr;
9415 }
9416
9417 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)9418 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
9419 {
9420 return is_boolean() ? &m_value.boolean : nullptr;
9421 }
9422
9423 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const9424 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
9425 {
9426 return is_boolean() ? &m_value.boolean : nullptr;
9427 }
9428
9429 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)9430 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
9431 {
9432 return is_number_integer() ? &m_value.number_integer : nullptr;
9433 }
9434
9435 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const9436 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
9437 {
9438 return is_number_integer() ? &m_value.number_integer : nullptr;
9439 }
9440
9441 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)9442 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
9443 {
9444 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
9445 }
9446
9447 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const9448 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
9449 {
9450 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
9451 }
9452
9453 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)9454 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
9455 {
9456 return is_number_float() ? &m_value.number_float : nullptr;
9457 }
9458
9459 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const9460 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
9461 {
9462 return is_number_float() ? &m_value.number_float : nullptr;
9463 }
9464
9465 /*!
9466 @brief helper function to implement get_ref()
9467
9468 This function helps to implement get_ref() without code duplication for
9469 const and non-const overloads
9470
9471 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
9472
9473 @throw type_error.303 if ReferenceType does not match underlying value
9474 type of the current JSON
9475 */
9476 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)9477 static ReferenceType get_ref_impl(ThisType& obj)
9478 {
9479 // delegate the call to get_ptr<>()
9480 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
9481
9482 if (JSON_LIKELY(ptr != nullptr))
9483 {
9484 return *ptr;
9485 }
9486
9487 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
9488 }
9489
9490 public:
9491 /// @name value access
9492 /// Direct access to the stored value of a JSON value.
9493 /// @{
9494
9495 /*!
9496 @brief get special-case overload
9497
9498 This overloads avoids a lot of template boilerplate, it can be seen as the
9499 identity method
9500
9501 @tparam BasicJsonType == @ref basic_json
9502
9503 @return a copy of *this
9504
9505 @complexity Constant.
9506
9507 @since version 2.1.0
9508 */
9509 template <
9510 typename BasicJsonType,
9511 detail::enable_if_t<std::is_same<typename std::remove_const<BasicJsonType>::type,
9512 basic_json_t>::value,
9513 int> = 0 >
get() const9514 basic_json get() const
9515 {
9516 return *this;
9517 }
9518
9519 /*!
9520 @brief get a value (explicit)
9521
9522 Explicit type conversion between the JSON value and a compatible value
9523 which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
9524 and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
9525 The value is converted by calling the @ref json_serializer<ValueType>
9526 `from_json()` method.
9527
9528 The function is equivalent to executing
9529 @code {.cpp}
9530 ValueType ret;
9531 JSONSerializer<ValueType>::from_json(*this, ret);
9532 return ret;
9533 @endcode
9534
9535 This overloads is chosen if:
9536 - @a ValueType is not @ref basic_json,
9537 - @ref json_serializer<ValueType> has a `from_json()` method of the form
9538 `void from_json(const basic_json&, ValueType&)`, and
9539 - @ref json_serializer<ValueType> does not have a `from_json()` method of
9540 the form `ValueType from_json(const basic_json&)`
9541
9542 @tparam ValueTypeCV the provided value type
9543 @tparam ValueType the returned value type
9544
9545 @return copy of the JSON value, converted to @a ValueType
9546
9547 @throw what @ref json_serializer<ValueType> `from_json()` method throws
9548
9549 @liveexample{The example below shows several conversions from JSON values
9550 to other types. There a few things to note: (1) Floating-point numbers can
9551 be converted to integers\, (2) A JSON array can be converted to a standard
9552 `std::vector<short>`\, (3) A JSON object can be converted to C++
9553 associative containers such as `std::unordered_map<std::string\,
9554 json>`.,get__ValueType_const}
9555
9556 @since version 2.1.0
9557 */
9558 template <
9559 typename ValueTypeCV,
9560 typename ValueType = detail::uncvref_t<ValueTypeCV>,
9561 detail::enable_if_t <
9562 not std::is_same<basic_json_t, ValueType>::value and
9563 detail::has_from_json<basic_json_t, ValueType>::value and
9564 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9565 int > = 0 >
9566 ValueType get() const noexcept(noexcept(
9567 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
9568 {
9569 // we cannot static_assert on ValueTypeCV being non-const, because
9570 // there is support for get<const basic_json_t>(), which is why we
9571 // still need the uncvref
9572 static_assert(not std::is_reference<ValueTypeCV>::value,
9573 "get() cannot be used with reference types, you might want to use get_ref()");
9574 static_assert(std::is_default_constructible<ValueType>::value,
9575 "types must be DefaultConstructible when used with get()");
9576
9577 ValueType ret;
9578 JSONSerializer<ValueType>::from_json(*this, ret);
9579 return ret;
9580 }
9581
9582 /*!
9583 @brief get a value (explicit); special case
9584
9585 Explicit type conversion between the JSON value and a compatible value
9586 which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
9587 and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
9588 The value is converted by calling the @ref json_serializer<ValueType>
9589 `from_json()` method.
9590
9591 The function is equivalent to executing
9592 @code {.cpp}
9593 return JSONSerializer<ValueTypeCV>::from_json(*this);
9594 @endcode
9595
9596 This overloads is chosen if:
9597 - @a ValueType is not @ref basic_json and
9598 - @ref json_serializer<ValueType> has a `from_json()` method of the form
9599 `ValueType from_json(const basic_json&)`
9600
9601 @note If @ref json_serializer<ValueType> has both overloads of
9602 `from_json()`, this one is chosen.
9603
9604 @tparam ValueTypeCV the provided value type
9605 @tparam ValueType the returned value type
9606
9607 @return copy of the JSON value, converted to @a ValueType
9608
9609 @throw what @ref json_serializer<ValueType> `from_json()` method throws
9610
9611 @since version 2.1.0
9612 */
9613 template <
9614 typename ValueTypeCV,
9615 typename ValueType = detail::uncvref_t<ValueTypeCV>,
9616 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
9617 detail::has_non_default_from_json<basic_json_t,
9618 ValueType>::value, int> = 0 >
9619 ValueType get() const noexcept(noexcept(
9620 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
9621 {
9622 static_assert(not std::is_reference<ValueTypeCV>::value,
9623 "get() cannot be used with reference types, you might want to use get_ref()");
9624 return JSONSerializer<ValueTypeCV>::from_json(*this);
9625 }
9626
9627 /*!
9628 @brief get a pointer value (explicit)
9629
9630 Explicit pointer access to the internally stored JSON value. No copies are
9631 made.
9632
9633 @warning The pointer becomes invalid if the underlying JSON object
9634 changes.
9635
9636 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
9637 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
9638 @ref number_unsigned_t, or @ref number_float_t.
9639
9640 @return pointer to the internally stored JSON value if the requested
9641 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
9642
9643 @complexity Constant.
9644
9645 @liveexample{The example below shows how pointers to internal values of a
9646 JSON value can be requested. Note that no type conversions are made and a
9647 `nullptr` is returned if the value and the requested pointer type does not
9648 match.,get__PointerType}
9649
9650 @sa @ref get_ptr() for explicit pointer-member access
9651
9652 @since version 1.0.0
9653 */
9654 template<typename PointerType, typename std::enable_if<
9655 std::is_pointer<PointerType>::value, int>::type = 0>
9656 PointerType get() noexcept
9657 {
9658 // delegate the call to get_ptr
9659 return get_ptr<PointerType>();
9660 }
9661
9662 /*!
9663 @brief get a pointer value (explicit)
9664 @copydoc get()
9665 */
9666 template<typename PointerType, typename std::enable_if<
9667 std::is_pointer<PointerType>::value, int>::type = 0>
get() const9668 constexpr const PointerType get() const noexcept
9669 {
9670 // delegate the call to get_ptr
9671 return get_ptr<PointerType>();
9672 }
9673
9674 /*!
9675 @brief get a pointer value (implicit)
9676
9677 Implicit pointer access to the internally stored JSON value. No copies are
9678 made.
9679
9680 @warning Writing data to the pointee of the result yields an undefined
9681 state.
9682
9683 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
9684 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
9685 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
9686 assertion.
9687
9688 @return pointer to the internally stored JSON value if the requested
9689 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
9690
9691 @complexity Constant.
9692
9693 @liveexample{The example below shows how pointers to internal values of a
9694 JSON value can be requested. Note that no type conversions are made and a
9695 `nullptr` is returned if the value and the requested pointer type does not
9696 match.,get_ptr}
9697
9698 @since version 1.0.0
9699 */
9700 template<typename PointerType, typename std::enable_if<
9701 std::is_pointer<PointerType>::value, int>::type = 0>
9702 PointerType get_ptr() noexcept
9703 {
9704 // get the type of the PointerType (remove pointer and const)
9705 using pointee_t = typename std::remove_const<typename
9706 std::remove_pointer<typename
9707 std::remove_const<PointerType>::type>::type>::type;
9708 // make sure the type matches the allowed types
9709 static_assert(
9710 std::is_same<object_t, pointee_t>::value
9711 or std::is_same<array_t, pointee_t>::value
9712 or std::is_same<string_t, pointee_t>::value
9713 or std::is_same<boolean_t, pointee_t>::value
9714 or std::is_same<number_integer_t, pointee_t>::value
9715 or std::is_same<number_unsigned_t, pointee_t>::value
9716 or std::is_same<number_float_t, pointee_t>::value
9717 , "incompatible pointer type");
9718
9719 // delegate the call to get_impl_ptr<>()
9720 return get_impl_ptr(static_cast<PointerType>(nullptr));
9721 }
9722
9723 /*!
9724 @brief get a pointer value (implicit)
9725 @copydoc get_ptr()
9726 */
9727 template<typename PointerType, typename std::enable_if<
9728 std::is_pointer<PointerType>::value and
9729 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const9730 constexpr const PointerType get_ptr() const noexcept
9731 {
9732 // get the type of the PointerType (remove pointer and const)
9733 using pointee_t = typename std::remove_const<typename
9734 std::remove_pointer<typename
9735 std::remove_const<PointerType>::type>::type>::type;
9736 // make sure the type matches the allowed types
9737 static_assert(
9738 std::is_same<object_t, pointee_t>::value
9739 or std::is_same<array_t, pointee_t>::value
9740 or std::is_same<string_t, pointee_t>::value
9741 or std::is_same<boolean_t, pointee_t>::value
9742 or std::is_same<number_integer_t, pointee_t>::value
9743 or std::is_same<number_unsigned_t, pointee_t>::value
9744 or std::is_same<number_float_t, pointee_t>::value
9745 , "incompatible pointer type");
9746
9747 // delegate the call to get_impl_ptr<>() const
9748 return get_impl_ptr(static_cast<PointerType>(nullptr));
9749 }
9750
9751 /*!
9752 @brief get a reference value (implicit)
9753
9754 Implicit reference access to the internally stored JSON value. No copies
9755 are made.
9756
9757 @warning Writing data to the referee of the result yields an undefined
9758 state.
9759
9760 @tparam ReferenceType reference type; must be a reference to @ref array_t,
9761 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
9762 @ref number_float_t. Enforced by static assertion.
9763
9764 @return reference to the internally stored JSON value if the requested
9765 reference type @a ReferenceType fits to the JSON value; throws
9766 type_error.303 otherwise
9767
9768 @throw type_error.303 in case passed type @a ReferenceType is incompatible
9769 with the stored JSON value; see example below
9770
9771 @complexity Constant.
9772
9773 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
9774
9775 @since version 1.1.0
9776 */
9777 template<typename ReferenceType, typename std::enable_if<
9778 std::is_reference<ReferenceType>::value, int>::type = 0>
9779 ReferenceType get_ref()
9780 {
9781 // delegate call to get_ref_impl
9782 return get_ref_impl<ReferenceType>(*this);
9783 }
9784
9785 /*!
9786 @brief get a reference value (implicit)
9787 @copydoc get_ref()
9788 */
9789 template<typename ReferenceType, typename std::enable_if<
9790 std::is_reference<ReferenceType>::value and
9791 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
9792 ReferenceType get_ref() const
9793 {
9794 // delegate call to get_ref_impl
9795 return get_ref_impl<ReferenceType>(*this);
9796 }
9797
9798 /*!
9799 @brief get a value (implicit)
9800
9801 Implicit type conversion between the JSON value and a compatible value.
9802 The call is realized by calling @ref get() const.
9803
9804 @tparam ValueType non-pointer type compatible to the JSON value, for
9805 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
9806 `std::vector` types for JSON arrays. The character type of @ref string_t
9807 as well as an initializer list of this type is excluded to avoid
9808 ambiguities as these types implicitly convert to `std::string`.
9809
9810 @return copy of the JSON value, converted to type @a ValueType
9811
9812 @throw type_error.302 in case passed type @a ValueType is incompatible
9813 to the JSON value type (e.g., the JSON value is of type boolean, but a
9814 string is requested); see example below
9815
9816 @complexity Linear in the size of the JSON value.
9817
9818 @liveexample{The example below shows several conversions from JSON values
9819 to other types. There a few things to note: (1) Floating-point numbers can
9820 be converted to integers\, (2) A JSON array can be converted to a standard
9821 `std::vector<short>`\, (3) A JSON object can be converted to C++
9822 associative containers such as `std::unordered_map<std::string\,
9823 json>`.,operator__ValueType}
9824
9825 @since version 1.0.0
9826 */
9827 template < typename ValueType, typename std::enable_if <
9828 not std::is_pointer<ValueType>::value and
9829 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
9830 not std::is_same<ValueType, typename string_t::value_type>::value
9831 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
9832 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
9833 #endif
9834 #if defined(JSON_HAS_CPP_17)
9835 and not std::is_same<ValueType, typename std::string_view>::value
9836 #endif
9837 , int >::type = 0 >
operator ValueType() const9838 operator ValueType() const
9839 {
9840 // delegate the call to get<>() const
9841 return get<ValueType>();
9842 }
9843
9844 /// @}
9845
9846
9847 ////////////////////
9848 // element access //
9849 ////////////////////
9850
9851 /// @name element access
9852 /// Access to the JSON value.
9853 /// @{
9854
9855 /*!
9856 @brief access specified array element with bounds checking
9857
9858 Returns a reference to the element at specified location @a idx, with
9859 bounds checking.
9860
9861 @param[in] idx index of the element to access
9862
9863 @return reference to the element at index @a idx
9864
9865 @throw type_error.304 if the JSON value is not an array; in this case,
9866 calling `at` with an index makes no sense. See example below.
9867 @throw out_of_range.401 if the index @a idx is out of range of the array;
9868 that is, `idx >= size()`. See example below.
9869
9870 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9871 changes in the JSON value.
9872
9873 @complexity Constant.
9874
9875 @since version 1.0.0
9876
9877 @liveexample{The example below shows how array elements can be read and
9878 written using `at()`. It also demonstrates the different exceptions that
9879 can be thrown.,at__size_type}
9880 */
at(size_type idx)9881 reference at(size_type idx)
9882 {
9883 // at only works for arrays
9884 if (JSON_LIKELY(is_array()))
9885 {
9886 JSON_TRY
9887 {
9888 return m_value.array->at(idx);
9889 }
9890 JSON_CATCH (std::out_of_range&)
9891 {
9892 // create better exception explanation
9893 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
9894 }
9895 }
9896 else
9897 {
9898 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9899 }
9900 }
9901
9902 /*!
9903 @brief access specified array element with bounds checking
9904
9905 Returns a const reference to the element at specified location @a idx,
9906 with bounds checking.
9907
9908 @param[in] idx index of the element to access
9909
9910 @return const reference to the element at index @a idx
9911
9912 @throw type_error.304 if the JSON value is not an array; in this case,
9913 calling `at` with an index makes no sense. See example below.
9914 @throw out_of_range.401 if the index @a idx is out of range of the array;
9915 that is, `idx >= size()`. See example below.
9916
9917 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9918 changes in the JSON value.
9919
9920 @complexity Constant.
9921
9922 @since version 1.0.0
9923
9924 @liveexample{The example below shows how array elements can be read using
9925 `at()`. It also demonstrates the different exceptions that can be thrown.,
9926 at__size_type_const}
9927 */
at(size_type idx) const9928 const_reference at(size_type idx) const
9929 {
9930 // at only works for arrays
9931 if (JSON_LIKELY(is_array()))
9932 {
9933 JSON_TRY
9934 {
9935 return m_value.array->at(idx);
9936 }
9937 JSON_CATCH (std::out_of_range&)
9938 {
9939 // create better exception explanation
9940 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
9941 }
9942 }
9943 else
9944 {
9945 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9946 }
9947 }
9948
9949 /*!
9950 @brief access specified object element with bounds checking
9951
9952 Returns a reference to the element at with specified key @a key, with
9953 bounds checking.
9954
9955 @param[in] key key of the element to access
9956
9957 @return reference to the element at key @a key
9958
9959 @throw type_error.304 if the JSON value is not an object; in this case,
9960 calling `at` with a key makes no sense. See example below.
9961 @throw out_of_range.403 if the key @a key is is not stored in the object;
9962 that is, `find(key) == end()`. See example below.
9963
9964 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9965 changes in the JSON value.
9966
9967 @complexity Logarithmic in the size of the container.
9968
9969 @sa @ref operator[](const typename object_t::key_type&) for unchecked
9970 access by reference
9971 @sa @ref value() for access by value with a default value
9972
9973 @since version 1.0.0
9974
9975 @liveexample{The example below shows how object elements can be read and
9976 written using `at()`. It also demonstrates the different exceptions that
9977 can be thrown.,at__object_t_key_type}
9978 */
at(const typename object_t::key_type & key)9979 reference at(const typename object_t::key_type& key)
9980 {
9981 // at only works for objects
9982 if (JSON_LIKELY(is_object()))
9983 {
9984 JSON_TRY
9985 {
9986 return m_value.object->at(key);
9987 }
9988 JSON_CATCH (std::out_of_range&)
9989 {
9990 // create better exception explanation
9991 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
9992 }
9993 }
9994 else
9995 {
9996 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9997 }
9998 }
9999
10000 /*!
10001 @brief access specified object element with bounds checking
10002
10003 Returns a const reference to the element at with specified key @a key,
10004 with bounds checking.
10005
10006 @param[in] key key of the element to access
10007
10008 @return const reference to the element at key @a key
10009
10010 @throw type_error.304 if the JSON value is not an object; in this case,
10011 calling `at` with a key makes no sense. See example below.
10012 @throw out_of_range.403 if the key @a key is is not stored in the object;
10013 that is, `find(key) == end()`. See example below.
10014
10015 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
10016 changes in the JSON value.
10017
10018 @complexity Logarithmic in the size of the container.
10019
10020 @sa @ref operator[](const typename object_t::key_type&) for unchecked
10021 access by reference
10022 @sa @ref value() for access by value with a default value
10023
10024 @since version 1.0.0
10025
10026 @liveexample{The example below shows how object elements can be read using
10027 `at()`. It also demonstrates the different exceptions that can be thrown.,
10028 at__object_t_key_type_const}
10029 */
at(const typename object_t::key_type & key) const10030 const_reference at(const typename object_t::key_type& key) const
10031 {
10032 // at only works for objects
10033 if (JSON_LIKELY(is_object()))
10034 {
10035 JSON_TRY
10036 {
10037 return m_value.object->at(key);
10038 }
10039 JSON_CATCH (std::out_of_range&)
10040 {
10041 // create better exception explanation
10042 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
10043 }
10044 }
10045 else
10046 {
10047 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
10048 }
10049 }
10050
10051 /*!
10052 @brief access specified array element
10053
10054 Returns a reference to the element at specified location @a idx.
10055
10056 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
10057 then the array is silently filled up with `null` values to make `idx` a
10058 valid reference to the last stored element.
10059
10060 @param[in] idx index of the element to access
10061
10062 @return reference to the element at index @a idx
10063
10064 @throw type_error.305 if the JSON value is not an array or null; in that
10065 cases, using the [] operator with an index makes no sense.
10066
10067 @complexity Constant if @a idx is in the range of the array. Otherwise
10068 linear in `idx - size()`.
10069
10070 @liveexample{The example below shows how array elements can be read and
10071 written using `[]` operator. Note the addition of `null`
10072 values.,operatorarray__size_type}
10073
10074 @since version 1.0.0
10075 */
operator [](size_type idx)10076 reference operator[](size_type idx)
10077 {
10078 // implicitly convert null value to an empty array
10079 if (is_null())
10080 {
10081 m_type = value_t::array;
10082 m_value.array = create<array_t>();
10083 assert_invariant();
10084 }
10085
10086 // operator[] only works for arrays
10087 if (JSON_LIKELY(is_array()))
10088 {
10089 // fill up array with null values if given idx is outside range
10090 if (idx >= m_value.array->size())
10091 {
10092 m_value.array->insert(m_value.array->end(),
10093 idx - m_value.array->size() + 1,
10094 basic_json());
10095 }
10096
10097 return m_value.array->operator[](idx);
10098 }
10099
10100 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
10101 }
10102
10103 /*!
10104 @brief access specified array element
10105
10106 Returns a const reference to the element at specified location @a idx.
10107
10108 @param[in] idx index of the element to access
10109
10110 @return const reference to the element at index @a idx
10111
10112 @throw type_error.305 if the JSON value is not an array; in that cases,
10113 using the [] operator with an index makes no sense.
10114
10115 @complexity Constant.
10116
10117 @liveexample{The example below shows how array elements can be read using
10118 the `[]` operator.,operatorarray__size_type_const}
10119
10120 @since version 1.0.0
10121 */
operator [](size_type idx) const10122 const_reference operator[](size_type idx) const
10123 {
10124 // const operator[] only works for arrays
10125 if (JSON_LIKELY(is_array()))
10126 {
10127 return m_value.array->operator[](idx);
10128 }
10129
10130 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
10131 }
10132
10133 /*!
10134 @brief access specified object element
10135
10136 Returns a reference to the element at with specified key @a key.
10137
10138 @note If @a key is not found in the object, then it is silently added to
10139 the object and filled with a `null` value to make `key` a valid reference.
10140 In case the value was `null` before, it is converted to an object.
10141
10142 @param[in] key key of the element to access
10143
10144 @return reference to the element at key @a key
10145
10146 @throw type_error.305 if the JSON value is not an object or null; in that
10147 cases, using the [] operator with a key makes no sense.
10148
10149 @complexity Logarithmic in the size of the container.
10150
10151 @liveexample{The example below shows how object elements can be read and
10152 written using the `[]` operator.,operatorarray__key_type}
10153
10154 @sa @ref at(const typename object_t::key_type&) for access by reference
10155 with range checking
10156 @sa @ref value() for access by value with a default value
10157
10158 @since version 1.0.0
10159 */
operator [](const typename object_t::key_type & key)10160 reference operator[](const typename object_t::key_type& key)
10161 {
10162 // implicitly convert null value to an empty object
10163 if (is_null())
10164 {
10165 m_type = value_t::object;
10166 m_value.object = create<object_t>();
10167 assert_invariant();
10168 }
10169
10170 // operator[] only works for objects
10171 if (JSON_LIKELY(is_object()))
10172 {
10173 return m_value.object->operator[](key);
10174 }
10175
10176 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
10177 }
10178
10179 /*!
10180 @brief read-only access specified object element
10181
10182 Returns a const reference to the element at with specified key @a key. No
10183 bounds checking is performed.
10184
10185 @warning If the element with key @a key does not exist, the behavior is
10186 undefined.
10187
10188 @param[in] key key of the element to access
10189
10190 @return const reference to the element at key @a key
10191
10192 @pre The element with key @a key must exist. **This precondition is
10193 enforced with an assertion.**
10194
10195 @throw type_error.305 if the JSON value is not an object; in that cases,
10196 using the [] operator with a key makes no sense.
10197
10198 @complexity Logarithmic in the size of the container.
10199
10200 @liveexample{The example below shows how object elements can be read using
10201 the `[]` operator.,operatorarray__key_type_const}
10202
10203 @sa @ref at(const typename object_t::key_type&) for access by reference
10204 with range checking
10205 @sa @ref value() for access by value with a default value
10206
10207 @since version 1.0.0
10208 */
operator [](const typename object_t::key_type & key) const10209 const_reference operator[](const typename object_t::key_type& key) const
10210 {
10211 // const operator[] only works for objects
10212 if (JSON_LIKELY(is_object()))
10213 {
10214 assert(m_value.object->find(key) != m_value.object->end());
10215 return m_value.object->find(key)->second;
10216 }
10217
10218 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
10219 }
10220
10221 /*!
10222 @brief access specified object element
10223
10224 Returns a reference to the element at with specified key @a key.
10225
10226 @note If @a key is not found in the object, then it is silently added to
10227 the object and filled with a `null` value to make `key` a valid reference.
10228 In case the value was `null` before, it is converted to an object.
10229
10230 @param[in] key key of the element to access
10231
10232 @return reference to the element at key @a key
10233
10234 @throw type_error.305 if the JSON value is not an object or null; in that
10235 cases, using the [] operator with a key makes no sense.
10236
10237 @complexity Logarithmic in the size of the container.
10238
10239 @liveexample{The example below shows how object elements can be read and
10240 written using the `[]` operator.,operatorarray__key_type}
10241
10242 @sa @ref at(const typename object_t::key_type&) for access by reference
10243 with range checking
10244 @sa @ref value() for access by value with a default value
10245
10246 @since version 1.1.0
10247 */
10248 template<typename T>
operator [](T * key)10249 reference operator[](T* key)
10250 {
10251 // implicitly convert null to object
10252 if (is_null())
10253 {
10254 m_type = value_t::object;
10255 m_value = value_t::object;
10256 assert_invariant();
10257 }
10258
10259 // at only works for objects
10260 if (JSON_LIKELY(is_object()))
10261 {
10262 return m_value.object->operator[](key);
10263 }
10264
10265 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
10266 }
10267
10268 /*!
10269 @brief read-only access specified object element
10270
10271 Returns a const reference to the element at with specified key @a key. No
10272 bounds checking is performed.
10273
10274 @warning If the element with key @a key does not exist, the behavior is
10275 undefined.
10276
10277 @param[in] key key of the element to access
10278
10279 @return const reference to the element at key @a key
10280
10281 @pre The element with key @a key must exist. **This precondition is
10282 enforced with an assertion.**
10283
10284 @throw type_error.305 if the JSON value is not an object; in that cases,
10285 using the [] operator with a key makes no sense.
10286
10287 @complexity Logarithmic in the size of the container.
10288
10289 @liveexample{The example below shows how object elements can be read using
10290 the `[]` operator.,operatorarray__key_type_const}
10291
10292 @sa @ref at(const typename object_t::key_type&) for access by reference
10293 with range checking
10294 @sa @ref value() for access by value with a default value
10295
10296 @since version 1.1.0
10297 */
10298 template<typename T>
operator [](T * key) const10299 const_reference operator[](T* key) const
10300 {
10301 // at only works for objects
10302 if (JSON_LIKELY(is_object()))
10303 {
10304 assert(m_value.object->find(key) != m_value.object->end());
10305 return m_value.object->find(key)->second;
10306 }
10307
10308 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
10309 }
10310
10311 /*!
10312 @brief access specified object element with default value
10313
10314 Returns either a copy of an object's element at the specified key @a key
10315 or a given default value if no element with key @a key exists.
10316
10317 The function is basically equivalent to executing
10318 @code {.cpp}
10319 try {
10320 return at(key);
10321 } catch(out_of_range) {
10322 return default_value;
10323 }
10324 @endcode
10325
10326 @note Unlike @ref at(const typename object_t::key_type&), this function
10327 does not throw if the given key @a key was not found.
10328
10329 @note Unlike @ref operator[](const typename object_t::key_type& key), this
10330 function does not implicitly add an element to the position defined by @a
10331 key. This function is furthermore also applicable to const objects.
10332
10333 @param[in] key key of the element to access
10334 @param[in] default_value the value to return if @a key is not found
10335
10336 @tparam ValueType type compatible to JSON values, for instance `int` for
10337 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
10338 JSON arrays. Note the type of the expected value at @a key and the default
10339 value @a default_value must be compatible.
10340
10341 @return copy of the element at key @a key or @a default_value if @a key
10342 is not found
10343
10344 @throw type_error.306 if the JSON value is not an objec; in that cases,
10345 using `value()` with a key makes no sense.
10346
10347 @complexity Logarithmic in the size of the container.
10348
10349 @liveexample{The example below shows how object elements can be queried
10350 with a default value.,basic_json__value}
10351
10352 @sa @ref at(const typename object_t::key_type&) for access by reference
10353 with range checking
10354 @sa @ref operator[](const typename object_t::key_type&) for unchecked
10355 access by reference
10356
10357 @since version 1.0.0
10358 */
10359 template<class ValueType, typename std::enable_if<
10360 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
10361 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
10362 {
10363 // at only works for objects
10364 if (JSON_LIKELY(is_object()))
10365 {
10366 // if key is found, return value and given default value otherwise
10367 const auto it = find(key);
10368 if (it != end())
10369 {
10370 return *it;
10371 }
10372
10373 return default_value;
10374 }
10375
10376 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
10377 }
10378
10379 /*!
10380 @brief overload for a default value of type const char*
10381 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
10382 */
value(const typename object_t::key_type & key,const char * default_value) const10383 string_t value(const typename object_t::key_type& key, const char* default_value) const
10384 {
10385 return value(key, string_t(default_value));
10386 }
10387
10388 /*!
10389 @brief access specified object element via JSON Pointer with default value
10390
10391 Returns either a copy of an object's element at the specified key @a key
10392 or a given default value if no element with key @a key exists.
10393
10394 The function is basically equivalent to executing
10395 @code {.cpp}
10396 try {
10397 return at(ptr);
10398 } catch(out_of_range) {
10399 return default_value;
10400 }
10401 @endcode
10402
10403 @note Unlike @ref at(const json_pointer&), this function does not throw
10404 if the given key @a key was not found.
10405
10406 @param[in] ptr a JSON pointer to the element to access
10407 @param[in] default_value the value to return if @a ptr found no value
10408
10409 @tparam ValueType type compatible to JSON values, for instance `int` for
10410 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
10411 JSON arrays. Note the type of the expected value at @a key and the default
10412 value @a default_value must be compatible.
10413
10414 @return copy of the element at key @a key or @a default_value if @a key
10415 is not found
10416
10417 @throw type_error.306 if the JSON value is not an objec; in that cases,
10418 using `value()` with a key makes no sense.
10419
10420 @complexity Logarithmic in the size of the container.
10421
10422 @liveexample{The example below shows how object elements can be queried
10423 with a default value.,basic_json__value_ptr}
10424
10425 @sa @ref operator[](const json_pointer&) for unchecked access by reference
10426
10427 @since version 2.0.2
10428 */
10429 template<class ValueType, typename std::enable_if<
10430 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
10431 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
10432 {
10433 // at only works for objects
10434 if (JSON_LIKELY(is_object()))
10435 {
10436 // if pointer resolves a value, return it or use default value
10437 JSON_TRY
10438 {
10439 return ptr.get_checked(this);
10440 }
10441 JSON_CATCH (out_of_range&)
10442 {
10443 return default_value;
10444 }
10445 }
10446
10447 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
10448 }
10449
10450 /*!
10451 @brief overload for a default value of type const char*
10452 @copydoc basic_json::value(const json_pointer&, ValueType) const
10453 */
value(const json_pointer & ptr,const char * default_value) const10454 string_t value(const json_pointer& ptr, const char* default_value) const
10455 {
10456 return value(ptr, string_t(default_value));
10457 }
10458
10459 /*!
10460 @brief access the first element
10461
10462 Returns a reference to the first element in the container. For a JSON
10463 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
10464
10465 @return In case of a structured type (array or object), a reference to the
10466 first element is returned. In case of number, string, or boolean values, a
10467 reference to the value is returned.
10468
10469 @complexity Constant.
10470
10471 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
10472 or an empty array or object (undefined behavior, **guarded by
10473 assertions**).
10474 @post The JSON value remains unchanged.
10475
10476 @throw invalid_iterator.214 when called on `null` value
10477
10478 @liveexample{The following code shows an example for `front()`.,front}
10479
10480 @sa @ref back() -- access the last element
10481
10482 @since version 1.0.0
10483 */
front()10484 reference front()
10485 {
10486 return *begin();
10487 }
10488
10489 /*!
10490 @copydoc basic_json::front()
10491 */
front() const10492 const_reference front() const
10493 {
10494 return *cbegin();
10495 }
10496
10497 /*!
10498 @brief access the last element
10499
10500 Returns a reference to the last element in the container. For a JSON
10501 container `c`, the expression `c.back()` is equivalent to
10502 @code {.cpp}
10503 auto tmp = c.end();
10504 --tmp;
10505 return *tmp;
10506 @endcode
10507
10508 @return In case of a structured type (array or object), a reference to the
10509 last element is returned. In case of number, string, or boolean values, a
10510 reference to the value is returned.
10511
10512 @complexity Constant.
10513
10514 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
10515 or an empty array or object (undefined behavior, **guarded by
10516 assertions**).
10517 @post The JSON value remains unchanged.
10518
10519 @throw invalid_iterator.214 when called on a `null` value. See example
10520 below.
10521
10522 @liveexample{The following code shows an example for `back()`.,back}
10523
10524 @sa @ref front() -- access the first element
10525
10526 @since version 1.0.0
10527 */
back()10528 reference back()
10529 {
10530 auto tmp = end();
10531 --tmp;
10532 return *tmp;
10533 }
10534
10535 /*!
10536 @copydoc basic_json::back()
10537 */
back() const10538 const_reference back() const
10539 {
10540 auto tmp = cend();
10541 --tmp;
10542 return *tmp;
10543 }
10544
10545 /*!
10546 @brief remove element given an iterator
10547
10548 Removes the element specified by iterator @a pos. The iterator @a pos must
10549 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
10550 but is not dereferenceable) cannot be used as a value for @a pos.
10551
10552 If called on a primitive type other than `null`, the resulting JSON value
10553 will be `null`.
10554
10555 @param[in] pos iterator to the element to remove
10556 @return Iterator following the last removed element. If the iterator @a
10557 pos refers to the last element, the `end()` iterator is returned.
10558
10559 @tparam IteratorType an @ref iterator or @ref const_iterator
10560
10561 @post Invalidates iterators and references at or after the point of the
10562 erase, including the `end()` iterator.
10563
10564 @throw type_error.307 if called on a `null` value; example: `"cannot use
10565 erase() with null"`
10566 @throw invalid_iterator.202 if called on an iterator which does not belong
10567 to the current JSON value; example: `"iterator does not fit current
10568 value"`
10569 @throw invalid_iterator.205 if called on a primitive type with invalid
10570 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
10571 out of range"`
10572
10573 @complexity The complexity depends on the type:
10574 - objects: amortized constant
10575 - arrays: linear in distance between @a pos and the end of the container
10576 - strings: linear in the length of the string
10577 - other types: constant
10578
10579 @liveexample{The example shows the result of `erase()` for different JSON
10580 types.,erase__IteratorType}
10581
10582 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10583 the given range
10584 @sa @ref erase(const typename object_t::key_type&) -- removes the element
10585 from an object at the given key
10586 @sa @ref erase(const size_type) -- removes the element from an array at
10587 the given index
10588
10589 @since version 1.0.0
10590 */
10591 template<class IteratorType, typename std::enable_if<
10592 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
10593 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
10594 = 0>
10595 IteratorType erase(IteratorType pos)
10596 {
10597 // make sure iterator fits the current value
10598 if (JSON_UNLIKELY(this != pos.m_object))
10599 {
10600 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
10601 }
10602
10603 IteratorType result = end();
10604
10605 switch (m_type)
10606 {
10607 case value_t::boolean:
10608 case value_t::number_float:
10609 case value_t::number_integer:
10610 case value_t::number_unsigned:
10611 case value_t::string:
10612 {
10613 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
10614 {
10615 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
10616 }
10617
10618 if (is_string())
10619 {
10620 AllocatorType<string_t> alloc;
10621 alloc.destroy(m_value.string);
10622 alloc.deallocate(m_value.string, 1);
10623 m_value.string = nullptr;
10624 }
10625
10626 m_type = value_t::null;
10627 assert_invariant();
10628 break;
10629 }
10630
10631 case value_t::object:
10632 {
10633 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
10634 break;
10635 }
10636
10637 case value_t::array:
10638 {
10639 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
10640 break;
10641 }
10642
10643 default:
10644 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10645 }
10646
10647 return result;
10648 }
10649
10650 /*!
10651 @brief remove elements given an iterator range
10652
10653 Removes the element specified by the range `[first; last)`. The iterator
10654 @a first does not need to be dereferenceable if `first == last`: erasing
10655 an empty range is a no-op.
10656
10657 If called on a primitive type other than `null`, the resulting JSON value
10658 will be `null`.
10659
10660 @param[in] first iterator to the beginning of the range to remove
10661 @param[in] last iterator past the end of the range to remove
10662 @return Iterator following the last removed element. If the iterator @a
10663 second refers to the last element, the `end()` iterator is returned.
10664
10665 @tparam IteratorType an @ref iterator or @ref const_iterator
10666
10667 @post Invalidates iterators and references at or after the point of the
10668 erase, including the `end()` iterator.
10669
10670 @throw type_error.307 if called on a `null` value; example: `"cannot use
10671 erase() with null"`
10672 @throw invalid_iterator.203 if called on iterators which does not belong
10673 to the current JSON value; example: `"iterators do not fit current value"`
10674 @throw invalid_iterator.204 if called on a primitive type with invalid
10675 iterators (i.e., if `first != begin()` and `last != end()`); example:
10676 `"iterators out of range"`
10677
10678 @complexity The complexity depends on the type:
10679 - objects: `log(size()) + std::distance(first, last)`
10680 - arrays: linear in the distance between @a first and @a last, plus linear
10681 in the distance between @a last and end of the container
10682 - strings: linear in the length of the string
10683 - other types: constant
10684
10685 @liveexample{The example shows the result of `erase()` for different JSON
10686 types.,erase__IteratorType_IteratorType}
10687
10688 @sa @ref erase(IteratorType) -- removes the element at a given position
10689 @sa @ref erase(const typename object_t::key_type&) -- removes the element
10690 from an object at the given key
10691 @sa @ref erase(const size_type) -- removes the element from an array at
10692 the given index
10693
10694 @since version 1.0.0
10695 */
10696 template<class IteratorType, typename std::enable_if<
10697 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
10698 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
10699 = 0>
10700 IteratorType erase(IteratorType first, IteratorType last)
10701 {
10702 // make sure iterator fits the current value
10703 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
10704 {
10705 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
10706 }
10707
10708 IteratorType result = end();
10709
10710 switch (m_type)
10711 {
10712 case value_t::boolean:
10713 case value_t::number_float:
10714 case value_t::number_integer:
10715 case value_t::number_unsigned:
10716 case value_t::string:
10717 {
10718 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
10719 or not last.m_it.primitive_iterator.is_end()))
10720 {
10721 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
10722 }
10723
10724 if (is_string())
10725 {
10726 AllocatorType<string_t> alloc;
10727 alloc.destroy(m_value.string);
10728 alloc.deallocate(m_value.string, 1);
10729 m_value.string = nullptr;
10730 }
10731
10732 m_type = value_t::null;
10733 assert_invariant();
10734 break;
10735 }
10736
10737 case value_t::object:
10738 {
10739 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
10740 last.m_it.object_iterator);
10741 break;
10742 }
10743
10744 case value_t::array:
10745 {
10746 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
10747 last.m_it.array_iterator);
10748 break;
10749 }
10750
10751 default:
10752 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10753 }
10754
10755 return result;
10756 }
10757
10758 /*!
10759 @brief remove element from a JSON object given a key
10760
10761 Removes elements from a JSON object with the key value @a key.
10762
10763 @param[in] key value of the elements to remove
10764
10765 @return Number of elements removed. If @a ObjectType is the default
10766 `std::map` type, the return value will always be `0` (@a key was not
10767 found) or `1` (@a key was found).
10768
10769 @post References and iterators to the erased elements are invalidated.
10770 Other references and iterators are not affected.
10771
10772 @throw type_error.307 when called on a type other than JSON object;
10773 example: `"cannot use erase() with null"`
10774
10775 @complexity `log(size()) + count(key)`
10776
10777 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
10778
10779 @sa @ref erase(IteratorType) -- removes the element at a given position
10780 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10781 the given range
10782 @sa @ref erase(const size_type) -- removes the element from an array at
10783 the given index
10784
10785 @since version 1.0.0
10786 */
erase(const typename object_t::key_type & key)10787 size_type erase(const typename object_t::key_type& key)
10788 {
10789 // this erase only works for objects
10790 if (JSON_LIKELY(is_object()))
10791 {
10792 return m_value.object->erase(key);
10793 }
10794
10795 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10796 }
10797
10798 /*!
10799 @brief remove element from a JSON array given an index
10800
10801 Removes element from a JSON array at the index @a idx.
10802
10803 @param[in] idx index of the element to remove
10804
10805 @throw type_error.307 when called on a type other than JSON object;
10806 example: `"cannot use erase() with null"`
10807 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
10808 is out of range"`
10809
10810 @complexity Linear in distance between @a idx and the end of the container.
10811
10812 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
10813
10814 @sa @ref erase(IteratorType) -- removes the element at a given position
10815 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10816 the given range
10817 @sa @ref erase(const typename object_t::key_type&) -- removes the element
10818 from an object at the given key
10819
10820 @since version 1.0.0
10821 */
erase(const size_type idx)10822 void erase(const size_type idx)
10823 {
10824 // this erase only works for arrays
10825 if (JSON_LIKELY(is_array()))
10826 {
10827 if (JSON_UNLIKELY(idx >= size()))
10828 {
10829 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
10830 }
10831
10832 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
10833 }
10834 else
10835 {
10836 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10837 }
10838 }
10839
10840 /// @}
10841
10842
10843 ////////////
10844 // lookup //
10845 ////////////
10846
10847 /// @name lookup
10848 /// @{
10849
10850 /*!
10851 @brief find an element in a JSON object
10852
10853 Finds an element in a JSON object with key equivalent to @a key. If the
10854 element is not found or the JSON value is not an object, end() is
10855 returned.
10856
10857 @note This method always returns @ref end() when executed on a JSON type
10858 that is not an object.
10859
10860 @param[in] key key value of the element to search for.
10861
10862 @return Iterator to an element with key equivalent to @a key. If no such
10863 element is found or the JSON value is not an object, past-the-end (see
10864 @ref end()) iterator is returned.
10865
10866 @complexity Logarithmic in the size of the JSON object.
10867
10868 @liveexample{The example shows how `find()` is used.,find__key_type}
10869
10870 @since version 1.0.0
10871 */
10872 template<typename KeyT>
find(KeyT && key)10873 iterator find(KeyT&& key)
10874 {
10875 auto result = end();
10876
10877 if (is_object())
10878 {
10879 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10880 }
10881
10882 return result;
10883 }
10884
10885 /*!
10886 @brief find an element in a JSON object
10887 @copydoc find(KeyT&&)
10888 */
10889 template<typename KeyT>
find(KeyT && key) const10890 const_iterator find(KeyT&& key) const
10891 {
10892 auto result = cend();
10893
10894 if (is_object())
10895 {
10896 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10897 }
10898
10899 return result;
10900 }
10901
10902 /*!
10903 @brief returns the number of occurrences of a key in a JSON object
10904
10905 Returns the number of elements with key @a key. If ObjectType is the
10906 default `std::map` type, the return value will always be `0` (@a key was
10907 not found) or `1` (@a key was found).
10908
10909 @note This method always returns `0` when executed on a JSON type that is
10910 not an object.
10911
10912 @param[in] key key value of the element to count
10913
10914 @return Number of elements with key @a key. If the JSON value is not an
10915 object, the return value will be `0`.
10916
10917 @complexity Logarithmic in the size of the JSON object.
10918
10919 @liveexample{The example shows how `count()` is used.,count}
10920
10921 @since version 1.0.0
10922 */
10923 template<typename KeyT>
count(KeyT && key) const10924 size_type count(KeyT&& key) const
10925 {
10926 // return 0 for all nonobject types
10927 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
10928 }
10929
10930 /// @}
10931
10932
10933 ///////////////
10934 // iterators //
10935 ///////////////
10936
10937 /// @name iterators
10938 /// @{
10939
10940 /*!
10941 @brief returns an iterator to the first element
10942
10943 Returns an iterator to the first element.
10944
10945 @image html range-begin-end.svg "Illustration from cppreference.com"
10946
10947 @return iterator to the first element
10948
10949 @complexity Constant.
10950
10951 @requirement This function helps `basic_json` satisfying the
10952 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10953 requirements:
10954 - The complexity is constant.
10955
10956 @liveexample{The following code shows an example for `begin()`.,begin}
10957
10958 @sa @ref cbegin() -- returns a const iterator to the beginning
10959 @sa @ref end() -- returns an iterator to the end
10960 @sa @ref cend() -- returns a const iterator to the end
10961
10962 @since version 1.0.0
10963 */
begin()10964 iterator begin() noexcept
10965 {
10966 iterator result(this);
10967 result.set_begin();
10968 return result;
10969 }
10970
10971 /*!
10972 @copydoc basic_json::cbegin()
10973 */
begin() const10974 const_iterator begin() const noexcept
10975 {
10976 return cbegin();
10977 }
10978
10979 /*!
10980 @brief returns a const iterator to the first element
10981
10982 Returns a const iterator to the first element.
10983
10984 @image html range-begin-end.svg "Illustration from cppreference.com"
10985
10986 @return const iterator to the first element
10987
10988 @complexity Constant.
10989
10990 @requirement This function helps `basic_json` satisfying the
10991 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10992 requirements:
10993 - The complexity is constant.
10994 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
10995
10996 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
10997
10998 @sa @ref begin() -- returns an iterator to the beginning
10999 @sa @ref end() -- returns an iterator to the end
11000 @sa @ref cend() -- returns a const iterator to the end
11001
11002 @since version 1.0.0
11003 */
cbegin() const11004 const_iterator cbegin() const noexcept
11005 {
11006 const_iterator result(this);
11007 result.set_begin();
11008 return result;
11009 }
11010
11011 /*!
11012 @brief returns an iterator to one past the last element
11013
11014 Returns an iterator to one past the last element.
11015
11016 @image html range-begin-end.svg "Illustration from cppreference.com"
11017
11018 @return iterator one past the last element
11019
11020 @complexity Constant.
11021
11022 @requirement This function helps `basic_json` satisfying the
11023 [Container](http://en.cppreference.com/w/cpp/concept/Container)
11024 requirements:
11025 - The complexity is constant.
11026
11027 @liveexample{The following code shows an example for `end()`.,end}
11028
11029 @sa @ref cend() -- returns a const iterator to the end
11030 @sa @ref begin() -- returns an iterator to the beginning
11031 @sa @ref cbegin() -- returns a const iterator to the beginning
11032
11033 @since version 1.0.0
11034 */
end()11035 iterator end() noexcept
11036 {
11037 iterator result(this);
11038 result.set_end();
11039 return result;
11040 }
11041
11042 /*!
11043 @copydoc basic_json::cend()
11044 */
end() const11045 const_iterator end() const noexcept
11046 {
11047 return cend();
11048 }
11049
11050 /*!
11051 @brief returns a const iterator to one past the last element
11052
11053 Returns a const iterator to one past the last element.
11054
11055 @image html range-begin-end.svg "Illustration from cppreference.com"
11056
11057 @return const iterator one past the last element
11058
11059 @complexity Constant.
11060
11061 @requirement This function helps `basic_json` satisfying the
11062 [Container](http://en.cppreference.com/w/cpp/concept/Container)
11063 requirements:
11064 - The complexity is constant.
11065 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
11066
11067 @liveexample{The following code shows an example for `cend()`.,cend}
11068
11069 @sa @ref end() -- returns an iterator to the end
11070 @sa @ref begin() -- returns an iterator to the beginning
11071 @sa @ref cbegin() -- returns a const iterator to the beginning
11072
11073 @since version 1.0.0
11074 */
cend() const11075 const_iterator cend() const noexcept
11076 {
11077 const_iterator result(this);
11078 result.set_end();
11079 return result;
11080 }
11081
11082 /*!
11083 @brief returns an iterator to the reverse-beginning
11084
11085 Returns an iterator to the reverse-beginning; that is, the last element.
11086
11087 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
11088
11089 @complexity Constant.
11090
11091 @requirement This function helps `basic_json` satisfying the
11092 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
11093 requirements:
11094 - The complexity is constant.
11095 - Has the semantics of `reverse_iterator(end())`.
11096
11097 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
11098
11099 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
11100 @sa @ref rend() -- returns a reverse iterator to the end
11101 @sa @ref crend() -- returns a const reverse iterator to the end
11102
11103 @since version 1.0.0
11104 */
rbegin()11105 reverse_iterator rbegin() noexcept
11106 {
11107 return reverse_iterator(end());
11108 }
11109
11110 /*!
11111 @copydoc basic_json::crbegin()
11112 */
rbegin() const11113 const_reverse_iterator rbegin() const noexcept
11114 {
11115 return crbegin();
11116 }
11117
11118 /*!
11119 @brief returns an iterator to the reverse-end
11120
11121 Returns an iterator to the reverse-end; that is, one before the first
11122 element.
11123
11124 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
11125
11126 @complexity Constant.
11127
11128 @requirement This function helps `basic_json` satisfying the
11129 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
11130 requirements:
11131 - The complexity is constant.
11132 - Has the semantics of `reverse_iterator(begin())`.
11133
11134 @liveexample{The following code shows an example for `rend()`.,rend}
11135
11136 @sa @ref crend() -- returns a const reverse iterator to the end
11137 @sa @ref rbegin() -- returns a reverse iterator to the beginning
11138 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
11139
11140 @since version 1.0.0
11141 */
rend()11142 reverse_iterator rend() noexcept
11143 {
11144 return reverse_iterator(begin());
11145 }
11146
11147 /*!
11148 @copydoc basic_json::crend()
11149 */
rend() const11150 const_reverse_iterator rend() const noexcept
11151 {
11152 return crend();
11153 }
11154
11155 /*!
11156 @brief returns a const reverse iterator to the last element
11157
11158 Returns a const iterator to the reverse-beginning; that is, the last
11159 element.
11160
11161 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
11162
11163 @complexity Constant.
11164
11165 @requirement This function helps `basic_json` satisfying the
11166 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
11167 requirements:
11168 - The complexity is constant.
11169 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
11170
11171 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
11172
11173 @sa @ref rbegin() -- returns a reverse iterator to the beginning
11174 @sa @ref rend() -- returns a reverse iterator to the end
11175 @sa @ref crend() -- returns a const reverse iterator to the end
11176
11177 @since version 1.0.0
11178 */
crbegin() const11179 const_reverse_iterator crbegin() const noexcept
11180 {
11181 return const_reverse_iterator(cend());
11182 }
11183
11184 /*!
11185 @brief returns a const reverse iterator to one before the first
11186
11187 Returns a const reverse iterator to the reverse-end; that is, one before
11188 the first element.
11189
11190 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
11191
11192 @complexity Constant.
11193
11194 @requirement This function helps `basic_json` satisfying the
11195 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
11196 requirements:
11197 - The complexity is constant.
11198 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
11199
11200 @liveexample{The following code shows an example for `crend()`.,crend}
11201
11202 @sa @ref rend() -- returns a reverse iterator to the end
11203 @sa @ref rbegin() -- returns a reverse iterator to the beginning
11204 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
11205
11206 @since version 1.0.0
11207 */
crend() const11208 const_reverse_iterator crend() const noexcept
11209 {
11210 return const_reverse_iterator(cbegin());
11211 }
11212
11213 public:
11214 /*!
11215 @brief wrapper to access iterator member functions in range-based for
11216
11217 This function allows to access @ref iterator::key() and @ref
11218 iterator::value() during range-based for loops. In these loops, a
11219 reference to the JSON values is returned, so there is no access to the
11220 underlying iterator.
11221
11222 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
11223
11224 @note The name of this function is not yet final and may change in the
11225 future.
11226 */
iterator_wrapper(reference cont)11227 static iteration_proxy<iterator> iterator_wrapper(reference cont)
11228 {
11229 return iteration_proxy<iterator>(cont);
11230 }
11231
11232 /*!
11233 @copydoc iterator_wrapper(reference)
11234 */
iterator_wrapper(const_reference cont)11235 static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
11236 {
11237 return iteration_proxy<const_iterator>(cont);
11238 }
11239
11240 /// @}
11241
11242
11243 //////////////
11244 // capacity //
11245 //////////////
11246
11247 /// @name capacity
11248 /// @{
11249
11250 /*!
11251 @brief checks whether the container is empty.
11252
11253 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
11254
11255 @return The return value depends on the different types and is
11256 defined as follows:
11257 Value type | return value
11258 ----------- | -------------
11259 null | `true`
11260 boolean | `false`
11261 string | `false`
11262 number | `false`
11263 object | result of function `object_t::empty()`
11264 array | result of function `array_t::empty()`
11265
11266 @liveexample{The following code uses `empty()` to check if a JSON
11267 object contains any elements.,empty}
11268
11269 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
11270 the Container concept; that is, their `empty()` functions have constant
11271 complexity.
11272
11273 @iterators No changes.
11274
11275 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11276
11277 @note This function does not return whether a string stored as JSON value
11278 is empty - it returns whether the JSON container itself is empty which is
11279 false in the case of a string.
11280
11281 @requirement This function helps `basic_json` satisfying the
11282 [Container](http://en.cppreference.com/w/cpp/concept/Container)
11283 requirements:
11284 - The complexity is constant.
11285 - Has the semantics of `begin() == end()`.
11286
11287 @sa @ref size() -- returns the number of elements
11288
11289 @since version 1.0.0
11290 */
empty() const11291 bool empty() const noexcept
11292 {
11293 switch (m_type)
11294 {
11295 case value_t::null:
11296 {
11297 // null values are empty
11298 return true;
11299 }
11300
11301 case value_t::array:
11302 {
11303 // delegate call to array_t::empty()
11304 return m_value.array->empty();
11305 }
11306
11307 case value_t::object:
11308 {
11309 // delegate call to object_t::empty()
11310 return m_value.object->empty();
11311 }
11312
11313 default:
11314 {
11315 // all other types are nonempty
11316 return false;
11317 }
11318 }
11319 }
11320
11321 /*!
11322 @brief returns the number of elements
11323
11324 Returns the number of elements in a JSON value.
11325
11326 @return The return value depends on the different types and is
11327 defined as follows:
11328 Value type | return value
11329 ----------- | -------------
11330 null | `0`
11331 boolean | `1`
11332 string | `1`
11333 number | `1`
11334 object | result of function object_t::size()
11335 array | result of function array_t::size()
11336
11337 @liveexample{The following code calls `size()` on the different value
11338 types.,size}
11339
11340 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
11341 the Container concept; that is, their size() functions have constant
11342 complexity.
11343
11344 @iterators No changes.
11345
11346 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11347
11348 @note This function does not return the length of a string stored as JSON
11349 value - it returns the number of elements in the JSON value which is 1 in
11350 the case of a string.
11351
11352 @requirement This function helps `basic_json` satisfying the
11353 [Container](http://en.cppreference.com/w/cpp/concept/Container)
11354 requirements:
11355 - The complexity is constant.
11356 - Has the semantics of `std::distance(begin(), end())`.
11357
11358 @sa @ref empty() -- checks whether the container is empty
11359 @sa @ref max_size() -- returns the maximal number of elements
11360
11361 @since version 1.0.0
11362 */
size() const11363 size_type size() const noexcept
11364 {
11365 switch (m_type)
11366 {
11367 case value_t::null:
11368 {
11369 // null values are empty
11370 return 0;
11371 }
11372
11373 case value_t::array:
11374 {
11375 // delegate call to array_t::size()
11376 return m_value.array->size();
11377 }
11378
11379 case value_t::object:
11380 {
11381 // delegate call to object_t::size()
11382 return m_value.object->size();
11383 }
11384
11385 default:
11386 {
11387 // all other types have size 1
11388 return 1;
11389 }
11390 }
11391 }
11392
11393 /*!
11394 @brief returns the maximum possible number of elements
11395
11396 Returns the maximum number of elements a JSON value is able to hold due to
11397 system or library implementation limitations, i.e. `std::distance(begin(),
11398 end())` for the JSON value.
11399
11400 @return The return value depends on the different types and is
11401 defined as follows:
11402 Value type | return value
11403 ----------- | -------------
11404 null | `0` (same as `size()`)
11405 boolean | `1` (same as `size()`)
11406 string | `1` (same as `size()`)
11407 number | `1` (same as `size()`)
11408 object | result of function `object_t::max_size()`
11409 array | result of function `array_t::max_size()`
11410
11411 @liveexample{The following code calls `max_size()` on the different value
11412 types. Note the output is implementation specific.,max_size}
11413
11414 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
11415 the Container concept; that is, their `max_size()` functions have constant
11416 complexity.
11417
11418 @iterators No changes.
11419
11420 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11421
11422 @requirement This function helps `basic_json` satisfying the
11423 [Container](http://en.cppreference.com/w/cpp/concept/Container)
11424 requirements:
11425 - The complexity is constant.
11426 - Has the semantics of returning `b.size()` where `b` is the largest
11427 possible JSON value.
11428
11429 @sa @ref size() -- returns the number of elements
11430
11431 @since version 1.0.0
11432 */
max_size() const11433 size_type max_size() const noexcept
11434 {
11435 switch (m_type)
11436 {
11437 case value_t::array:
11438 {
11439 // delegate call to array_t::max_size()
11440 return m_value.array->max_size();
11441 }
11442
11443 case value_t::object:
11444 {
11445 // delegate call to object_t::max_size()
11446 return m_value.object->max_size();
11447 }
11448
11449 default:
11450 {
11451 // all other types have max_size() == size()
11452 return size();
11453 }
11454 }
11455 }
11456
11457 /// @}
11458
11459
11460 ///////////////
11461 // modifiers //
11462 ///////////////
11463
11464 /// @name modifiers
11465 /// @{
11466
11467 /*!
11468 @brief clears the contents
11469
11470 Clears the content of a JSON value and resets it to the default value as
11471 if @ref basic_json(value_t) would have been called with the current value
11472 type from @ref type():
11473
11474 Value type | initial value
11475 ----------- | -------------
11476 null | `null`
11477 boolean | `false`
11478 string | `""`
11479 number | `0`
11480 object | `{}`
11481 array | `[]`
11482
11483 @post Has the same effect as calling
11484 @code {.cpp}
11485 *this = basic_json(type());
11486 @endcode
11487
11488 @liveexample{The example below shows the effect of `clear()` to different
11489 JSON types.,clear}
11490
11491 @complexity Linear in the size of the JSON value.
11492
11493 @iterators All iterators, pointers and references related to this container
11494 are invalidated.
11495
11496 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11497
11498 @sa @ref basic_json(value_t) -- constructor that creates an object with the
11499 same value than calling `clear()`
11500
11501 @since version 1.0.0
11502 */
clear()11503 void clear() noexcept
11504 {
11505 switch (m_type)
11506 {
11507 case value_t::number_integer:
11508 {
11509 m_value.number_integer = 0;
11510 break;
11511 }
11512
11513 case value_t::number_unsigned:
11514 {
11515 m_value.number_unsigned = 0;
11516 break;
11517 }
11518
11519 case value_t::number_float:
11520 {
11521 m_value.number_float = 0.0;
11522 break;
11523 }
11524
11525 case value_t::boolean:
11526 {
11527 m_value.boolean = false;
11528 break;
11529 }
11530
11531 case value_t::string:
11532 {
11533 m_value.string->clear();
11534 break;
11535 }
11536
11537 case value_t::array:
11538 {
11539 m_value.array->clear();
11540 break;
11541 }
11542
11543 case value_t::object:
11544 {
11545 m_value.object->clear();
11546 break;
11547 }
11548
11549 default:
11550 break;
11551 }
11552 }
11553
11554 /*!
11555 @brief add an object to an array
11556
11557 Appends the given element @a val to the end of the JSON value. If the
11558 function is called on a JSON null value, an empty array is created before
11559 appending @a val.
11560
11561 @param[in] val the value to add to the JSON array
11562
11563 @throw type_error.308 when called on a type other than JSON array or
11564 null; example: `"cannot use push_back() with number"`
11565
11566 @complexity Amortized constant.
11567
11568 @liveexample{The example shows how `push_back()` and `+=` can be used to
11569 add elements to a JSON array. Note how the `null` value was silently
11570 converted to a JSON array.,push_back}
11571
11572 @since version 1.0.0
11573 */
push_back(basic_json && val)11574 void push_back(basic_json&& val)
11575 {
11576 // push_back only works for null objects or arrays
11577 if (JSON_UNLIKELY(not(is_null() or is_array())))
11578 {
11579 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
11580 }
11581
11582 // transform null object into an array
11583 if (is_null())
11584 {
11585 m_type = value_t::array;
11586 m_value = value_t::array;
11587 assert_invariant();
11588 }
11589
11590 // add element to array (move semantics)
11591 m_value.array->push_back(std::move(val));
11592 // invalidate object
11593 val.m_type = value_t::null;
11594 }
11595
11596 /*!
11597 @brief add an object to an array
11598 @copydoc push_back(basic_json&&)
11599 */
operator +=(basic_json && val)11600 reference operator+=(basic_json&& val)
11601 {
11602 push_back(std::move(val));
11603 return *this;
11604 }
11605
11606 /*!
11607 @brief add an object to an array
11608 @copydoc push_back(basic_json&&)
11609 */
push_back(const basic_json & val)11610 void push_back(const basic_json& val)
11611 {
11612 // push_back only works for null objects or arrays
11613 if (JSON_UNLIKELY(not(is_null() or is_array())))
11614 {
11615 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
11616 }
11617
11618 // transform null object into an array
11619 if (is_null())
11620 {
11621 m_type = value_t::array;
11622 m_value = value_t::array;
11623 assert_invariant();
11624 }
11625
11626 // add element to array
11627 m_value.array->push_back(val);
11628 }
11629
11630 /*!
11631 @brief add an object to an array
11632 @copydoc push_back(basic_json&&)
11633 */
operator +=(const basic_json & val)11634 reference operator+=(const basic_json& val)
11635 {
11636 push_back(val);
11637 return *this;
11638 }
11639
11640 /*!
11641 @brief add an object to an object
11642
11643 Inserts the given element @a val to the JSON object. If the function is
11644 called on a JSON null value, an empty object is created before inserting
11645 @a val.
11646
11647 @param[in] val the value to add to the JSON object
11648
11649 @throw type_error.308 when called on a type other than JSON object or
11650 null; example: `"cannot use push_back() with number"`
11651
11652 @complexity Logarithmic in the size of the container, O(log(`size()`)).
11653
11654 @liveexample{The example shows how `push_back()` and `+=` can be used to
11655 add elements to a JSON object. Note how the `null` value was silently
11656 converted to a JSON object.,push_back__object_t__value}
11657
11658 @since version 1.0.0
11659 */
push_back(const typename object_t::value_type & val)11660 void push_back(const typename object_t::value_type& val)
11661 {
11662 // push_back only works for null objects or objects
11663 if (JSON_UNLIKELY(not(is_null() or is_object())))
11664 {
11665 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
11666 }
11667
11668 // transform null object into an object
11669 if (is_null())
11670 {
11671 m_type = value_t::object;
11672 m_value = value_t::object;
11673 assert_invariant();
11674 }
11675
11676 // add element to array
11677 m_value.object->insert(val);
11678 }
11679
11680 /*!
11681 @brief add an object to an object
11682 @copydoc push_back(const typename object_t::value_type&)
11683 */
operator +=(const typename object_t::value_type & val)11684 reference operator+=(const typename object_t::value_type& val)
11685 {
11686 push_back(val);
11687 return *this;
11688 }
11689
11690 /*!
11691 @brief add an object to an object
11692
11693 This function allows to use `push_back` with an initializer list. In case
11694
11695 1. the current value is an object,
11696 2. the initializer list @a init contains only two elements, and
11697 3. the first element of @a init is a string,
11698
11699 @a init is converted into an object element and added using
11700 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
11701 is converted to a JSON value and added using @ref push_back(basic_json&&).
11702
11703 @param[in] init an initializer list
11704
11705 @complexity Linear in the size of the initializer list @a init.
11706
11707 @note This function is required to resolve an ambiguous overload error,
11708 because pairs like `{"key", "value"}` can be both interpreted as
11709 `object_t::value_type` or `std::initializer_list<basic_json>`, see
11710 https://github.com/nlohmann/json/issues/235 for more information.
11711
11712 @liveexample{The example shows how initializer lists are treated as
11713 objects when possible.,push_back__initializer_list}
11714 */
push_back(initializer_list_t init)11715 void push_back(initializer_list_t init)
11716 {
11717 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
11718 {
11719 basic_json&& key = init.begin()->moved_or_copied();
11720 push_back(typename object_t::value_type(
11721 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
11722 }
11723 else
11724 {
11725 push_back(basic_json(init));
11726 }
11727 }
11728
11729 /*!
11730 @brief add an object to an object
11731 @copydoc push_back(initializer_list_t)
11732 */
operator +=(initializer_list_t init)11733 reference operator+=(initializer_list_t init)
11734 {
11735 push_back(init);
11736 return *this;
11737 }
11738
11739 /*!
11740 @brief add an object to an array
11741
11742 Creates a JSON value from the passed parameters @a args to the end of the
11743 JSON value. If the function is called on a JSON null value, an empty array
11744 is created before appending the value created from @a args.
11745
11746 @param[in] args arguments to forward to a constructor of @ref basic_json
11747 @tparam Args compatible types to create a @ref basic_json object
11748
11749 @throw type_error.311 when called on a type other than JSON array or
11750 null; example: `"cannot use emplace_back() with number"`
11751
11752 @complexity Amortized constant.
11753
11754 @liveexample{The example shows how `push_back()` can be used to add
11755 elements to a JSON array. Note how the `null` value was silently converted
11756 to a JSON array.,emplace_back}
11757
11758 @since version 2.0.8
11759 */
11760 template<class... Args>
emplace_back(Args &&...args)11761 void emplace_back(Args&& ... args)
11762 {
11763 // emplace_back only works for null objects or arrays
11764 if (JSON_UNLIKELY(not(is_null() or is_array())))
11765 {
11766 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
11767 }
11768
11769 // transform null object into an array
11770 if (is_null())
11771 {
11772 m_type = value_t::array;
11773 m_value = value_t::array;
11774 assert_invariant();
11775 }
11776
11777 // add element to array (perfect forwarding)
11778 m_value.array->emplace_back(std::forward<Args>(args)...);
11779 }
11780
11781 /*!
11782 @brief add an object to an object if key does not exist
11783
11784 Inserts a new element into a JSON object constructed in-place with the
11785 given @a args if there is no element with the key in the container. If the
11786 function is called on a JSON null value, an empty object is created before
11787 appending the value created from @a args.
11788
11789 @param[in] args arguments to forward to a constructor of @ref basic_json
11790 @tparam Args compatible types to create a @ref basic_json object
11791
11792 @return a pair consisting of an iterator to the inserted element, or the
11793 already-existing element if no insertion happened, and a bool
11794 denoting whether the insertion took place.
11795
11796 @throw type_error.311 when called on a type other than JSON object or
11797 null; example: `"cannot use emplace() with number"`
11798
11799 @complexity Logarithmic in the size of the container, O(log(`size()`)).
11800
11801 @liveexample{The example shows how `emplace()` can be used to add elements
11802 to a JSON object. Note how the `null` value was silently converted to a
11803 JSON object. Further note how no value is added if there was already one
11804 value stored with the same key.,emplace}
11805
11806 @since version 2.0.8
11807 */
11808 template<class... Args>
emplace(Args &&...args)11809 std::pair<iterator, bool> emplace(Args&& ... args)
11810 {
11811 // emplace only works for null objects or arrays
11812 if (JSON_UNLIKELY(not(is_null() or is_object())))
11813 {
11814 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
11815 }
11816
11817 // transform null object into an object
11818 if (is_null())
11819 {
11820 m_type = value_t::object;
11821 m_value = value_t::object;
11822 assert_invariant();
11823 }
11824
11825 // add element to array (perfect forwarding)
11826 auto res = m_value.object->emplace(std::forward<Args>(args)...);
11827 // create result iterator and set iterator to the result of emplace
11828 auto it = begin();
11829 it.m_it.object_iterator = res.first;
11830
11831 // return pair of iterator and boolean
11832 return {it, res.second};
11833 }
11834
11835 /*!
11836 @brief inserts element
11837
11838 Inserts element @a val before iterator @a pos.
11839
11840 @param[in] pos iterator before which the content will be inserted; may be
11841 the end() iterator
11842 @param[in] val element to insert
11843 @return iterator pointing to the inserted @a val.
11844
11845 @throw type_error.309 if called on JSON values other than arrays;
11846 example: `"cannot use insert() with string"`
11847 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11848 example: `"iterator does not fit current value"`
11849
11850 @complexity Constant plus linear in the distance between @a pos and end of
11851 the container.
11852
11853 @liveexample{The example shows how `insert()` is used.,insert}
11854
11855 @since version 1.0.0
11856 */
insert(const_iterator pos,const basic_json & val)11857 iterator insert(const_iterator pos, const basic_json& val)
11858 {
11859 // insert only works for arrays
11860 if (JSON_LIKELY(is_array()))
11861 {
11862 // check if iterator pos fits to this JSON value
11863 if (JSON_UNLIKELY(pos.m_object != this))
11864 {
11865 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11866 }
11867
11868 // insert to array and return iterator
11869 iterator result(this);
11870 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
11871 return result;
11872 }
11873
11874 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11875 }
11876
11877 /*!
11878 @brief inserts element
11879 @copydoc insert(const_iterator, const basic_json&)
11880 */
insert(const_iterator pos,basic_json && val)11881 iterator insert(const_iterator pos, basic_json&& val)
11882 {
11883 return insert(pos, val);
11884 }
11885
11886 /*!
11887 @brief inserts elements
11888
11889 Inserts @a cnt copies of @a val before iterator @a pos.
11890
11891 @param[in] pos iterator before which the content will be inserted; may be
11892 the end() iterator
11893 @param[in] cnt number of copies of @a val to insert
11894 @param[in] val element to insert
11895 @return iterator pointing to the first element inserted, or @a pos if
11896 `cnt==0`
11897
11898 @throw type_error.309 if called on JSON values other than arrays; example:
11899 `"cannot use insert() with string"`
11900 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11901 example: `"iterator does not fit current value"`
11902
11903 @complexity Linear in @a cnt plus linear in the distance between @a pos
11904 and end of the container.
11905
11906 @liveexample{The example shows how `insert()` is used.,insert__count}
11907
11908 @since version 1.0.0
11909 */
insert(const_iterator pos,size_type cnt,const basic_json & val)11910 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
11911 {
11912 // insert only works for arrays
11913 if (JSON_LIKELY(is_array()))
11914 {
11915 // check if iterator pos fits to this JSON value
11916 if (JSON_UNLIKELY(pos.m_object != this))
11917 {
11918 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11919 }
11920
11921 // insert to array and return iterator
11922 iterator result(this);
11923 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
11924 return result;
11925 }
11926
11927 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11928 }
11929
11930 /*!
11931 @brief inserts elements
11932
11933 Inserts elements from range `[first, last)` before iterator @a pos.
11934
11935 @param[in] pos iterator before which the content will be inserted; may be
11936 the end() iterator
11937 @param[in] first begin of the range of elements to insert
11938 @param[in] last end of the range of elements to insert
11939
11940 @throw type_error.309 if called on JSON values other than arrays; example:
11941 `"cannot use insert() with string"`
11942 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11943 example: `"iterator does not fit current value"`
11944 @throw invalid_iterator.210 if @a first and @a last do not belong to the
11945 same JSON value; example: `"iterators do not fit"`
11946 @throw invalid_iterator.211 if @a first or @a last are iterators into
11947 container for which insert is called; example: `"passed iterators may not
11948 belong to container"`
11949
11950 @return iterator pointing to the first element inserted, or @a pos if
11951 `first==last`
11952
11953 @complexity Linear in `std::distance(first, last)` plus linear in the
11954 distance between @a pos and end of the container.
11955
11956 @liveexample{The example shows how `insert()` is used.,insert__range}
11957
11958 @since version 1.0.0
11959 */
insert(const_iterator pos,const_iterator first,const_iterator last)11960 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
11961 {
11962 // insert only works for arrays
11963 if (JSON_UNLIKELY(not is_array()))
11964 {
11965 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11966 }
11967
11968 // check if iterator pos fits to this JSON value
11969 if (JSON_UNLIKELY(pos.m_object != this))
11970 {
11971 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11972 }
11973
11974 // check if range iterators belong to the same JSON object
11975 if (JSON_UNLIKELY(first.m_object != last.m_object))
11976 {
11977 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11978 }
11979
11980 if (JSON_UNLIKELY(first.m_object == this))
11981 {
11982 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
11983 }
11984
11985 // insert to array and return iterator
11986 iterator result(this);
11987 result.m_it.array_iterator = m_value.array->insert(
11988 pos.m_it.array_iterator,
11989 first.m_it.array_iterator,
11990 last.m_it.array_iterator);
11991 return result;
11992 }
11993
11994 /*!
11995 @brief inserts elements
11996
11997 Inserts elements from initializer list @a ilist before iterator @a pos.
11998
11999 @param[in] pos iterator before which the content will be inserted; may be
12000 the end() iterator
12001 @param[in] ilist initializer list to insert the values from
12002
12003 @throw type_error.309 if called on JSON values other than arrays; example:
12004 `"cannot use insert() with string"`
12005 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
12006 example: `"iterator does not fit current value"`
12007
12008 @return iterator pointing to the first element inserted, or @a pos if
12009 `ilist` is empty
12010
12011 @complexity Linear in `ilist.size()` plus linear in the distance between
12012 @a pos and end of the container.
12013
12014 @liveexample{The example shows how `insert()` is used.,insert__ilist}
12015
12016 @since version 1.0.0
12017 */
insert(const_iterator pos,initializer_list_t ilist)12018 iterator insert(const_iterator pos, initializer_list_t ilist)
12019 {
12020 // insert only works for arrays
12021 if (JSON_UNLIKELY(not is_array()))
12022 {
12023 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
12024 }
12025
12026 // check if iterator pos fits to this JSON value
12027 if (JSON_UNLIKELY(pos.m_object != this))
12028 {
12029 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
12030 }
12031
12032 // insert to array and return iterator
12033 iterator result(this);
12034 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
12035 return result;
12036 }
12037
12038 /*!
12039 @brief inserts elements
12040
12041 Inserts elements from range `[first, last)`.
12042
12043 @param[in] first begin of the range of elements to insert
12044 @param[in] last end of the range of elements to insert
12045
12046 @throw type_error.309 if called on JSON values other than objects; example:
12047 `"cannot use insert() with string"`
12048 @throw invalid_iterator.202 if iterator @a first or @a last does does not
12049 point to an object; example: `"iterators first and last must point to
12050 objects"`
12051 @throw invalid_iterator.210 if @a first and @a last do not belong to the
12052 same JSON value; example: `"iterators do not fit"`
12053
12054 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
12055 of elements to insert.
12056
12057 @liveexample{The example shows how `insert()` is used.,insert__range_object}
12058
12059 @since version 3.0.0
12060 */
insert(const_iterator first,const_iterator last)12061 void insert(const_iterator first, const_iterator last)
12062 {
12063 // insert only works for objects
12064 if (JSON_UNLIKELY(not is_object()))
12065 {
12066 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
12067 }
12068
12069 // check if range iterators belong to the same JSON object
12070 if (JSON_UNLIKELY(first.m_object != last.m_object))
12071 {
12072 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
12073 }
12074
12075 // passed iterators must belong to objects
12076 if (JSON_UNLIKELY(not first.m_object->is_object()))
12077 {
12078 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
12079 }
12080
12081 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
12082 }
12083
12084 /*!
12085 @brief updates a JSON object from another object, overwriting existing keys
12086
12087 Inserts all values from JSON object @a j and overwrites existing keys.
12088
12089 @param[in] j JSON object to read values from
12090
12091 @throw type_error.312 if called on JSON values other than objects; example:
12092 `"cannot use update() with string"`
12093
12094 @complexity O(N*log(size() + N)), where N is the number of elements to
12095 insert.
12096
12097 @liveexample{The example shows how `update()` is used.,update}
12098
12099 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
12100
12101 @since version 3.0.0
12102 */
update(const_reference j)12103 void update(const_reference j)
12104 {
12105 // implicitly convert null value to an empty object
12106 if (is_null())
12107 {
12108 m_type = value_t::object;
12109 m_value.object = create<object_t>();
12110 assert_invariant();
12111 }
12112
12113 if (JSON_UNLIKELY(not is_object()))
12114 {
12115 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
12116 }
12117 if (JSON_UNLIKELY(not j.is_object()))
12118 {
12119 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
12120 }
12121
12122 for (auto it = j.begin(); it != j.end(); ++it)
12123 {
12124 m_value.object->operator[](it.key()) = it.value();
12125 }
12126 }
12127
12128 /*!
12129 @brief updates a JSON object from another object, overwriting existing keys
12130
12131 Inserts all values from from range `[first, last)` and overwrites existing
12132 keys.
12133
12134 @param[in] first begin of the range of elements to insert
12135 @param[in] last end of the range of elements to insert
12136
12137 @throw type_error.312 if called on JSON values other than objects; example:
12138 `"cannot use update() with string"`
12139 @throw invalid_iterator.202 if iterator @a first or @a last does does not
12140 point to an object; example: `"iterators first and last must point to
12141 objects"`
12142 @throw invalid_iterator.210 if @a first and @a last do not belong to the
12143 same JSON value; example: `"iterators do not fit"`
12144
12145 @complexity O(N*log(size() + N)), where N is the number of elements to
12146 insert.
12147
12148 @liveexample{The example shows how `update()` is used__range.,update}
12149
12150 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
12151
12152 @since version 3.0.0
12153 */
update(const_iterator first,const_iterator last)12154 void update(const_iterator first, const_iterator last)
12155 {
12156 // implicitly convert null value to an empty object
12157 if (is_null())
12158 {
12159 m_type = value_t::object;
12160 m_value.object = create<object_t>();
12161 assert_invariant();
12162 }
12163
12164 if (JSON_UNLIKELY(not is_object()))
12165 {
12166 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
12167 }
12168
12169 // check if range iterators belong to the same JSON object
12170 if (JSON_UNLIKELY(first.m_object != last.m_object))
12171 {
12172 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
12173 }
12174
12175 // passed iterators must belong to objects
12176 if (JSON_UNLIKELY(not first.m_object->is_object()
12177 or not first.m_object->is_object()))
12178 {
12179 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
12180 }
12181
12182 for (auto it = first; it != last; ++it)
12183 {
12184 m_value.object->operator[](it.key()) = it.value();
12185 }
12186 }
12187
12188 /*!
12189 @brief exchanges the values
12190
12191 Exchanges the contents of the JSON value with those of @a other. Does not
12192 invoke any move, copy, or swap operations on individual elements. All
12193 iterators and references remain valid. The past-the-end iterator is
12194 invalidated.
12195
12196 @param[in,out] other JSON value to exchange the contents with
12197
12198 @complexity Constant.
12199
12200 @liveexample{The example below shows how JSON values can be swapped with
12201 `swap()`.,swap__reference}
12202
12203 @since version 1.0.0
12204 */
swap(reference other)12205 void swap(reference other) noexcept (
12206 std::is_nothrow_move_constructible<value_t>::value and
12207 std::is_nothrow_move_assignable<value_t>::value and
12208 std::is_nothrow_move_constructible<json_value>::value and
12209 std::is_nothrow_move_assignable<json_value>::value
12210 )
12211 {
12212 std::swap(m_type, other.m_type);
12213 std::swap(m_value, other.m_value);
12214 assert_invariant();
12215 }
12216
12217 /*!
12218 @brief exchanges the values
12219
12220 Exchanges the contents of a JSON array with those of @a other. Does not
12221 invoke any move, copy, or swap operations on individual elements. All
12222 iterators and references remain valid. The past-the-end iterator is
12223 invalidated.
12224
12225 @param[in,out] other array to exchange the contents with
12226
12227 @throw type_error.310 when JSON value is not an array; example: `"cannot
12228 use swap() with string"`
12229
12230 @complexity Constant.
12231
12232 @liveexample{The example below shows how arrays can be swapped with
12233 `swap()`.,swap__array_t}
12234
12235 @since version 1.0.0
12236 */
swap(array_t & other)12237 void swap(array_t& other)
12238 {
12239 // swap only works for arrays
12240 if (JSON_LIKELY(is_array()))
12241 {
12242 std::swap(*(m_value.array), other);
12243 }
12244 else
12245 {
12246 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
12247 }
12248 }
12249
12250 /*!
12251 @brief exchanges the values
12252
12253 Exchanges the contents of a JSON object with those of @a other. Does not
12254 invoke any move, copy, or swap operations on individual elements. All
12255 iterators and references remain valid. The past-the-end iterator is
12256 invalidated.
12257
12258 @param[in,out] other object to exchange the contents with
12259
12260 @throw type_error.310 when JSON value is not an object; example:
12261 `"cannot use swap() with string"`
12262
12263 @complexity Constant.
12264
12265 @liveexample{The example below shows how objects can be swapped with
12266 `swap()`.,swap__object_t}
12267
12268 @since version 1.0.0
12269 */
swap(object_t & other)12270 void swap(object_t& other)
12271 {
12272 // swap only works for objects
12273 if (JSON_LIKELY(is_object()))
12274 {
12275 std::swap(*(m_value.object), other);
12276 }
12277 else
12278 {
12279 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
12280 }
12281 }
12282
12283 /*!
12284 @brief exchanges the values
12285
12286 Exchanges the contents of a JSON string with those of @a other. Does not
12287 invoke any move, copy, or swap operations on individual elements. All
12288 iterators and references remain valid. The past-the-end iterator is
12289 invalidated.
12290
12291 @param[in,out] other string to exchange the contents with
12292
12293 @throw type_error.310 when JSON value is not a string; example: `"cannot
12294 use swap() with boolean"`
12295
12296 @complexity Constant.
12297
12298 @liveexample{The example below shows how strings can be swapped with
12299 `swap()`.,swap__string_t}
12300
12301 @since version 1.0.0
12302 */
swap(string_t & other)12303 void swap(string_t& other)
12304 {
12305 // swap only works for strings
12306 if (JSON_LIKELY(is_string()))
12307 {
12308 std::swap(*(m_value.string), other);
12309 }
12310 else
12311 {
12312 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
12313 }
12314 }
12315
12316 /// @}
12317
12318 public:
12319 //////////////////////////////////////////
12320 // lexicographical comparison operators //
12321 //////////////////////////////////////////
12322
12323 /// @name lexicographical comparison operators
12324 /// @{
12325
12326 /*!
12327 @brief comparison: equal
12328
12329 Compares two JSON values for equality according to the following rules:
12330 - Two JSON values are equal if (1) they are from the same type and (2)
12331 their stored values are the same according to their respective
12332 `operator==`.
12333 - Integer and floating-point numbers are automatically converted before
12334 comparison. Note than two NaN values are always treated as unequal.
12335 - Two JSON null values are equal.
12336
12337 @note Floating-point inside JSON values numbers are compared with
12338 `json::number_float_t::operator==` which is `double::operator==` by
12339 default. To compare floating-point while respecting an epsilon, an alternative
12340 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
12341 could be used, for instance
12342 @code {.cpp}
12343 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
12344 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
12345 {
12346 return std::abs(a - b) <= epsilon;
12347 }
12348 @endcode
12349
12350 @note NaN values never compare equal to themselves or to other NaN values.
12351
12352 @param[in] lhs first JSON value to consider
12353 @param[in] rhs second JSON value to consider
12354 @return whether the values @a lhs and @a rhs are equal
12355
12356 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12357
12358 @complexity Linear.
12359
12360 @liveexample{The example demonstrates comparing several JSON
12361 types.,operator__equal}
12362
12363 @since version 1.0.0
12364 */
operator ==(const_reference lhs,const_reference rhs)12365 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
12366 {
12367 const auto lhs_type = lhs.type();
12368 const auto rhs_type = rhs.type();
12369
12370 if (lhs_type == rhs_type)
12371 {
12372 switch (lhs_type)
12373 {
12374 case value_t::array:
12375 return (*lhs.m_value.array == *rhs.m_value.array);
12376
12377 case value_t::object:
12378 return (*lhs.m_value.object == *rhs.m_value.object);
12379
12380 case value_t::null:
12381 return true;
12382
12383 case value_t::string:
12384 return (*lhs.m_value.string == *rhs.m_value.string);
12385
12386 case value_t::boolean:
12387 return (lhs.m_value.boolean == rhs.m_value.boolean);
12388
12389 case value_t::number_integer:
12390 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
12391
12392 case value_t::number_unsigned:
12393 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
12394
12395 case value_t::number_float:
12396 return (lhs.m_value.number_float == rhs.m_value.number_float);
12397
12398 default:
12399 return false;
12400 }
12401 }
12402 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
12403 {
12404 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
12405 }
12406 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
12407 {
12408 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
12409 }
12410 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
12411 {
12412 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
12413 }
12414 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
12415 {
12416 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
12417 }
12418 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
12419 {
12420 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
12421 }
12422 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
12423 {
12424 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
12425 }
12426
12427 return false;
12428 }
12429
12430 /*!
12431 @brief comparison: equal
12432 @copydoc operator==(const_reference, const_reference)
12433 */
12434 template<typename ScalarType, typename std::enable_if<
12435 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)12436 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
12437 {
12438 return (lhs == basic_json(rhs));
12439 }
12440
12441 /*!
12442 @brief comparison: equal
12443 @copydoc operator==(const_reference, const_reference)
12444 */
12445 template<typename ScalarType, typename std::enable_if<
12446 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)12447 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
12448 {
12449 return (basic_json(lhs) == rhs);
12450 }
12451
12452 /*!
12453 @brief comparison: not equal
12454
12455 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
12456
12457 @param[in] lhs first JSON value to consider
12458 @param[in] rhs second JSON value to consider
12459 @return whether the values @a lhs and @a rhs are not equal
12460
12461 @complexity Linear.
12462
12463 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12464
12465 @liveexample{The example demonstrates comparing several JSON
12466 types.,operator__notequal}
12467
12468 @since version 1.0.0
12469 */
operator !=(const_reference lhs,const_reference rhs)12470 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
12471 {
12472 return not (lhs == rhs);
12473 }
12474
12475 /*!
12476 @brief comparison: not equal
12477 @copydoc operator!=(const_reference, const_reference)
12478 */
12479 template<typename ScalarType, typename std::enable_if<
12480 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)12481 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
12482 {
12483 return (lhs != basic_json(rhs));
12484 }
12485
12486 /*!
12487 @brief comparison: not equal
12488 @copydoc operator!=(const_reference, const_reference)
12489 */
12490 template<typename ScalarType, typename std::enable_if<
12491 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)12492 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
12493 {
12494 return (basic_json(lhs) != rhs);
12495 }
12496
12497 /*!
12498 @brief comparison: less than
12499
12500 Compares whether one JSON value @a lhs is less than another JSON value @a
12501 rhs according to the following rules:
12502 - If @a lhs and @a rhs have the same type, the values are compared using
12503 the default `<` operator.
12504 - Integer and floating-point numbers are automatically converted before
12505 comparison
12506 - In case @a lhs and @a rhs have different types, the values are ignored
12507 and the order of the types is considered, see
12508 @ref operator<(const value_t, const value_t).
12509
12510 @param[in] lhs first JSON value to consider
12511 @param[in] rhs second JSON value to consider
12512 @return whether @a lhs is less than @a rhs
12513
12514 @complexity Linear.
12515
12516 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12517
12518 @liveexample{The example demonstrates comparing several JSON
12519 types.,operator__less}
12520
12521 @since version 1.0.0
12522 */
operator <(const_reference lhs,const_reference rhs)12523 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
12524 {
12525 const auto lhs_type = lhs.type();
12526 const auto rhs_type = rhs.type();
12527
12528 if (lhs_type == rhs_type)
12529 {
12530 switch (lhs_type)
12531 {
12532 case value_t::array:
12533 return (*lhs.m_value.array) < (*rhs.m_value.array);
12534
12535 case value_t::object:
12536 return *lhs.m_value.object < *rhs.m_value.object;
12537
12538 case value_t::null:
12539 return false;
12540
12541 case value_t::string:
12542 return *lhs.m_value.string < *rhs.m_value.string;
12543
12544 case value_t::boolean:
12545 return lhs.m_value.boolean < rhs.m_value.boolean;
12546
12547 case value_t::number_integer:
12548 return lhs.m_value.number_integer < rhs.m_value.number_integer;
12549
12550 case value_t::number_unsigned:
12551 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
12552
12553 case value_t::number_float:
12554 return lhs.m_value.number_float < rhs.m_value.number_float;
12555
12556 default:
12557 return false;
12558 }
12559 }
12560 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
12561 {
12562 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
12563 }
12564 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
12565 {
12566 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
12567 }
12568 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
12569 {
12570 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
12571 }
12572 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
12573 {
12574 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
12575 }
12576 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
12577 {
12578 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
12579 }
12580 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
12581 {
12582 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
12583 }
12584
12585 // We only reach this line if we cannot compare values. In that case,
12586 // we compare types. Note we have to call the operator explicitly,
12587 // because MSVC has problems otherwise.
12588 return operator<(lhs_type, rhs_type);
12589 }
12590
12591 /*!
12592 @brief comparison: less than
12593 @copydoc operator<(const_reference, const_reference)
12594 */
12595 template<typename ScalarType, typename std::enable_if<
12596 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)12597 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
12598 {
12599 return (lhs < basic_json(rhs));
12600 }
12601
12602 /*!
12603 @brief comparison: less than
12604 @copydoc operator<(const_reference, const_reference)
12605 */
12606 template<typename ScalarType, typename std::enable_if<
12607 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)12608 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
12609 {
12610 return (basic_json(lhs) < rhs);
12611 }
12612
12613 /*!
12614 @brief comparison: less than or equal
12615
12616 Compares whether one JSON value @a lhs is less than or equal to another
12617 JSON value by calculating `not (rhs < lhs)`.
12618
12619 @param[in] lhs first JSON value to consider
12620 @param[in] rhs second JSON value to consider
12621 @return whether @a lhs is less than or equal to @a rhs
12622
12623 @complexity Linear.
12624
12625 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12626
12627 @liveexample{The example demonstrates comparing several JSON
12628 types.,operator__greater}
12629
12630 @since version 1.0.0
12631 */
operator <=(const_reference lhs,const_reference rhs)12632 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
12633 {
12634 return not (rhs < lhs);
12635 }
12636
12637 /*!
12638 @brief comparison: less than or equal
12639 @copydoc operator<=(const_reference, const_reference)
12640 */
12641 template<typename ScalarType, typename std::enable_if<
12642 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)12643 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
12644 {
12645 return (lhs <= basic_json(rhs));
12646 }
12647
12648 /*!
12649 @brief comparison: less than or equal
12650 @copydoc operator<=(const_reference, const_reference)
12651 */
12652 template<typename ScalarType, typename std::enable_if<
12653 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)12654 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
12655 {
12656 return (basic_json(lhs) <= rhs);
12657 }
12658
12659 /*!
12660 @brief comparison: greater than
12661
12662 Compares whether one JSON value @a lhs is greater than another
12663 JSON value by calculating `not (lhs <= rhs)`.
12664
12665 @param[in] lhs first JSON value to consider
12666 @param[in] rhs second JSON value to consider
12667 @return whether @a lhs is greater than to @a rhs
12668
12669 @complexity Linear.
12670
12671 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12672
12673 @liveexample{The example demonstrates comparing several JSON
12674 types.,operator__lessequal}
12675
12676 @since version 1.0.0
12677 */
operator >(const_reference lhs,const_reference rhs)12678 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
12679 {
12680 return not (lhs <= rhs);
12681 }
12682
12683 /*!
12684 @brief comparison: greater than
12685 @copydoc operator>(const_reference, const_reference)
12686 */
12687 template<typename ScalarType, typename std::enable_if<
12688 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)12689 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
12690 {
12691 return (lhs > basic_json(rhs));
12692 }
12693
12694 /*!
12695 @brief comparison: greater than
12696 @copydoc operator>(const_reference, const_reference)
12697 */
12698 template<typename ScalarType, typename std::enable_if<
12699 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)12700 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
12701 {
12702 return (basic_json(lhs) > rhs);
12703 }
12704
12705 /*!
12706 @brief comparison: greater than or equal
12707
12708 Compares whether one JSON value @a lhs is greater than or equal to another
12709 JSON value by calculating `not (lhs < rhs)`.
12710
12711 @param[in] lhs first JSON value to consider
12712 @param[in] rhs second JSON value to consider
12713 @return whether @a lhs is greater than or equal to @a rhs
12714
12715 @complexity Linear.
12716
12717 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12718
12719 @liveexample{The example demonstrates comparing several JSON
12720 types.,operator__greaterequal}
12721
12722 @since version 1.0.0
12723 */
operator >=(const_reference lhs,const_reference rhs)12724 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
12725 {
12726 return not (lhs < rhs);
12727 }
12728
12729 /*!
12730 @brief comparison: greater than or equal
12731 @copydoc operator>=(const_reference, const_reference)
12732 */
12733 template<typename ScalarType, typename std::enable_if<
12734 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)12735 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
12736 {
12737 return (lhs >= basic_json(rhs));
12738 }
12739
12740 /*!
12741 @brief comparison: greater than or equal
12742 @copydoc operator>=(const_reference, const_reference)
12743 */
12744 template<typename ScalarType, typename std::enable_if<
12745 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)12746 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
12747 {
12748 return (basic_json(lhs) >= rhs);
12749 }
12750
12751 /// @}
12752
12753 ///////////////////
12754 // serialization //
12755 ///////////////////
12756
12757 /// @name serialization
12758 /// @{
12759
12760 /*!
12761 @brief serialize to stream
12762
12763 Serialize the given JSON value @a j to the output stream @a o. The JSON
12764 value will be serialized using the @ref dump member function.
12765
12766 - The indentation of the output can be controlled with the member variable
12767 `width` of the output stream @a o. For instance, using the manipulator
12768 `std::setw(4)` on @a o sets the indentation level to `4` and the
12769 serialization result is the same as calling `dump(4)`.
12770
12771 - The indentation characrer can be controlled with the member variable
12772 `fill` of the output stream @a o. For instance, the manipulator
12773 `std::setfill('\\t')` sets indentation to use a tab character rather than
12774 the default space character.
12775
12776 @param[in,out] o stream to serialize to
12777 @param[in] j JSON value to serialize
12778
12779 @return the stream @a o
12780
12781 @complexity Linear.
12782
12783 @liveexample{The example below shows the serialization with different
12784 parameters to `width` to adjust the indentation level.,operator_serialize}
12785
12786 @since version 1.0.0; indentaction character added in version 3.0.0
12787 */
operator <<(std::ostream & o,const basic_json & j)12788 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
12789 {
12790 // read width member and use it as indentation parameter if nonzero
12791 const bool pretty_print = (o.width() > 0);
12792 const auto indentation = (pretty_print ? o.width() : 0);
12793
12794 // reset width to 0 for subsequent calls to this stream
12795 o.width(0);
12796
12797 // do the actual serialization
12798 serializer s(detail::output_adapter<char>(o), o.fill());
12799 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
12800 return o;
12801 }
12802
12803 /*!
12804 @brief serialize to stream
12805 @deprecated This stream operator is deprecated and will be removed in a
12806 future version of the library. Please use
12807 @ref operator<<(std::ostream&, const basic_json&)
12808 instead; that is, replace calls like `j >> o;` with `o << j;`.
12809 @since version 1.0.0; deprecated since version 3.0.0
12810 */
12811 JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)12812 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
12813 {
12814 return o << j;
12815 }
12816
12817 /// @}
12818
12819
12820 /////////////////////
12821 // deserialization //
12822 /////////////////////
12823
12824 /// @name deserialization
12825 /// @{
12826
12827 /*!
12828 @brief deserialize from a compatible input
12829
12830 This function reads from a compatible input. Examples are:
12831 - an array of 1-byte values
12832 - strings with character/literal type with size of 1 byte
12833 - input streams
12834 - container with contiguous storage of 1-byte values. Compatible container
12835 types include `std::vector`, `std::string`, `std::array`,
12836 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
12837 arrays can be used with `std::begin()`/`std::end()`. User-defined
12838 containers can be used as long as they implement random-access iterators
12839 and a contiguous storage.
12840
12841 @pre Each element of the container has a size of 1 byte. Violating this
12842 precondition yields undefined behavior. **This precondition is enforced
12843 with a static assertion.**
12844
12845 @pre The container storage is contiguous. Violating this precondition
12846 yields undefined behavior. **This precondition is enforced with an
12847 assertion.**
12848 @pre Each element of the container has a size of 1 byte. Violating this
12849 precondition yields undefined behavior. **This precondition is enforced
12850 with a static assertion.**
12851
12852 @warning There is no way to enforce all preconditions at compile-time. If
12853 the function is called with a noncompliant container and with
12854 assertions switched off, the behavior is undefined and will most
12855 likely yield segmentation violation.
12856
12857 @param[in] i input to read from
12858 @param[in] cb a parser callback function of type @ref parser_callback_t
12859 which is used to control the deserialization by filtering unwanted values
12860 (optional)
12861
12862 @return result of the deserialization
12863
12864 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
12865 of input; expected string literal""`
12866 @throw parse_error.102 if to_unicode fails or surrogate error
12867 @throw parse_error.103 if to_unicode fails
12868
12869 @complexity Linear in the length of the input. The parser is a predictive
12870 LL(1) parser. The complexity can be higher if the parser callback function
12871 @a cb has a super-linear complexity.
12872
12873 @note A UTF-8 byte order mark is silently ignored.
12874
12875 @liveexample{The example below demonstrates the `parse()` function reading
12876 from an array.,parse__array__parser_callback_t}
12877
12878 @liveexample{The example below demonstrates the `parse()` function with
12879 and without callback function.,parse__string__parser_callback_t}
12880
12881 @liveexample{The example below demonstrates the `parse()` function with
12882 and without callback function.,parse__istream__parser_callback_t}
12883
12884 @liveexample{The example below demonstrates the `parse()` function reading
12885 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
12886
12887 @since version 2.0.3 (contiguous containers)
12888 */
parse(detail::input_adapter i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)12889 static basic_json parse(detail::input_adapter i,
12890 const parser_callback_t cb = nullptr,
12891 const bool allow_exceptions = true)
12892 {
12893 basic_json result;
12894 parser(i, cb, allow_exceptions).parse(true, result);
12895 return result;
12896 }
12897
12898 /*!
12899 @copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
12900 */
parse(detail::input_adapter & i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)12901 static basic_json parse(detail::input_adapter& i,
12902 const parser_callback_t cb = nullptr,
12903 const bool allow_exceptions = true)
12904 {
12905 basic_json result;
12906 parser(i, cb, allow_exceptions).parse(true, result);
12907 return result;
12908 }
12909
accept(detail::input_adapter i)12910 static bool accept(detail::input_adapter i)
12911 {
12912 return parser(i).accept(true);
12913 }
12914
accept(detail::input_adapter & i)12915 static bool accept(detail::input_adapter& i)
12916 {
12917 return parser(i).accept(true);
12918 }
12919
12920 /*!
12921 @brief deserialize from an iterator range with contiguous storage
12922
12923 This function reads from an iterator range of a container with contiguous
12924 storage of 1-byte values. Compatible container types include
12925 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
12926 `std::initializer_list`. Furthermore, C-style arrays can be used with
12927 `std::begin()`/`std::end()`. User-defined containers can be used as long
12928 as they implement random-access iterators and a contiguous storage.
12929
12930 @pre The iterator range is contiguous. Violating this precondition yields
12931 undefined behavior. **This precondition is enforced with an assertion.**
12932 @pre Each element in the range has a size of 1 byte. Violating this
12933 precondition yields undefined behavior. **This precondition is enforced
12934 with a static assertion.**
12935
12936 @warning There is no way to enforce all preconditions at compile-time. If
12937 the function is called with noncompliant iterators and with
12938 assertions switched off, the behavior is undefined and will most
12939 likely yield segmentation violation.
12940
12941 @tparam IteratorType iterator of container with contiguous storage
12942 @param[in] first begin of the range to parse (included)
12943 @param[in] last end of the range to parse (excluded)
12944 @param[in] cb a parser callback function of type @ref parser_callback_t
12945 which is used to control the deserialization by filtering unwanted values
12946 (optional)
12947 @param[in] allow_exceptions whether to throw exceptions in case of a
12948 parse error (optional, true by default)
12949
12950 @return result of the deserialization
12951
12952 @throw parse_error.101 in case of an unexpected token
12953 @throw parse_error.102 if to_unicode fails or surrogate error
12954 @throw parse_error.103 if to_unicode fails
12955
12956 @complexity Linear in the length of the input. The parser is a predictive
12957 LL(1) parser. The complexity can be higher if the parser callback function
12958 @a cb has a super-linear complexity.
12959
12960 @note A UTF-8 byte order mark is silently ignored.
12961
12962 @liveexample{The example below demonstrates the `parse()` function reading
12963 from an iterator range.,parse__iteratortype__parser_callback_t}
12964
12965 @since version 2.0.3
12966 */
12967 template<class IteratorType, typename std::enable_if<
12968 std::is_base_of<
12969 std::random_access_iterator_tag,
12970 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)12971 static basic_json parse(IteratorType first, IteratorType last,
12972 const parser_callback_t cb = nullptr,
12973 const bool allow_exceptions = true)
12974 {
12975 basic_json result;
12976 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
12977 return result;
12978 }
12979
12980 template<class IteratorType, typename std::enable_if<
12981 std::is_base_of<
12982 std::random_access_iterator_tag,
12983 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)12984 static bool accept(IteratorType first, IteratorType last)
12985 {
12986 return parser(detail::input_adapter(first, last)).accept(true);
12987 }
12988
12989 /*!
12990 @brief deserialize from stream
12991 @deprecated This stream operator is deprecated and will be removed in a
12992 future version of the library. Please use
12993 @ref operator>>(std::istream&, basic_json&)
12994 instead; that is, replace calls like `j << i;` with `i >> j;`.
12995 @since version 1.0.0; deprecated since version 3.0.0
12996 */
12997 JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)12998 friend std::istream& operator<<(basic_json& j, std::istream& i)
12999 {
13000 return operator>>(i, j);
13001 }
13002
13003 /*!
13004 @brief deserialize from stream
13005
13006 Deserializes an input stream to a JSON value.
13007
13008 @param[in,out] i input stream to read a serialized JSON value from
13009 @param[in,out] j JSON value to write the deserialized input to
13010
13011 @throw parse_error.101 in case of an unexpected token
13012 @throw parse_error.102 if to_unicode fails or surrogate error
13013 @throw parse_error.103 if to_unicode fails
13014
13015 @complexity Linear in the length of the input. The parser is a predictive
13016 LL(1) parser.
13017
13018 @note A UTF-8 byte order mark is silently ignored.
13019
13020 @liveexample{The example below shows how a JSON value is constructed by
13021 reading a serialization from a stream.,operator_deserialize}
13022
13023 @sa parse(std::istream&, const parser_callback_t) for a variant with a
13024 parser callback function to filter values while parsing
13025
13026 @since version 1.0.0
13027 */
operator >>(std::istream & i,basic_json & j)13028 friend std::istream& operator>>(std::istream& i, basic_json& j)
13029 {
13030 parser(detail::input_adapter(i)).parse(false, j);
13031 return i;
13032 }
13033
13034 /// @}
13035
13036 ///////////////////////////
13037 // convenience functions //
13038 ///////////////////////////
13039
13040 /*!
13041 @brief return the type as string
13042
13043 Returns the type name as string to be used in error messages - usually to
13044 indicate that a function was called on a wrong JSON type.
13045
13046 @return a string representation of a the @a m_type member:
13047 Value type | return value
13048 ----------- | -------------
13049 null | `"null"`
13050 boolean | `"boolean"`
13051 string | `"string"`
13052 number | `"number"` (for all number types)
13053 object | `"object"`
13054 array | `"array"`
13055 discarded | `"discarded"`
13056
13057 @exceptionsafety No-throw guarantee: this function never throws exceptions.
13058
13059 @complexity Constant.
13060
13061 @liveexample{The following code exemplifies `type_name()` for all JSON
13062 types.,type_name}
13063
13064 @sa @ref type() -- return the type of the JSON value
13065 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
13066
13067 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
13068 since 3.0.0
13069 */
type_name() const13070 const char* type_name() const noexcept
13071 {
13072 {
13073 switch (m_type)
13074 {
13075 case value_t::null:
13076 return "null";
13077 case value_t::object:
13078 return "object";
13079 case value_t::array:
13080 return "array";
13081 case value_t::string:
13082 return "string";
13083 case value_t::boolean:
13084 return "boolean";
13085 case value_t::discarded:
13086 return "discarded";
13087 default:
13088 return "number";
13089 }
13090 }
13091 }
13092
13093
13094 private:
13095 //////////////////////
13096 // member variables //
13097 //////////////////////
13098
13099 /// the type of the current element
13100 value_t m_type = value_t::null;
13101
13102 /// the value of the current element
13103 json_value m_value = {};
13104
13105 //////////////////////////////////////////
13106 // binary serialization/deserialization //
13107 //////////////////////////////////////////
13108
13109 /// @name binary serialization/deserialization support
13110 /// @{
13111
13112 public:
13113 /*!
13114 @brief create a CBOR serialization of a given JSON value
13115
13116 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
13117 Binary Object Representation) serialization format. CBOR is a binary
13118 serialization format which aims to be more compact than JSON itself, yet
13119 more efficient to parse.
13120
13121 The library uses the following mapping from JSON values types to
13122 CBOR types according to the CBOR specification (RFC 7049):
13123
13124 JSON value type | value/range | CBOR type | first byte
13125 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
13126 null | `null` | Null | 0xf6
13127 boolean | `true` | True | 0xf5
13128 boolean | `false` | False | 0xf4
13129 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3b
13130 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3a
13131 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
13132 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
13133 number_integer | -24..-1 | Negative integer | 0x20..0x37
13134 number_integer | 0..23 | Integer | 0x00..0x17
13135 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
13136 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
13137 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1a
13138 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1b
13139 number_unsigned | 0..23 | Integer | 0x00..0x17
13140 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
13141 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
13142 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1a
13143 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1b
13144 number_float | *any value* | Double-Precision Float | 0xfb
13145 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
13146 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
13147 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
13148 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7a
13149 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7b
13150 array | *size*: 0..23 | array | 0x80..0x97
13151 array | *size*: 23..255 | array (1 byte follow) | 0x98
13152 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
13153 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9a
13154 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9b
13155 object | *size*: 0..23 | map | 0xa0..0xb7
13156 object | *size*: 23..255 | map (1 byte follow) | 0xb8
13157 object | *size*: 256..65535 | map (2 bytes follow) | 0xb9
13158 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xba
13159 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xbb
13160
13161 @note The mapping is **complete** in the sense that any JSON value type
13162 can be converted to a CBOR value.
13163
13164 @note If NaN or Infinity are stored inside a JSON number, they are
13165 serialized properly. This behavior differs from the @ref dump()
13166 function which serializes NaN or Infinity to `null`.
13167
13168 @note The following CBOR types are not used in the conversion:
13169 - byte strings (0x40..0x5f)
13170 - UTF-8 strings terminated by "break" (0x7f)
13171 - arrays terminated by "break" (0x9f)
13172 - maps terminated by "break" (0xbf)
13173 - date/time (0xc0..0xc1)
13174 - bignum (0xc2..0xc3)
13175 - decimal fraction (0xc4)
13176 - bigfloat (0xc5)
13177 - tagged items (0xc6..0xd4, 0xd8..0xdb)
13178 - expected conversions (0xd5..0xd7)
13179 - simple values (0xe0..0xf3, 0xf8)
13180 - undefined (0xf7)
13181 - half and single-precision floats (0xf9-0xfa)
13182 - break (0xff)
13183
13184 @param[in] j JSON value to serialize
13185 @return MessagePack serialization as byte vector
13186
13187 @complexity Linear in the size of the JSON value @a j.
13188
13189 @liveexample{The example shows the serialization of a JSON value to a byte
13190 vector in CBOR format.,to_cbor}
13191
13192 @sa http://cbor.io
13193 @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
13194 analogous deserialization
13195 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
13196
13197 @since version 2.0.9
13198 */
to_cbor(const basic_json & j)13199 static std::vector<uint8_t> to_cbor(const basic_json& j)
13200 {
13201 std::vector<uint8_t> result;
13202 to_cbor(j, result);
13203 return result;
13204 }
13205
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)13206 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
13207 {
13208 binary_writer<uint8_t>(o).write_cbor(j);
13209 }
13210
to_cbor(const basic_json & j,detail::output_adapter<char> o)13211 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
13212 {
13213 binary_writer<char>(o).write_cbor(j);
13214 }
13215
13216 /*!
13217 @brief create a MessagePack serialization of a given JSON value
13218
13219 Serializes a given JSON value @a j to a byte vector using the MessagePack
13220 serialization format. MessagePack is a binary serialization format which
13221 aims to be more compact than JSON itself, yet more efficient to parse.
13222
13223 The library uses the following mapping from JSON values types to
13224 MessagePack types according to the MessagePack specification:
13225
13226 JSON value type | value/range | MessagePack type | first byte
13227 --------------- | --------------------------------- | ---------------- | ----------
13228 null | `null` | nil | 0xc0
13229 boolean | `true` | true | 0xc3
13230 boolean | `false` | false | 0xc2
13231 number_integer | -9223372036854775808..-2147483649 | int64 | 0xd3
13232 number_integer | -2147483648..-32769 | int32 | 0xd2
13233 number_integer | -32768..-129 | int16 | 0xd1
13234 number_integer | -128..-33 | int8 | 0xd0
13235 number_integer | -32..-1 | negative fixint | 0xe0..0xff
13236 number_integer | 0..127 | positive fixint | 0x00..0x7f
13237 number_integer | 128..255 | uint 8 | 0xcc
13238 number_integer | 256..65535 | uint 16 | 0xcd
13239 number_integer | 65536..4294967295 | uint 32 | 0xce
13240 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xcf
13241 number_unsigned | 0..127 | positive fixint | 0x00..0x7f
13242 number_unsigned | 128..255 | uint 8 | 0xcc
13243 number_unsigned | 256..65535 | uint 16 | 0xcd
13244 number_unsigned | 65536..4294967295 | uint 32 | 0xce
13245 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xcf
13246 number_float | *any value* | float 64 | 0xcb
13247 string | *length*: 0..31 | fixstr | 0xa0..0xbf
13248 string | *length*: 32..255 | str 8 | 0xd9
13249 string | *length*: 256..65535 | str 16 | 0xda
13250 string | *length*: 65536..4294967295 | str 32 | 0xdb
13251 array | *size*: 0..15 | fixarray | 0x90..0x9f
13252 array | *size*: 16..65535 | array 16 | 0xdc
13253 array | *size*: 65536..4294967295 | array 32 | 0xdd
13254 object | *size*: 0..15 | fix map | 0x80..0x8f
13255 object | *size*: 16..65535 | map 16 | 0xde
13256 object | *size*: 65536..4294967295 | map 32 | 0xdf
13257
13258 @note The mapping is **complete** in the sense that any JSON value type
13259 can be converted to a MessagePack value.
13260
13261 @note The following values can **not** be converted to a MessagePack value:
13262 - strings with more than 4294967295 bytes
13263 - arrays with more than 4294967295 elements
13264 - objects with more than 4294967295 elements
13265
13266 @note The following MessagePack types are not used in the conversion:
13267 - bin 8 - bin 32 (0xc4..0xc6)
13268 - ext 8 - ext 32 (0xc7..0xc9)
13269 - float 32 (0xca)
13270 - fixext 1 - fixext 16 (0xd4..0xd8)
13271
13272 @note Any MessagePack output created @ref to_msgpack can be successfully
13273 parsed by @ref from_msgpack.
13274
13275 @note If NaN or Infinity are stored inside a JSON number, they are
13276 serialized properly. This behavior differs from the @ref dump()
13277 function which serializes NaN or Infinity to `null`.
13278
13279 @param[in] j JSON value to serialize
13280 @return MessagePack serialization as byte vector
13281
13282 @complexity Linear in the size of the JSON value @a j.
13283
13284 @liveexample{The example shows the serialization of a JSON value to a byte
13285 vector in MessagePack format.,to_msgpack}
13286
13287 @sa http://msgpack.org
13288 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
13289 analogous deserialization
13290 @sa @ref to_cbor(const basic_json& for the related CBOR format
13291
13292 @since version 2.0.9
13293 */
to_msgpack(const basic_json & j)13294 static std::vector<uint8_t> to_msgpack(const basic_json& j)
13295 {
13296 std::vector<uint8_t> result;
13297 to_msgpack(j, result);
13298 return result;
13299 }
13300
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)13301 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
13302 {
13303 binary_writer<uint8_t>(o).write_msgpack(j);
13304 }
13305
to_msgpack(const basic_json & j,detail::output_adapter<char> o)13306 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
13307 {
13308 binary_writer<char>(o).write_msgpack(j);
13309 }
13310
13311 /*!
13312 @brief create a JSON value from an input in CBOR format
13313
13314 Deserializes a given input @a i to a JSON value using the CBOR (Concise
13315 Binary Object Representation) serialization format.
13316
13317 The library maps CBOR types to JSON value types as follows:
13318
13319 CBOR type | JSON value type | first byte
13320 ---------------------- | --------------- | ----------
13321 Integer | number_unsigned | 0x00..0x17
13322 Unsigned integer | number_unsigned | 0x18
13323 Unsigned integer | number_unsigned | 0x19
13324 Unsigned integer | number_unsigned | 0x1a
13325 Unsigned integer | number_unsigned | 0x1b
13326 Negative integer | number_integer | 0x20..0x37
13327 Negative integer | number_integer | 0x38
13328 Negative integer | number_integer | 0x39
13329 Negative integer | number_integer | 0x3a
13330 Negative integer | number_integer | 0x3b
13331 Negative integer | number_integer | 0x40..0x57
13332 UTF-8 string | string | 0x60..0x77
13333 UTF-8 string | string | 0x78
13334 UTF-8 string | string | 0x79
13335 UTF-8 string | string | 0x7a
13336 UTF-8 string | string | 0x7b
13337 UTF-8 string | string | 0x7f
13338 array | array | 0x80..0x97
13339 array | array | 0x98
13340 array | array | 0x99
13341 array | array | 0x9a
13342 array | array | 0x9b
13343 array | array | 0x9f
13344 map | object | 0xa0..0xb7
13345 map | object | 0xb8
13346 map | object | 0xb9
13347 map | object | 0xba
13348 map | object | 0xbb
13349 map | object | 0xbf
13350 False | `false` | 0xf4
13351 True | `true` | 0xf5
13352 Nill | `null` | 0xf6
13353 Half-Precision Float | number_float | 0xf9
13354 Single-Precision Float | number_float | 0xfa
13355 Double-Precision Float | number_float | 0xfb
13356
13357 @warning The mapping is **incomplete** in the sense that not all CBOR
13358 types can be converted to a JSON value. The following CBOR types
13359 are not supported and will yield parse errors (parse_error.112):
13360 - byte strings (0x40..0x5f)
13361 - date/time (0xc0..0xc1)
13362 - bignum (0xc2..0xc3)
13363 - decimal fraction (0xc4)
13364 - bigfloat (0xc5)
13365 - tagged items (0xc6..0xd4, 0xd8..0xdb)
13366 - expected conversions (0xd5..0xd7)
13367 - simple values (0xe0..0xf3, 0xf8)
13368 - undefined (0xf7)
13369
13370 @warning CBOR allows map keys of any type, whereas JSON only allows
13371 strings as keys in object values. Therefore, CBOR maps with keys
13372 other than UTF-8 strings are rejected (parse_error.113).
13373
13374 @note Any CBOR output created @ref to_cbor can be successfully parsed by
13375 @ref from_cbor.
13376
13377 @param[in] i an input in CBOR format convertible to an input adapter
13378 @param[in] strict whether to expect the input to be consumed until EOF
13379 (true by default)
13380 @return deserialized JSON value
13381
13382 @throw parse_error.110 if the given input ends prematurely or the end of
13383 file was not reached when @a strict was set to true
13384 @throw parse_error.112 if unsupported features from CBOR were
13385 used in the given input @a v or if the input is not valid CBOR
13386 @throw parse_error.113 if a string was expected as map key, but not found
13387
13388 @complexity Linear in the size of the input @a i.
13389
13390 @liveexample{The example shows the deserialization of a byte vector in CBOR
13391 format to a JSON value.,from_cbor}
13392
13393 @sa http://cbor.io
13394 @sa @ref to_cbor(const basic_json&) for the analogous serialization
13395 @sa @ref from_msgpack(detail::input_adapter, const bool) for the
13396 related MessagePack format
13397
13398 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
13399 consume input adapters, removed start_index parameter, and added
13400 @a strict parameter since 3.0.0
13401 */
from_cbor(detail::input_adapter i,const bool strict=true)13402 static basic_json from_cbor(detail::input_adapter i,
13403 const bool strict = true)
13404 {
13405 return binary_reader(i).parse_cbor(strict);
13406 }
13407
13408 /*!
13409 @copydoc from_cbor(detail::input_adapter, const bool)
13410 */
13411 template<typename A1, typename A2,
13412 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_cbor(A1 && a1,A2 && a2,const bool strict=true)13413 static basic_json from_cbor(A1 && a1, A2 && a2, const bool strict = true)
13414 {
13415 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
13416 }
13417
13418 /*!
13419 @brief create a JSON value from an input in MessagePack format
13420
13421 Deserializes a given input @a i to a JSON value using the MessagePack
13422 serialization format.
13423
13424 The library maps MessagePack types to JSON value types as follows:
13425
13426 MessagePack type | JSON value type | first byte
13427 ---------------- | --------------- | ----------
13428 positive fixint | number_unsigned | 0x00..0x7f
13429 fixmap | object | 0x80..0x8f
13430 fixarray | array | 0x90..0x9f
13431 fixstr | string | 0xa0..0xbf
13432 nil | `null` | 0xc0
13433 false | `false` | 0xc2
13434 true | `true` | 0xc3
13435 float 32 | number_float | 0xca
13436 float 64 | number_float | 0xcb
13437 uint 8 | number_unsigned | 0xcc
13438 uint 16 | number_unsigned | 0xcd
13439 uint 32 | number_unsigned | 0xce
13440 uint 64 | number_unsigned | 0xcf
13441 int 8 | number_integer | 0xd0
13442 int 16 | number_integer | 0xd1
13443 int 32 | number_integer | 0xd2
13444 int 64 | number_integer | 0xd3
13445 str 8 | string | 0xd9
13446 str 16 | string | 0xda
13447 str 32 | string | 0xdb
13448 array 16 | array | 0xdc
13449 array 32 | array | 0xdd
13450 map 16 | object | 0xde
13451 map 32 | object | 0xdf
13452 negative fixint | number_integer | 0xe0-0xff
13453
13454 @warning The mapping is **incomplete** in the sense that not all
13455 MessagePack types can be converted to a JSON value. The following
13456 MessagePack types are not supported and will yield parse errors:
13457 - bin 8 - bin 32 (0xc4..0xc6)
13458 - ext 8 - ext 32 (0xc7..0xc9)
13459 - fixext 1 - fixext 16 (0xd4..0xd8)
13460
13461 @note Any MessagePack output created @ref to_msgpack can be successfully
13462 parsed by @ref from_msgpack.
13463
13464 @param[in] i an input in MessagePack format convertible to an input
13465 adapter
13466 @param[in] strict whether to expect the input to be consumed until EOF
13467 (true by default)
13468
13469 @throw parse_error.110 if the given input ends prematurely or the end of
13470 file was not reached when @a strict was set to true
13471 @throw parse_error.112 if unsupported features from MessagePack were
13472 used in the given input @a i or if the input is not valid MessagePack
13473 @throw parse_error.113 if a string was expected as map key, but not found
13474
13475 @complexity Linear in the size of the input @a i.
13476
13477 @liveexample{The example shows the deserialization of a byte vector in
13478 MessagePack format to a JSON value.,from_msgpack}
13479
13480 @sa http://msgpack.org
13481 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
13482 @sa @ref from_cbor(detail::input_adapter, const bool) for the related CBOR
13483 format
13484
13485 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
13486 consume input adapters, removed start_index parameter, and added
13487 @a strict parameter since 3.0.0
13488 */
from_msgpack(detail::input_adapter i,const bool strict=true)13489 static basic_json from_msgpack(detail::input_adapter i,
13490 const bool strict = true)
13491 {
13492 return binary_reader(i).parse_msgpack(strict);
13493 }
13494
13495 /*!
13496 @copydoc from_msgpack(detail::input_adapter, const bool)
13497 */
13498 template<typename A1, typename A2,
13499 detail::enable_if_t<std::is_constructible<detail::input_adapter, A1, A2>::value, int> = 0>
from_msgpack(A1 && a1,A2 && a2,const bool strict=true)13500 static basic_json from_msgpack(A1 && a1, A2 && a2, const bool strict = true)
13501 {
13502 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
13503 }
13504
13505 /// @}
13506
13507 //////////////////////////
13508 // JSON Pointer support //
13509 //////////////////////////
13510
13511 /// @name JSON Pointer functions
13512 /// @{
13513
13514 /*!
13515 @brief access specified element via JSON Pointer
13516
13517 Uses a JSON pointer to retrieve a reference to the respective JSON value.
13518 No bound checking is performed. Similar to @ref operator[](const typename
13519 object_t::key_type&), `null` values are created in arrays and objects if
13520 necessary.
13521
13522 In particular:
13523 - If the JSON pointer points to an object key that does not exist, it
13524 is created an filled with a `null` value before a reference to it
13525 is returned.
13526 - If the JSON pointer points to an array index that does not exist, it
13527 is created an filled with a `null` value before a reference to it
13528 is returned. All indices between the current maximum and the given
13529 index are also filled with `null`.
13530 - The special value `-` is treated as a synonym for the index past the
13531 end.
13532
13533 @param[in] ptr a JSON pointer
13534
13535 @return reference to the element pointed to by @a ptr
13536
13537 @complexity Constant.
13538
13539 @throw parse_error.106 if an array index begins with '0'
13540 @throw parse_error.109 if an array index was not a number
13541 @throw out_of_range.404 if the JSON pointer can not be resolved
13542
13543 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
13544
13545 @since version 2.0.0
13546 */
operator [](const json_pointer & ptr)13547 reference operator[](const json_pointer& ptr)
13548 {
13549 return ptr.get_unchecked(this);
13550 }
13551
13552 /*!
13553 @brief access specified element via JSON Pointer
13554
13555 Uses a JSON pointer to retrieve a reference to the respective JSON value.
13556 No bound checking is performed. The function does not change the JSON
13557 value; no `null` values are created. In particular, the the special value
13558 `-` yields an exception.
13559
13560 @param[in] ptr JSON pointer to the desired element
13561
13562 @return const reference to the element pointed to by @a ptr
13563
13564 @complexity Constant.
13565
13566 @throw parse_error.106 if an array index begins with '0'
13567 @throw parse_error.109 if an array index was not a number
13568 @throw out_of_range.402 if the array index '-' is used
13569 @throw out_of_range.404 if the JSON pointer can not be resolved
13570
13571 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
13572
13573 @since version 2.0.0
13574 */
operator [](const json_pointer & ptr) const13575 const_reference operator[](const json_pointer& ptr) const
13576 {
13577 return ptr.get_unchecked(this);
13578 }
13579
13580 /*!
13581 @brief access specified element via JSON Pointer
13582
13583 Returns a reference to the element at with specified JSON pointer @a ptr,
13584 with bounds checking.
13585
13586 @param[in] ptr JSON pointer to the desired element
13587
13588 @return reference to the element pointed to by @a ptr
13589
13590 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
13591 begins with '0'. See example below.
13592
13593 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
13594 is not a number. See example below.
13595
13596 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
13597 is out of range. See example below.
13598
13599 @throw out_of_range.402 if the array index '-' is used in the passed JSON
13600 pointer @a ptr. As `at` provides checked access (and no elements are
13601 implicitly inserted), the index '-' is always invalid. See example below.
13602
13603 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
13604 See example below.
13605
13606 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13607 changes in the JSON value.
13608
13609 @complexity Constant.
13610
13611 @since version 2.0.0
13612
13613 @liveexample{The behavior is shown in the example.,at_json_pointer}
13614 */
at(const json_pointer & ptr)13615 reference at(const json_pointer& ptr)
13616 {
13617 return ptr.get_checked(this);
13618 }
13619
13620 /*!
13621 @brief access specified element via JSON Pointer
13622
13623 Returns a const reference to the element at with specified JSON pointer @a
13624 ptr, with bounds checking.
13625
13626 @param[in] ptr JSON pointer to the desired element
13627
13628 @return reference to the element pointed to by @a ptr
13629
13630 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
13631 begins with '0'. See example below.
13632
13633 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
13634 is not a number. See example below.
13635
13636 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
13637 is out of range. See example below.
13638
13639 @throw out_of_range.402 if the array index '-' is used in the passed JSON
13640 pointer @a ptr. As `at` provides checked access (and no elements are
13641 implicitly inserted), the index '-' is always invalid. See example below.
13642
13643 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
13644 See example below.
13645
13646 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
13647 changes in the JSON value.
13648
13649 @complexity Constant.
13650
13651 @since version 2.0.0
13652
13653 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
13654 */
at(const json_pointer & ptr) const13655 const_reference at(const json_pointer& ptr) const
13656 {
13657 return ptr.get_checked(this);
13658 }
13659
13660 /*!
13661 @brief return flattened JSON value
13662
13663 The function creates a JSON object whose keys are JSON pointers (see [RFC
13664 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
13665 primitive. The original JSON value can be restored using the @ref
13666 unflatten() function.
13667
13668 @return an object that maps JSON pointers to primitive values
13669
13670 @note Empty objects and arrays are flattened to `null` and will not be
13671 reconstructed correctly by the @ref unflatten() function.
13672
13673 @complexity Linear in the size the JSON value.
13674
13675 @liveexample{The following code shows how a JSON object is flattened to an
13676 object whose keys consist of JSON pointers.,flatten}
13677
13678 @sa @ref unflatten() for the reverse function
13679
13680 @since version 2.0.0
13681 */
flatten() const13682 basic_json flatten() const
13683 {
13684 basic_json result(value_t::object);
13685 json_pointer::flatten("", *this, result);
13686 return result;
13687 }
13688
13689 /*!
13690 @brief unflatten a previously flattened JSON value
13691
13692 The function restores the arbitrary nesting of a JSON value that has been
13693 flattened before using the @ref flatten() function. The JSON value must
13694 meet certain constraints:
13695 1. The value must be an object.
13696 2. The keys must be JSON pointers (see
13697 [RFC 6901](https://tools.ietf.org/html/rfc6901))
13698 3. The mapped values must be primitive JSON types.
13699
13700 @return the original JSON from a flattened version
13701
13702 @note Empty objects and arrays are flattened by @ref flatten() to `null`
13703 values and can not unflattened to their original type. Apart from
13704 this example, for a JSON value `j`, the following is always true:
13705 `j == j.flatten().unflatten()`.
13706
13707 @complexity Linear in the size the JSON value.
13708
13709 @throw type_error.314 if value is not an object
13710 @throw type_error.315 if object values are not primitive
13711
13712 @liveexample{The following code shows how a flattened JSON object is
13713 unflattened into the original nested JSON object.,unflatten}
13714
13715 @sa @ref flatten() for the reverse function
13716
13717 @since version 2.0.0
13718 */
unflatten() const13719 basic_json unflatten() const
13720 {
13721 return json_pointer::unflatten(*this);
13722 }
13723
13724 /// @}
13725
13726 //////////////////////////
13727 // JSON Patch functions //
13728 //////////////////////////
13729
13730 /// @name JSON Patch functions
13731 /// @{
13732
13733 /*!
13734 @brief applies a JSON patch
13735
13736 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
13737 expressing a sequence of operations to apply to a JSON) document. With
13738 this function, a JSON Patch is applied to the current JSON value by
13739 executing all operations from the patch.
13740
13741 @param[in] json_patch JSON patch document
13742 @return patched document
13743
13744 @note The application of a patch is atomic: Either all operations succeed
13745 and the patched document is returned or an exception is thrown. In
13746 any case, the original value is not changed: the patch is applied
13747 to a copy of the value.
13748
13749 @throw parse_error.104 if the JSON patch does not consist of an array of
13750 objects
13751
13752 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
13753 attributes are missing); example: `"operation add must have member path"`
13754
13755 @throw out_of_range.401 if an array index is out of range.
13756
13757 @throw out_of_range.403 if a JSON pointer inside the patch could not be
13758 resolved successfully in the current JSON value; example: `"key baz not
13759 found"`
13760
13761 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
13762 "move")
13763
13764 @throw other_error.501 if "test" operation was unsuccessful
13765
13766 @complexity Linear in the size of the JSON value and the length of the
13767 JSON patch. As usually only a fraction of the JSON value is affected by
13768 the patch, the complexity can usually be neglected.
13769
13770 @liveexample{The following code shows how a JSON patch is applied to a
13771 value.,patch}
13772
13773 @sa @ref diff -- create a JSON patch by comparing two JSON values
13774
13775 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
13776 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
13777
13778 @since version 2.0.0
13779 */
patch(const basic_json & json_patch) const13780 basic_json patch(const basic_json& json_patch) const
13781 {
13782 // make a working copy to apply the patch to
13783 basic_json result = *this;
13784
13785 // the valid JSON Patch operations
13786 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
13787
13788 const auto get_op = [](const std::string & op)
13789 {
13790 if (op == "add")
13791 {
13792 return patch_operations::add;
13793 }
13794 if (op == "remove")
13795 {
13796 return patch_operations::remove;
13797 }
13798 if (op == "replace")
13799 {
13800 return patch_operations::replace;
13801 }
13802 if (op == "move")
13803 {
13804 return patch_operations::move;
13805 }
13806 if (op == "copy")
13807 {
13808 return patch_operations::copy;
13809 }
13810 if (op == "test")
13811 {
13812 return patch_operations::test;
13813 }
13814
13815 return patch_operations::invalid;
13816 };
13817
13818 // wrapper for "add" operation; add value at ptr
13819 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
13820 {
13821 // adding to the root of the target document means replacing it
13822 if (ptr.is_root())
13823 {
13824 result = val;
13825 }
13826 else
13827 {
13828 // make sure the top element of the pointer exists
13829 json_pointer top_pointer = ptr.top();
13830 if (top_pointer != ptr)
13831 {
13832 result.at(top_pointer);
13833 }
13834
13835 // get reference to parent of JSON pointer ptr
13836 const auto last_path = ptr.pop_back();
13837 basic_json& parent = result[ptr];
13838
13839 switch (parent.m_type)
13840 {
13841 case value_t::null:
13842 case value_t::object:
13843 {
13844 // use operator[] to add value
13845 parent[last_path] = val;
13846 break;
13847 }
13848
13849 case value_t::array:
13850 {
13851 if (last_path == "-")
13852 {
13853 // special case: append to back
13854 parent.push_back(val);
13855 }
13856 else
13857 {
13858 const auto idx = std::stoi(last_path);
13859 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
13860 {
13861 // avoid undefined behavior
13862 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
13863 }
13864 else
13865 {
13866 // default case: insert add offset
13867 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
13868 }
13869 }
13870 break;
13871 }
13872
13873 default:
13874 {
13875 // if there exists a parent it cannot be primitive
13876 assert(false); // LCOV_EXCL_LINE
13877 }
13878 }
13879 }
13880 };
13881
13882 // wrapper for "remove" operation; remove value at ptr
13883 const auto operation_remove = [&result](json_pointer & ptr)
13884 {
13885 // get reference to parent of JSON pointer ptr
13886 const auto last_path = ptr.pop_back();
13887 basic_json& parent = result.at(ptr);
13888
13889 // remove child
13890 if (parent.is_object())
13891 {
13892 // perform range check
13893 auto it = parent.find(last_path);
13894 if (JSON_LIKELY(it != parent.end()))
13895 {
13896 parent.erase(it);
13897 }
13898 else
13899 {
13900 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
13901 }
13902 }
13903 else if (parent.is_array())
13904 {
13905 // note erase performs range check
13906 parent.erase(static_cast<size_type>(std::stoi(last_path)));
13907 }
13908 };
13909
13910 // type check: top level value must be an array
13911 if (JSON_UNLIKELY(not json_patch.is_array()))
13912 {
13913 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
13914 }
13915
13916 // iterate and apply the operations
13917 for (const auto& val : json_patch)
13918 {
13919 // wrapper to get a value for an operation
13920 const auto get_value = [&val](const std::string & op,
13921 const std::string & member,
13922 bool string_type) -> basic_json&
13923 {
13924 // find value
13925 auto it = val.m_value.object->find(member);
13926
13927 // context-sensitive error message
13928 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
13929
13930 // check if desired value is present
13931 if (JSON_UNLIKELY(it == val.m_value.object->end()))
13932 {
13933 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
13934 }
13935
13936 // check if result is of type string
13937 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
13938 {
13939 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
13940 }
13941
13942 // no error: return value
13943 return it->second;
13944 };
13945
13946 // type check: every element of the array must be an object
13947 if (JSON_UNLIKELY(not val.is_object()))
13948 {
13949 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
13950 }
13951
13952 // collect mandatory members
13953 const std::string op = get_value("op", "op", true);
13954 const std::string path = get_value(op, "path", true);
13955 json_pointer ptr(path);
13956
13957 switch (get_op(op))
13958 {
13959 case patch_operations::add:
13960 {
13961 operation_add(ptr, get_value("add", "value", false));
13962 break;
13963 }
13964
13965 case patch_operations::remove:
13966 {
13967 operation_remove(ptr);
13968 break;
13969 }
13970
13971 case patch_operations::replace:
13972 {
13973 // the "path" location must exist - use at()
13974 result.at(ptr) = get_value("replace", "value", false);
13975 break;
13976 }
13977
13978 case patch_operations::move:
13979 {
13980 const std::string from_path = get_value("move", "from", true);
13981 json_pointer from_ptr(from_path);
13982
13983 // the "from" location must exist - use at()
13984 basic_json v = result.at(from_ptr);
13985
13986 // The move operation is functionally identical to a
13987 // "remove" operation on the "from" location, followed
13988 // immediately by an "add" operation at the target
13989 // location with the value that was just removed.
13990 operation_remove(from_ptr);
13991 operation_add(ptr, v);
13992 break;
13993 }
13994
13995 case patch_operations::copy:
13996 {
13997 const std::string from_path = get_value("copy", "from", true);
13998 const json_pointer from_ptr(from_path);
13999
14000 // the "from" location must exist - use at()
14001 result[ptr] = result.at(from_ptr);
14002 break;
14003 }
14004
14005 case patch_operations::test:
14006 {
14007 bool success = false;
14008 JSON_TRY
14009 {
14010 // check if "value" matches the one at "path"
14011 // the "path" location must exist - use at()
14012 success = (result.at(ptr) == get_value("test", "value", false));
14013 }
14014 JSON_CATCH (out_of_range&)
14015 {
14016 // ignore out of range errors: success remains false
14017 }
14018
14019 // throw an exception if test fails
14020 if (JSON_UNLIKELY(not success))
14021 {
14022 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
14023 }
14024
14025 break;
14026 }
14027
14028 case patch_operations::invalid:
14029 {
14030 // op must be "add", "remove", "replace", "move", "copy", or
14031 // "test"
14032 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
14033 }
14034 }
14035 }
14036
14037 return result;
14038 }
14039
14040 /*!
14041 @brief creates a diff as a JSON patch
14042
14043 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
14044 be changed into the value @a target by calling @ref patch function.
14045
14046 @invariant For two JSON values @a source and @a target, the following code
14047 yields always `true`:
14048 @code {.cpp}
14049 source.patch(diff(source, target)) == target;
14050 @endcode
14051
14052 @note Currently, only `remove`, `add`, and `replace` operations are
14053 generated.
14054
14055 @param[in] source JSON value to compare from
14056 @param[in] target JSON value to compare against
14057 @param[in] path helper value to create JSON pointers
14058
14059 @return a JSON patch to convert the @a source to @a target
14060
14061 @complexity Linear in the lengths of @a source and @a target.
14062
14063 @liveexample{The following code shows how a JSON patch is created as a
14064 diff for two JSON values.,diff}
14065
14066 @sa @ref patch -- apply a JSON patch
14067
14068 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
14069
14070 @since version 2.0.0
14071 */
diff(const basic_json & source,const basic_json & target,const std::string & path="")14072 static basic_json diff(const basic_json& source, const basic_json& target,
14073 const std::string& path = "")
14074 {
14075 // the patch
14076 basic_json result(value_t::array);
14077
14078 // if the values are the same, return empty patch
14079 if (source == target)
14080 {
14081 return result;
14082 }
14083
14084 if (source.type() != target.type())
14085 {
14086 // different types: replace value
14087 result.push_back(
14088 {
14089 {"op", "replace"}, {"path", path}, {"value", target}
14090 });
14091 }
14092 else
14093 {
14094 switch (source.type())
14095 {
14096 case value_t::array:
14097 {
14098 // first pass: traverse common elements
14099 std::size_t i = 0;
14100 while (i < source.size() and i < target.size())
14101 {
14102 // recursive call to compare array values at index i
14103 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
14104 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14105 ++i;
14106 }
14107
14108 // i now reached the end of at least one array
14109 // in a second pass, traverse the remaining elements
14110
14111 // remove my remaining elements
14112 const auto end_index = static_cast<difference_type>(result.size());
14113 while (i < source.size())
14114 {
14115 // add operations in reverse order to avoid invalid
14116 // indices
14117 result.insert(result.begin() + end_index, object(
14118 {
14119 {"op", "remove"},
14120 {"path", path + "/" + std::to_string(i)}
14121 }));
14122 ++i;
14123 }
14124
14125 // add other remaining elements
14126 while (i < target.size())
14127 {
14128 result.push_back(
14129 {
14130 {"op", "add"},
14131 {"path", path + "/" + std::to_string(i)},
14132 {"value", target[i]}
14133 });
14134 ++i;
14135 }
14136
14137 break;
14138 }
14139
14140 case value_t::object:
14141 {
14142 // first pass: traverse this object's elements
14143 for (auto it = source.begin(); it != source.end(); ++it)
14144 {
14145 // escape the key name to be used in a JSON patch
14146 const auto key = json_pointer::escape(it.key());
14147
14148 if (target.find(it.key()) != target.end())
14149 {
14150 // recursive call to compare object values at key it
14151 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
14152 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
14153 }
14154 else
14155 {
14156 // found a key that is not in o -> remove it
14157 result.push_back(object(
14158 {
14159 {"op", "remove"}, {"path", path + "/" + key}
14160 }));
14161 }
14162 }
14163
14164 // second pass: traverse other object's elements
14165 for (auto it = target.begin(); it != target.end(); ++it)
14166 {
14167 if (source.find(it.key()) == source.end())
14168 {
14169 // found a key that is not in this -> add it
14170 const auto key = json_pointer::escape(it.key());
14171 result.push_back(
14172 {
14173 {"op", "add"}, {"path", path + "/" + key},
14174 {"value", it.value()}
14175 });
14176 }
14177 }
14178
14179 break;
14180 }
14181
14182 default:
14183 {
14184 // both primitive type: replace value
14185 result.push_back(
14186 {
14187 {"op", "replace"}, {"path", path}, {"value", target}
14188 });
14189 break;
14190 }
14191 }
14192 }
14193
14194 return result;
14195 }
14196
14197 /// @}
14198 };
14199
14200 /////////////
14201 // presets //
14202 /////////////
14203
14204 /*!
14205 @brief default JSON class
14206
14207 This type is the default specialization of the @ref basic_json class which
14208 uses the standard template types.
14209
14210 @since version 1.0.0
14211 */
14212 using json = basic_json<>;
14213
14214 //////////////////
14215 // json_pointer //
14216 //////////////////
14217
14218 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14219 NLOHMANN_BASIC_JSON_TPL&
get_and_create(NLOHMANN_BASIC_JSON_TPL & j) const14220 json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
14221 {
14222 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
14223 auto result = &j;
14224
14225 // in case no reference tokens exist, return a reference to the JSON value
14226 // j which will be overwritten by a primitive value
14227 for (const auto& reference_token : reference_tokens)
14228 {
14229 switch (result->m_type)
14230 {
14231 case detail::value_t::null:
14232 {
14233 if (reference_token == "0")
14234 {
14235 // start a new array if reference token is 0
14236 result = &result->operator[](0);
14237 }
14238 else
14239 {
14240 // start a new object otherwise
14241 result = &result->operator[](reference_token);
14242 }
14243 break;
14244 }
14245
14246 case detail::value_t::object:
14247 {
14248 // create an entry in the object
14249 result = &result->operator[](reference_token);
14250 break;
14251 }
14252
14253 case detail::value_t::array:
14254 {
14255 // create an entry in the array
14256 JSON_TRY
14257 {
14258 result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
14259 }
14260 JSON_CATCH(std::invalid_argument&)
14261 {
14262 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
14263 }
14264 break;
14265 }
14266
14267 /*
14268 The following code is only reached if there exists a reference
14269 token _and_ the current value is primitive. In this case, we have
14270 an error situation, because primitive values may only occur as
14271 single value; that is, with an empty list of reference tokens.
14272 */
14273 default:
14274 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
14275 }
14276 }
14277
14278 return *result;
14279 }
14280
14281 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14282 NLOHMANN_BASIC_JSON_TPL&
get_unchecked(NLOHMANN_BASIC_JSON_TPL * ptr) const14283 json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
14284 {
14285 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
14286 for (const auto& reference_token : reference_tokens)
14287 {
14288 // convert null values to arrays or objects before continuing
14289 if (ptr->m_type == detail::value_t::null)
14290 {
14291 // check if reference token is a number
14292 const bool nums =
14293 std::all_of(reference_token.begin(), reference_token.end(),
14294 [](const char x)
14295 {
14296 return (x >= '0' and x <= '9');
14297 });
14298
14299 // change value to array for numbers or "-" or to object otherwise
14300 *ptr = (nums or reference_token == "-")
14301 ? detail::value_t::array
14302 : detail::value_t::object;
14303 }
14304
14305 switch (ptr->m_type)
14306 {
14307 case detail::value_t::object:
14308 {
14309 // use unchecked object access
14310 ptr = &ptr->operator[](reference_token);
14311 break;
14312 }
14313
14314 case detail::value_t::array:
14315 {
14316 // error condition (cf. RFC 6901, Sect. 4)
14317 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
14318 {
14319 JSON_THROW(detail::parse_error::create(106, 0,
14320 "array index '" + reference_token +
14321 "' must not begin with '0'"));
14322 }
14323
14324 if (reference_token == "-")
14325 {
14326 // explicitly treat "-" as index beyond the end
14327 ptr = &ptr->operator[](ptr->m_value.array->size());
14328 }
14329 else
14330 {
14331 // convert array index to number; unchecked access
14332 JSON_TRY
14333 {
14334 ptr = &ptr->operator[](
14335 static_cast<size_type>(std::stoi(reference_token)));
14336 }
14337 JSON_CATCH(std::invalid_argument&)
14338 {
14339 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
14340 }
14341 }
14342 break;
14343 }
14344
14345 default:
14346 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
14347 }
14348 }
14349
14350 return *ptr;
14351 }
14352
14353 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14354 NLOHMANN_BASIC_JSON_TPL&
get_checked(NLOHMANN_BASIC_JSON_TPL * ptr) const14355 json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
14356 {
14357 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
14358 for (const auto& reference_token : reference_tokens)
14359 {
14360 switch (ptr->m_type)
14361 {
14362 case detail::value_t::object:
14363 {
14364 // note: at performs range check
14365 ptr = &ptr->at(reference_token);
14366 break;
14367 }
14368
14369 case detail::value_t::array:
14370 {
14371 if (JSON_UNLIKELY(reference_token == "-"))
14372 {
14373 // "-" always fails the range check
14374 JSON_THROW(detail::out_of_range::create(402,
14375 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14376 ") is out of range"));
14377 }
14378
14379 // error condition (cf. RFC 6901, Sect. 4)
14380 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
14381 {
14382 JSON_THROW(detail::parse_error::create(106, 0,
14383 "array index '" + reference_token +
14384 "' must not begin with '0'"));
14385 }
14386
14387 // note: at performs range check
14388 JSON_TRY
14389 {
14390 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
14391 }
14392 JSON_CATCH(std::invalid_argument&)
14393 {
14394 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
14395 }
14396 break;
14397 }
14398
14399 default:
14400 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
14401 }
14402 }
14403
14404 return *ptr;
14405 }
14406
14407 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14408 const NLOHMANN_BASIC_JSON_TPL&
get_unchecked(const NLOHMANN_BASIC_JSON_TPL * ptr) const14409 json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
14410 {
14411 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
14412 for (const auto& reference_token : reference_tokens)
14413 {
14414 switch (ptr->m_type)
14415 {
14416 case detail::value_t::object:
14417 {
14418 // use unchecked object access
14419 ptr = &ptr->operator[](reference_token);
14420 break;
14421 }
14422
14423 case detail::value_t::array:
14424 {
14425 if (JSON_UNLIKELY(reference_token == "-"))
14426 {
14427 // "-" cannot be used for const access
14428 JSON_THROW(detail::out_of_range::create(402,
14429 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14430 ") is out of range"));
14431 }
14432
14433 // error condition (cf. RFC 6901, Sect. 4)
14434 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
14435 {
14436 JSON_THROW(detail::parse_error::create(106, 0,
14437 "array index '" + reference_token +
14438 "' must not begin with '0'"));
14439 }
14440
14441 // use unchecked array access
14442 JSON_TRY
14443 {
14444 ptr = &ptr->operator[](
14445 static_cast<size_type>(std::stoi(reference_token)));
14446 }
14447 JSON_CATCH(std::invalid_argument&)
14448 {
14449 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
14450 }
14451 break;
14452 }
14453
14454 default:
14455 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
14456 }
14457 }
14458
14459 return *ptr;
14460 }
14461
14462 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14463 const NLOHMANN_BASIC_JSON_TPL&
get_checked(const NLOHMANN_BASIC_JSON_TPL * ptr) const14464 json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
14465 {
14466 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
14467 for (const auto& reference_token : reference_tokens)
14468 {
14469 switch (ptr->m_type)
14470 {
14471 case detail::value_t::object:
14472 {
14473 // note: at performs range check
14474 ptr = &ptr->at(reference_token);
14475 break;
14476 }
14477
14478 case detail::value_t::array:
14479 {
14480 if (JSON_UNLIKELY(reference_token == "-"))
14481 {
14482 // "-" always fails the range check
14483 JSON_THROW(detail::out_of_range::create(402,
14484 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
14485 ") is out of range"));
14486 }
14487
14488 // error condition (cf. RFC 6901, Sect. 4)
14489 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
14490 {
14491 JSON_THROW(detail::parse_error::create(106, 0,
14492 "array index '" + reference_token +
14493 "' must not begin with '0'"));
14494 }
14495
14496 // note: at performs range check
14497 JSON_TRY
14498 {
14499 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
14500 }
14501 JSON_CATCH(std::invalid_argument&)
14502 {
14503 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
14504 }
14505 break;
14506 }
14507
14508 default:
14509 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
14510 }
14511 }
14512
14513 return *ptr;
14514 }
14515
14516 NLOHMANN_BASIC_JSON_TPL_DECLARATION
flatten(const std::string & reference_string,const NLOHMANN_BASIC_JSON_TPL & value,NLOHMANN_BASIC_JSON_TPL & result)14517 void json_pointer::flatten(const std::string& reference_string,
14518 const NLOHMANN_BASIC_JSON_TPL& value,
14519 NLOHMANN_BASIC_JSON_TPL& result)
14520 {
14521 switch (value.m_type)
14522 {
14523 case detail::value_t::array:
14524 {
14525 if (value.m_value.array->empty())
14526 {
14527 // flatten empty array as null
14528 result[reference_string] = nullptr;
14529 }
14530 else
14531 {
14532 // iterate array and use index as reference string
14533 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
14534 {
14535 flatten(reference_string + "/" + std::to_string(i),
14536 value.m_value.array->operator[](i), result);
14537 }
14538 }
14539 break;
14540 }
14541
14542 case detail::value_t::object:
14543 {
14544 if (value.m_value.object->empty())
14545 {
14546 // flatten empty object as null
14547 result[reference_string] = nullptr;
14548 }
14549 else
14550 {
14551 // iterate object and use keys as reference string
14552 for (const auto& element : *value.m_value.object)
14553 {
14554 flatten(reference_string + "/" + escape(element.first), element.second, result);
14555 }
14556 }
14557 break;
14558 }
14559
14560 default:
14561 {
14562 // add primitive value with its reference string
14563 result[reference_string] = value;
14564 break;
14565 }
14566 }
14567 }
14568
14569 NLOHMANN_BASIC_JSON_TPL_DECLARATION
14570 NLOHMANN_BASIC_JSON_TPL
unflatten(const NLOHMANN_BASIC_JSON_TPL & value)14571 json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
14572 {
14573 if (JSON_UNLIKELY(not value.is_object()))
14574 {
14575 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
14576 }
14577
14578 NLOHMANN_BASIC_JSON_TPL result;
14579
14580 // iterate the JSON object values
14581 for (const auto& element : *value.m_value.object)
14582 {
14583 if (JSON_UNLIKELY(not element.second.is_primitive()))
14584 {
14585 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
14586 }
14587
14588 // assign value to reference pointed to by JSON pointer; Note that if
14589 // the JSON pointer is "" (i.e., points to the whole value), function
14590 // get_and_create returns a reference to result itself. An assignment
14591 // will then create a primitive value.
14592 json_pointer(element.first).get_and_create(result) = element.second;
14593 }
14594
14595 return result;
14596 }
14597
operator ==(json_pointer const & lhs,json_pointer const & rhs)14598 inline bool operator==(json_pointer const& lhs, json_pointer const& rhs) noexcept
14599 {
14600 return (lhs.reference_tokens == rhs.reference_tokens);
14601 }
14602
operator !=(json_pointer const & lhs,json_pointer const & rhs)14603 inline bool operator!=(json_pointer const& lhs, json_pointer const& rhs) noexcept
14604 {
14605 return not (lhs == rhs);
14606 }
14607 } // namespace nlohmann
14608
14609
14610 ///////////////////////
14611 // nonmember support //
14612 ///////////////////////
14613
14614 // specialization of std::swap, and std::hash
14615 namespace std
14616 {
14617 /*!
14618 @brief exchanges the values of two JSON objects
14619
14620 @since version 1.0.0
14621 */
14622 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)14623 inline void swap(nlohmann::json& j1,
14624 nlohmann::json& j2) noexcept(
14625 is_nothrow_move_constructible<nlohmann::json>::value and
14626 is_nothrow_move_assignable<nlohmann::json>::value
14627 )
14628 {
14629 j1.swap(j2);
14630 }
14631
14632 /// hash value for JSON objects
14633 template<>
14634 struct hash<nlohmann::json>
14635 {
14636 /*!
14637 @brief return a hash value for a JSON object
14638
14639 @since version 1.0.0
14640 */
operator ()std::hash14641 std::size_t operator()(const nlohmann::json& j) const
14642 {
14643 // a naive hashing via the string representation
14644 const auto& h = hash<nlohmann::json::string_t>();
14645 return h(j.dump());
14646 }
14647 };
14648
14649 /// specialization for std::less<value_t>
14650 /// @note: do not remove the space after '<',
14651 /// see https://github.com/nlohmann/json/pull/679
14652 template<>
14653 struct less< ::nlohmann::detail::value_t>
14654 {
14655 /*!
14656 @brief compare two value_t enum values
14657 @since version 3.0.0
14658 */
operator ()std::less14659 bool operator()(nlohmann::detail::value_t lhs,
14660 nlohmann::detail::value_t rhs) const noexcept
14661 {
14662 return nlohmann::detail::operator<(lhs, rhs);
14663 }
14664 };
14665
14666 } // namespace std
14667
14668 /*!
14669 @brief user-defined string literal for JSON values
14670
14671 This operator implements a user-defined string literal for JSON objects. It
14672 can be used by adding `"_json"` to a string literal and returns a JSON object
14673 if no parse error occurred.
14674
14675 @param[in] s a string representation of a JSON object
14676 @param[in] n the length of string @a s
14677 @return a JSON object
14678
14679 @since version 1.0.0
14680 */
operator ""_json(const char * s,std::size_t n)14681 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
14682 {
14683 return nlohmann::json::parse(s, s + n);
14684 }
14685
14686 /*!
14687 @brief user-defined string literal for JSON pointer
14688
14689 This operator implements a user-defined string literal for JSON Pointers. It
14690 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
14691 object if no parse error occurred.
14692
14693 @param[in] s a string representation of a JSON Pointer
14694 @param[in] n the length of string @a s
14695 @return a JSON pointer object
14696
14697 @since version 2.0.0
14698 */
operator ""_json_pointer(const char * s,std::size_t n)14699 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
14700 {
14701 return nlohmann::json::json_pointer(std::string(s, n));
14702 }
14703
14704 // restore GCC/clang diagnostic settings
14705 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
14706 #pragma GCC diagnostic pop
14707 #endif
14708 #if defined(__clang__)
14709 #pragma GCC diagnostic pop
14710 #endif
14711
14712 // clean up
14713 #undef JSON_CATCH
14714 #undef JSON_THROW
14715 #undef JSON_TRY
14716 #undef JSON_LIKELY
14717 #undef JSON_UNLIKELY
14718 #undef JSON_DEPRECATED
14719 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
14720 #undef NLOHMANN_BASIC_JSON_TPL
14721
14722 #endif
14723