1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 2.1.1
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
7 Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24
25 #ifndef NLOHMANN_JSON_HPP
26 #define NLOHMANN_JSON_HPP
27
28 #include <algorithm> // all_of, copy, fill, find, for_each, generate_n, none_of, remove, reverse, transform
29 #include <array> // array
30 #include <cassert> // assert
31 #include <ciso646> // and, not, or
32 #include <clocale> // lconv, localeconv
33 #include <cmath> // isfinite, labs, ldexp, signbit
34 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
35 #include <cstdint> // int64_t, uint64_t
36 #include <cstdlib> // abort, strtod, strtof, strtold, strtoul, strtoll, strtoull
37 #include <cstring> // memcpy, strlen
38 #include <forward_list> // forward_list
39 #include <functional> // function, hash, less
40 #include <initializer_list> // initializer_list
41 #include <iomanip> // hex
42 #include <iosfwd> // istream, ostream
43 #include <iterator> // advance, begin, back_inserter, bidirectional_iterator_tag, distance, end, inserter, iterator, iterator_traits, next, random_access_iterator_tag, reverse_iterator
44 #include <limits> // numeric_limits
45 #include <locale> // locale
46 #include <map> // map
47 #include <memory> // addressof, allocator, allocator_traits, unique_ptr
48 #include <numeric> // accumulate
49 #include <sstream> // stringstream
50 #include <string> // getline, stoi, string, to_string
51 #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
52 #include <utility> // declval, forward, make_pair, move, pair, swap
53 #include <valarray> // valarray
54 #include <vector> // vector
55
56 // exclude unsupported compilers
57 #if defined(__clang__)
58 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
59 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
60 #endif
61 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
62 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40900
63 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
64 #endif
65 #endif
66
67 // disable float-equal warnings on GCC/clang
68 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
69 #pragma GCC diagnostic push
70 #pragma GCC diagnostic ignored "-Wfloat-equal"
71 #endif
72
73 // disable documentation warnings on clang
74 #if defined(__clang__)
75 #pragma GCC diagnostic push
76 #pragma GCC diagnostic ignored "-Wdocumentation"
77 #endif
78
79 // allow for portable deprecation warnings
80 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
81 #define JSON_DEPRECATED __attribute__((deprecated))
82 #elif defined(_MSC_VER)
83 #define JSON_DEPRECATED __declspec(deprecated)
84 #else
85 #define JSON_DEPRECATED
86 #endif
87
88 // allow to disable exceptions
89 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(JSON_NOEXCEPTION)
90 #define JSON_THROW(exception) throw exception
91 #define JSON_TRY try
92 #define JSON_CATCH(exception) catch(exception)
93 #else
94 #define JSON_THROW(exception) std::abort()
95 #define JSON_TRY if(true)
96 #define JSON_CATCH(exception) if(false)
97 #endif
98
99 // manual branch prediction
100 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
101 #define JSON_LIKELY(x) __builtin_expect(!!(x), 1)
102 #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
103 #else
104 #define JSON_LIKELY(x) x
105 #define JSON_UNLIKELY(x) x
106 #endif
107
108 // cpp language standard detection
109 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
110 #define JSON_HAS_CPP_17
111 #define JSON_HAS_CPP_14
112 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
113 #define JSON_HAS_CPP_14
114 #endif
115
116 /*!
117 @brief namespace for Niels Lohmann
118 @see https://github.com/nlohmann
119 @since version 1.0.0
120 */
121 namespace nlohmann
122 {
123 template<typename = void, typename = void>
124 struct adl_serializer;
125
126 // forward declaration of basic_json (required to split the class)
127 template<template<typename U, typename V, typename... Args> class ObjectType =
128 std::map,
129 template<typename U, typename... Args> class ArrayType = std::vector,
130 class StringType = std::string, class BooleanType = bool,
131 class NumberIntegerType = std::int64_t,
132 class NumberUnsignedType = std::uint64_t,
133 class NumberFloatType = double,
134 template<typename U> class AllocatorType = std::allocator,
135 template<typename T, typename SFINAE = void> class JSONSerializer =
136 adl_serializer>
137 class basic_json;
138
139 // Ugly macros to avoid uglier copy-paste when specializing basic_json
140 // This is only temporary and will be removed in 3.0
141
142 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
143 template<template<typename, typename, typename...> class ObjectType, \
144 template<typename, typename...> class ArrayType, \
145 class StringType, class BooleanType, class NumberIntegerType, \
146 class NumberUnsignedType, class NumberFloatType, \
147 template<typename> class AllocatorType, \
148 template<typename, typename = void> class JSONSerializer>
149
150 #define NLOHMANN_BASIC_JSON_TPL \
151 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
152 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
153 AllocatorType, JSONSerializer>
154
155
156 /*!
157 @brief unnamed namespace with internal helper functions
158 This namespace collects some functions that could not be defined inside the
159 @ref basic_json class.
160 @since version 2.1.0
161 */
162 namespace detail
163 {
164 ////////////////
165 // exceptions //
166 ////////////////
167
168 /*!
169 @brief general exception of the @ref basic_json class
170 This class is an extension of `std::exception` objects with a member @a id for
171 exception ids. It is used as the base class for all exceptions thrown by the
172 @ref basic_json class. This class can hence be used as "wildcard" to catch
173 exceptions.
174 Subclasses:
175 - @ref parse_error for exceptions indicating a parse error
176 - @ref invalid_iterator for exceptions indicating errors with iterators
177 - @ref type_error for exceptions indicating executing a member function with
178 a wrong type
179 - @ref out_of_range for exceptions indicating access out of the defined range
180 - @ref other_error for exceptions indicating other library errors
181 @internal
182 @note To have nothrow-copy-constructible exceptions, we internally use
183 `std::runtime_error` which can cope with arbitrary-length error messages.
184 Intermediate strings are built with static functions and then passed to
185 the actual constructor.
186 @endinternal
187 @liveexample{The following code shows how arbitrary library exceptions can be
188 caught.,exception}
189 @since version 3.0.0
190 */
191 class exception : public std::exception
192 {
193 public:
194 /// returns the explanatory string
what() const195 const char* what() const noexcept override
196 {
197 return m.what();
198 }
199
200 /// the id of the exception
201 const int id;
202
203 protected:
exception(int id_,const char * what_arg)204 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
205
name(const std::string & ename,int id_)206 static std::string name(const std::string& ename, int id_)
207 {
208 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
209 }
210
211 private:
212 /// an exception object as storage for error messages
213 std::runtime_error m;
214 };
215
216 /*!
217 @brief exception indicating a parse error
218 This excpetion is thrown by the library when a parse error occurs. Parse errors
219 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
220 as when using JSON Patch.
221 Member @a byte holds the byte index of the last read character in the input
222 file.
223 Exceptions have ids 1xx.
224 name / id | example message | description
225 ------------------------------ | --------------- | -------------------------
226 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.
227 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.
228 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.
229 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.
230 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.
231 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`.
232 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.
233 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.
234 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
235 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.
236 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.
237 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.
238 @note For an input with n bytes, 1 is the index of the first character and n+1
239 is the index of the terminating null byte or the end of file. This also
240 holds true when reading a byte vector (CBOR or MessagePack).
241 @liveexample{The following code shows how a `parse_error` exception can be
242 caught.,parse_error}
243 @sa @ref exception for the base class of the library exceptions
244 @sa @ref invalid_iterator for exceptions indicating errors with iterators
245 @sa @ref type_error for exceptions indicating executing a member function with
246 a wrong type
247 @sa @ref out_of_range for exceptions indicating access out of the defined range
248 @sa @ref other_error for exceptions indicating other library errors
249 @since version 3.0.0
250 */
251 class parse_error : public exception
252 {
253 public:
254 /*!
255 @brief create a parse error exception
256 @param[in] id_ the id of the exception
257 @param[in] byte_ the byte index where the error occurred (or 0 if the
258 position cannot be determined)
259 @param[in] what_arg the explanatory string
260 @return parse_error object
261 */
create(int id_,std::size_t byte_,const std::string & what_arg)262 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg)
263 {
264 std::string w = exception::name("parse_error", id_) + "parse error" +
265 (byte_ != 0 ? (" at " + std::to_string(byte_)) : "") +
266 ": " + what_arg;
267 return parse_error(id_, byte_, w.c_str());
268 }
269
270 /*!
271 @brief byte index of the parse error
272 The byte index of the last read character in the input file.
273 @note For an input with n bytes, 1 is the index of the first character and
274 n+1 is the index of the terminating null byte or the end of file.
275 This also holds true when reading a byte vector (CBOR or MessagePack).
276 */
277 const std::size_t byte;
278
279 private:
parse_error(int id_,std::size_t byte_,const char * what_arg)280 parse_error(int id_, std::size_t byte_, const char* what_arg)
281 : exception(id_, what_arg), byte(byte_) {}
282 };
283
284 /*!
285 @brief exception indicating errors with iterators
286 This exception is thrown if iterators passed to a library function do not match
287 the expected semantics.
288 Exceptions have ids 2xx.
289 name / id | example message | description
290 ----------------------------------- | --------------- | -------------------------
291 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.
292 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.
293 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.
294 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.
295 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.
296 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.
297 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.
298 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.
299 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.
300 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.
301 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.
302 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
303 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
304 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().
305 @liveexample{The following code shows how an `invalid_iterator` exception can be
306 caught.,invalid_iterator}
307 @sa @ref exception for the base class of the library exceptions
308 @sa @ref parse_error for exceptions indicating a parse error
309 @sa @ref type_error for exceptions indicating executing a member function with
310 a wrong type
311 @sa @ref out_of_range for exceptions indicating access out of the defined range
312 @sa @ref other_error for exceptions indicating other library errors
313 @since version 3.0.0
314 */
315 class invalid_iterator : public exception
316 {
317 public:
create(int id_,const std::string & what_arg)318 static invalid_iterator create(int id_, const std::string& what_arg)
319 {
320 std::string w = exception::name("invalid_iterator", id_) + what_arg;
321 return invalid_iterator(id_, w.c_str());
322 }
323
324 private:
invalid_iterator(int id_,const char * what_arg)325 invalid_iterator(int id_, const char* what_arg)
326 : exception(id_, what_arg) {}
327 };
328
329 /*!
330 @brief exception indicating executing a member function with a wrong type
331 This exception is thrown in case of a type error; that is, a library function is
332 executed on a JSON value whose type does not match the expected semantics.
333 Exceptions have ids 3xx.
334 name / id | example message | description
335 ----------------------------- | --------------- | -------------------------
336 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.
337 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.
338 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&.
339 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
340 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
341 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
342 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
343 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.
344 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
345 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
346 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.
347 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
348 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.
349 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
350 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.
351 @liveexample{The following code shows how a `type_error` exception can be
352 caught.,type_error}
353 @sa @ref exception for the base class of the library exceptions
354 @sa @ref parse_error for exceptions indicating a parse error
355 @sa @ref invalid_iterator for exceptions indicating errors with iterators
356 @sa @ref out_of_range for exceptions indicating access out of the defined range
357 @sa @ref other_error for exceptions indicating other library errors
358 @since version 3.0.0
359 */
360 class type_error : public exception
361 {
362 public:
create(int id_,const std::string & what_arg)363 static type_error create(int id_, const std::string& what_arg)
364 {
365 std::string w = exception::name("type_error", id_) + what_arg;
366 return type_error(id_, w.c_str());
367 }
368
369 private:
type_error(int id_,const char * what_arg)370 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
371 };
372
373 /*!
374 @brief exception indicating access out of the defined range
375 This exception is thrown in case a library function is called on an input
376 parameter that exceeds the expected range, for instance in case of array
377 indices or nonexisting object keys.
378 Exceptions have ids 4xx.
379 name / id | example message | description
380 ------------------------------- | --------------- | -------------------------
381 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.
382 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.
383 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
384 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
385 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.
386 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.
387 @liveexample{The following code shows how an `out_of_range` exception can be
388 caught.,out_of_range}
389 @sa @ref exception for the base class of the library exceptions
390 @sa @ref parse_error for exceptions indicating a parse error
391 @sa @ref invalid_iterator for exceptions indicating errors with iterators
392 @sa @ref type_error for exceptions indicating executing a member function with
393 a wrong type
394 @sa @ref other_error for exceptions indicating other library errors
395 @since version 3.0.0
396 */
397 class out_of_range : public exception
398 {
399 public:
create(int id_,const std::string & what_arg)400 static out_of_range create(int id_, const std::string& what_arg)
401 {
402 std::string w = exception::name("out_of_range", id_) + what_arg;
403 return out_of_range(id_, w.c_str());
404 }
405
406 private:
out_of_range(int id_,const char * what_arg)407 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
408 };
409
410 /*!
411 @brief exception indicating other library errors
412 This exception is thrown in case of errors that cannot be classified with the
413 other exception types.
414 Exceptions have ids 5xx.
415 name / id | example message | description
416 ------------------------------ | --------------- | -------------------------
417 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
418 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)
419 @sa @ref exception for the base class of the library exceptions
420 @sa @ref parse_error for exceptions indicating a parse error
421 @sa @ref invalid_iterator for exceptions indicating errors with iterators
422 @sa @ref type_error for exceptions indicating executing a member function with
423 a wrong type
424 @sa @ref out_of_range for exceptions indicating access out of the defined range
425 @liveexample{The following code shows how an `other_error` exception can be
426 caught.,other_error}
427 @since version 3.0.0
428 */
429 class other_error : public exception
430 {
431 public:
create(int id_,const std::string & what_arg)432 static other_error create(int id_, const std::string& what_arg)
433 {
434 std::string w = exception::name("other_error", id_) + what_arg;
435 return other_error(id_, w.c_str());
436 }
437
438 private:
other_error(int id_,const char * what_arg)439 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
440 };
441
442
443
444 ///////////////////////////
445 // JSON type enumeration //
446 ///////////////////////////
447
448 /*!
449 @brief the JSON type enumeration
450 This enumeration collects the different JSON types. It is internally used to
451 distinguish the stored values, and the functions @ref basic_json::is_null(),
452 @ref basic_json::is_object(), @ref basic_json::is_array(),
453 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
454 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
455 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
456 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
457 @ref basic_json::is_structured() rely on it.
458 @note There are three enumeration entries (number_integer, number_unsigned, and
459 number_float), because the library distinguishes these three types for numbers:
460 @ref basic_json::number_unsigned_t is used for unsigned integers,
461 @ref basic_json::number_integer_t is used for signed integers, and
462 @ref basic_json::number_float_t is used for floating-point numbers or to
463 approximate integers which do not fit in the limits of their respective type.
464 @sa @ref basic_json::basic_json(const value_t value_type) -- create a JSON
465 value with the default value for a given type
466 @since version 1.0.0
467 */
468 enum class value_t : uint8_t
469 {
470 null, ///< null value
471 object, ///< object (unordered set of name/value pairs)
472 array, ///< array (ordered collection of values)
473 string, ///< string value
474 boolean, ///< boolean value
475 number_integer, ///< number value (signed integer)
476 number_unsigned, ///< number value (unsigned integer)
477 number_float, ///< number value (floating-point)
478 discarded ///< discarded by the the parser callback function
479 };
480
481 /*!
482 @brief comparison operator for JSON types
483 Returns an ordering that is similar to Python:
484 - order: null < boolean < number < object < array < string
485 - furthermore, each type is not smaller than itself
486 @since version 1.0.0
487 */
operator <(const value_t lhs,const value_t rhs)488 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
489 {
490 static constexpr std::array<uint8_t, 8> order = {{
491 0, // null
492 3, // object
493 4, // array
494 5, // string
495 1, // boolean
496 2, // integer
497 2, // unsigned
498 2, // float
499 }
500 };
501
502 // discarded values are not comparable
503 return lhs != value_t::discarded and rhs != value_t::discarded and
504 order[static_cast<std::size_t>(lhs)] < order[static_cast<std::size_t>(rhs)];
505 }
506
507
508 /////////////
509 // helpers //
510 /////////////
511
512 template<typename> struct is_basic_json : std::false_type {};
513
514 NLOHMANN_BASIC_JSON_TPL_DECLARATION
515 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
516
517 // alias templates to reduce boilerplate
518 template<bool B, typename T = void>
519 using enable_if_t = typename std::enable_if<B, T>::type;
520
521 template<typename T>
522 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
523
524 // implementation of C++14 index_sequence and affiliates
525 // source: https://stackoverflow.com/a/32223343
526 template<std::size_t... Ints>
527 struct index_sequence
528 {
529 using type = index_sequence;
530 using value_type = std::size_t;
sizenlohmann::detail::index_sequence531 static constexpr std::size_t size() noexcept
532 {
533 return sizeof...(Ints);
534 }
535 };
536
537 template<class Sequence1, class Sequence2>
538 struct merge_and_renumber;
539
540 template<std::size_t... I1, std::size_t... I2>
541 struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
542 : index_sequence < I1..., (sizeof...(I1) + I2)... >
543 {};
544
545 template<std::size_t N>
546 struct make_index_sequence
547 : merge_and_renumber < typename make_index_sequence < N / 2 >::type,
548 typename make_index_sequence < N - N / 2 >::type >
549 {};
550
551 template<> struct make_index_sequence<0> : index_sequence<> { };
552 template<> struct make_index_sequence<1> : index_sequence<0> { };
553
554 template<typename... Ts>
555 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
556
557 /*
558 Implementation of two C++17 constructs: conjunction, negation. This is needed
559 to avoid evaluating all the traits in a condition
560 For example: not std::is_same<void, T>::value and has_value_type<T>::value
561 will not compile when T = void (on MSVC at least). Whereas
562 conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
563 stop evaluating if negation<...>::value == false
564 Please note that those constructs must be used with caution, since symbols can
565 become very long quickly (which can slow down compilation and cause MSVC
566 internal compiler errors). Only use it when you have to (see example ahead).
567 */
568 template<class...> struct conjunction : std::true_type {};
569 template<class B1> struct conjunction<B1> : B1 {};
570 template<class B1, class... Bn>
571 struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
572
573 template<class B> struct negation : std::integral_constant < bool, !B::value > {};
574
575 // dispatch utility (taken from ranges-v3)
576 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
577 template<> struct priority_tag<0> {};
578
579
580 //////////////////
581 // constructors //
582 //////////////////
583
584 template<value_t> struct external_constructor;
585
586 template<>
587 struct external_constructor<value_t::boolean>
588 {
589 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor590 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
591 {
592 j.m_type = value_t::boolean;
593 j.m_value = b;
594 j.assert_invariant();
595 }
596 };
597
598 template<>
599 struct external_constructor<value_t::string>
600 {
601 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor602 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
603 {
604 j.m_type = value_t::string;
605 j.m_value = s;
606 j.assert_invariant();
607 }
608
609 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor610 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
611 {
612 j.m_type = value_t::string;
613 j.m_value = std::move(s);
614 j.assert_invariant();
615 }
616 };
617
618 template<>
619 struct external_constructor<value_t::number_float>
620 {
621 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor622 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
623 {
624 j.m_type = value_t::number_float;
625 j.m_value = val;
626 j.assert_invariant();
627 }
628 };
629
630 template<>
631 struct external_constructor<value_t::number_unsigned>
632 {
633 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor634 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
635 {
636 j.m_type = value_t::number_unsigned;
637 j.m_value = val;
638 j.assert_invariant();
639 }
640 };
641
642 template<>
643 struct external_constructor<value_t::number_integer>
644 {
645 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor646 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
647 {
648 j.m_type = value_t::number_integer;
649 j.m_value = val;
650 j.assert_invariant();
651 }
652 };
653
654 template<>
655 struct external_constructor<value_t::array>
656 {
657 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor658 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
659 {
660 j.m_type = value_t::array;
661 j.m_value = arr;
662 j.assert_invariant();
663 }
664
665 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor666 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
667 {
668 j.m_type = value_t::array;
669 j.m_value = std::move(arr);
670 j.assert_invariant();
671 }
672
673 template<typename BasicJsonType, typename CompatibleArrayType,
674 enable_if_t<not std::is_same<CompatibleArrayType,
675 typename BasicJsonType::array_t>::value,
676 int> = 0>
constructnlohmann::detail::external_constructor677 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
678 {
679 using std::begin;
680 using std::end;
681 j.m_type = value_t::array;
682 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
683 j.assert_invariant();
684 }
685
686 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor687 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
688 {
689 j.m_type = value_t::array;
690 j.m_value = value_t::array;
691 j.m_value.array->reserve(arr.size());
692 for (bool x : arr)
693 {
694 j.m_value.array->push_back(x);
695 }
696 j.assert_invariant();
697 }
698
699 template<typename BasicJsonType, typename T,
700 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor701 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
702 {
703 j.m_type = value_t::array;
704 j.m_value = value_t::array;
705 j.m_value.array->resize(arr.size());
706 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
707 j.assert_invariant();
708 }
709 };
710
711 template<>
712 struct external_constructor<value_t::object>
713 {
714 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor715 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
716 {
717 j.m_type = value_t::object;
718 j.m_value = obj;
719 j.assert_invariant();
720 }
721
722 template<typename BasicJsonType>
constructnlohmann::detail::external_constructor723 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
724 {
725 j.m_type = value_t::object;
726 j.m_value = std::move(obj);
727 j.assert_invariant();
728 }
729
730 template<typename BasicJsonType, typename CompatibleObjectType,
731 enable_if_t<not std::is_same<CompatibleObjectType,
732 typename BasicJsonType::object_t>::value, int> = 0>
constructnlohmann::detail::external_constructor733 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
734 {
735 using std::begin;
736 using std::end;
737
738 j.m_type = value_t::object;
739 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
740 j.assert_invariant();
741 }
742 };
743
744
745 ////////////////////////
746 // has_/is_ functions //
747 ////////////////////////
748
749 /*!
750 @brief Helper to determine whether there's a key_type for T.
751 This helper is used to tell associative containers apart from other containers
752 such as sequence containers. For instance, `std::map` passes the test as it
753 contains a `mapped_type`, whereas `std::vector` fails the test.
754 @sa http://stackoverflow.com/a/7728728/266378
755 @since version 1.0.0, overworked in version 2.0.6
756 */
757 #define NLOHMANN_JSON_HAS_HELPER(type) \
758 template<typename T> struct has_##type { \
759 private: \
760 template<typename U, typename = typename U::type> \
761 static int detect(U &&); \
762 static void detect(...); \
763 public: \
764 static constexpr bool value = \
765 std::is_integral<decltype(detect(std::declval<T>()))>::value; \
766 }
767
768 NLOHMANN_JSON_HAS_HELPER(mapped_type);
769 NLOHMANN_JSON_HAS_HELPER(key_type);
770 NLOHMANN_JSON_HAS_HELPER(value_type);
771 NLOHMANN_JSON_HAS_HELPER(iterator);
772
773 #undef NLOHMANN_JSON_HAS_HELPER
774
775
776 template<bool B, class RealType, class CompatibleObjectType>
777 struct is_compatible_object_type_impl : std::false_type {};
778
779 template<class RealType, class CompatibleObjectType>
780 struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
781 {
782 static constexpr auto value =
783 std::is_constructible<typename RealType::key_type, typename CompatibleObjectType::key_type>::value and
784 std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
785 };
786
787 template<class BasicJsonType, class CompatibleObjectType>
788 struct is_compatible_object_type
789 {
790 static auto constexpr value = is_compatible_object_type_impl <
791 conjunction<negation<std::is_same<void, CompatibleObjectType>>,
792 has_mapped_type<CompatibleObjectType>,
793 has_key_type<CompatibleObjectType>>::value,
794 typename BasicJsonType::object_t, CompatibleObjectType >::value;
795 };
796
797 template<typename BasicJsonType, typename T>
798 struct is_basic_json_nested_type
799 {
800 static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
801 std::is_same<T, typename BasicJsonType::const_iterator>::value or
802 std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
803 std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
804 };
805
806 template<class BasicJsonType, class CompatibleArrayType>
807 struct is_compatible_array_type
808 {
809 static auto constexpr value =
810 conjunction<negation<std::is_same<void, CompatibleArrayType>>,
811 negation<is_compatible_object_type<
812 BasicJsonType, CompatibleArrayType>>,
813 negation<std::is_constructible<typename BasicJsonType::string_t,
814 CompatibleArrayType>>,
815 negation<is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>>,
816 has_value_type<CompatibleArrayType>,
817 has_iterator<CompatibleArrayType>>::value;
818 };
819
820 template<bool, typename, typename>
821 struct is_compatible_integer_type_impl : std::false_type {};
822
823 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
824 struct is_compatible_integer_type_impl<true, RealIntegerType, CompatibleNumberIntegerType>
825 {
826 // is there an assert somewhere on overflows?
827 using RealLimits = std::numeric_limits<RealIntegerType>;
828 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
829
830 static constexpr auto value =
831 std::is_constructible<RealIntegerType, CompatibleNumberIntegerType>::value and
832 CompatibleLimits::is_integer and
833 RealLimits::is_signed == CompatibleLimits::is_signed;
834 };
835
836 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
837 struct is_compatible_integer_type
838 {
839 static constexpr auto value =
840 is_compatible_integer_type_impl <
841 std::is_integral<CompatibleNumberIntegerType>::value and
842 not std::is_same<bool, CompatibleNumberIntegerType>::value,
843 RealIntegerType, CompatibleNumberIntegerType > ::value;
844 };
845
846
847 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
848 template<typename BasicJsonType, typename T>
849 struct has_from_json
850 {
851 private:
852 // also check the return type of from_json
853 template<typename U, typename = enable_if_t<std::is_same<void, decltype(uncvref_t<U>::from_json(
854 std::declval<BasicJsonType>(), std::declval<T&>()))>::value>>
855 static int detect(U&&);
856 static void detect(...);
857
858 public:
859 static constexpr bool value = std::is_integral<decltype(
860 detect(std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
861 };
862
863 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
864 // this overload is used for non-default-constructible user-defined-types
865 template<typename BasicJsonType, typename T>
866 struct has_non_default_from_json
867 {
868 private:
869 template <
870 typename U,
871 typename = enable_if_t<std::is_same<
872 T, decltype(uncvref_t<U>::from_json(std::declval<BasicJsonType>()))>::value >>
873 static int detect(U&&);
874 static void detect(...);
875
876 public:
877 static constexpr bool value = std::is_integral<decltype(detect(
878 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
879 };
880
881 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
882 template<typename BasicJsonType, typename T>
883 struct has_to_json
884 {
885 private:
886 template<typename U, typename = decltype(uncvref_t<U>::to_json(
887 std::declval<BasicJsonType&>(), std::declval<T>()))>
888 static int detect(U&&);
889 static void detect(...);
890
891 public:
892 static constexpr bool value = std::is_integral<decltype(detect(
893 std::declval<typename BasicJsonType::template json_serializer<T, void>>()))>::value;
894 };
895
896
897 /////////////
898 // to_json //
899 /////////////
900
901 template<typename BasicJsonType, typename T, enable_if_t<
902 std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)903 void to_json(BasicJsonType& j, T b) noexcept
904 {
905 external_constructor<value_t::boolean>::construct(j, b);
906 }
907
908 template<typename BasicJsonType, typename CompatibleString,
909 enable_if_t<std::is_constructible<typename BasicJsonType::string_t,
910 CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)911 void to_json(BasicJsonType& j, const CompatibleString& s)
912 {
913 external_constructor<value_t::string>::construct(j, s);
914 }
915
916 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)917 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
918 {
919 external_constructor<value_t::string>::construct(j, std::move(s));
920 }
921
922 template<typename BasicJsonType, typename FloatType,
923 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)924 void to_json(BasicJsonType& j, FloatType val) noexcept
925 {
926 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
927 }
928
929 template <
930 typename BasicJsonType, typename CompatibleNumberUnsignedType,
931 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t,
932 CompatibleNumberUnsignedType>::value, int> = 0 >
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)933 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
934 {
935 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
936 }
937
938 template <
939 typename BasicJsonType, typename CompatibleNumberIntegerType,
940 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t,
941 CompatibleNumberIntegerType>::value, int> = 0 >
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)942 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
943 {
944 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
945 }
946
947 template<typename BasicJsonType, typename EnumType,
948 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)949 void to_json(BasicJsonType& j, EnumType e) noexcept
950 {
951 using underlying_type = typename std::underlying_type<EnumType>::type;
952 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
953 }
954
955 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)956 void to_json(BasicJsonType& j, const std::vector<bool>& e)
957 {
958 external_constructor<value_t::array>::construct(j, e);
959 }
960
961 template <
962 typename BasicJsonType, typename CompatibleArrayType,
963 enable_if_t <
964 is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value or
965 std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value,
966 int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)967 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
968 {
969 external_constructor<value_t::array>::construct(j, arr);
970 }
971
972 template <typename BasicJsonType, typename T,
973 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,std::valarray<T> arr)974 void to_json(BasicJsonType& j, std::valarray<T> arr)
975 {
976 external_constructor<value_t::array>::construct(j, std::move(arr));
977 }
978
979 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)980 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
981 {
982 external_constructor<value_t::array>::construct(j, std::move(arr));
983 }
984
985 template <
986 typename BasicJsonType, typename CompatibleObjectType,
987 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value,
988 int> = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)989 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
990 {
991 external_constructor<value_t::object>::construct(j, obj);
992 }
993
994 template <typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)995 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
996 {
997 external_constructor<value_t::object>::construct(j, std::move(obj));
998 }
999
1000 template<typename BasicJsonType, typename T, std::size_t N,
1001 enable_if_t<not std::is_constructible<
1002 typename BasicJsonType::string_t, T (&)[N]>::value,
1003 int> = 0>
to_json(BasicJsonType & j,T (& arr)[N])1004 void to_json(BasicJsonType& j, T (&arr)[N])
1005 {
1006 external_constructor<value_t::array>::construct(j, arr);
1007 }
1008
1009 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::pair<Args...> & p)1010 void to_json(BasicJsonType& j, const std::pair<Args...>& p)
1011 {
1012 j = {p.first, p.second};
1013 }
1014
1015 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)1016 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...>)
1017 {
1018 j = {std::get<Idx>(t)...};
1019 }
1020
1021 template<typename BasicJsonType, typename... Args>
to_json(BasicJsonType & j,const std::tuple<Args...> & t)1022 void to_json(BasicJsonType& j, const std::tuple<Args...>& t)
1023 {
1024 to_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1025 }
1026
1027 ///////////////
1028 // from_json //
1029 ///////////////
1030
1031 // overloads for basic_json template parameters
1032 template<typename BasicJsonType, typename ArithmeticType,
1033 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
1034 not std::is_same<ArithmeticType,
1035 typename BasicJsonType::boolean_t>::value,
1036 int> = 0>
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)1037 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
1038 {
1039 switch (static_cast<value_t>(j))
1040 {
1041 case value_t::number_unsigned:
1042 {
1043 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1044 break;
1045 }
1046 case value_t::number_integer:
1047 {
1048 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1049 break;
1050 }
1051 case value_t::number_float:
1052 {
1053 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1054 break;
1055 }
1056
1057 default:
1058 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1059 }
1060 }
1061
1062 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)1063 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
1064 {
1065 if (JSON_UNLIKELY(not j.is_boolean()))
1066 {
1067 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name())));
1068 }
1069 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
1070 }
1071
1072 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)1073 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
1074 {
1075 if (JSON_UNLIKELY(not j.is_string()))
1076 {
1077 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name())));
1078 }
1079 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
1080 }
1081
1082 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)1083 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
1084 {
1085 get_arithmetic_value(j, val);
1086 }
1087
1088 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)1089 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
1090 {
1091 get_arithmetic_value(j, val);
1092 }
1093
1094 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)1095 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
1096 {
1097 get_arithmetic_value(j, val);
1098 }
1099
1100 template<typename BasicJsonType, typename EnumType,
1101 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)1102 void from_json(const BasicJsonType& j, EnumType& e)
1103 {
1104 typename std::underlying_type<EnumType>::type val;
1105 get_arithmetic_value(j, val);
1106 e = static_cast<EnumType>(val);
1107 }
1108
1109 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::array_t & arr)1110 void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
1111 {
1112 if (JSON_UNLIKELY(not j.is_array()))
1113 {
1114 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1115 }
1116 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
1117 }
1118
1119 // forward_list doesn't have an insert method
1120 template<typename BasicJsonType, typename T, typename Allocator,
1121 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)1122 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
1123 {
1124 if (JSON_UNLIKELY(not j.is_array()))
1125 {
1126 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1127 }
1128 std::transform(j.rbegin(), j.rend(),
1129 std::front_inserter(l), [](const BasicJsonType & i)
1130 {
1131 return i.template get<T>();
1132 });
1133 }
1134
1135 // valarray doesn't have an insert method
1136 template<typename BasicJsonType, typename T,
1137 enable_if_t<std::is_convertible<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)1138 void from_json(const BasicJsonType& j, std::valarray<T>& l)
1139 {
1140 if (JSON_UNLIKELY(not j.is_array()))
1141 {
1142 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
1143 }
1144 l.resize(j.size());
1145 std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
1146 }
1147
1148 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<0>)1149 void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0> /*unused*/)
1150 {
1151 using std::end;
1152
1153 std::transform(j.begin(), j.end(),
1154 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1155 {
1156 // get<BasicJsonType>() returns *this, this won't call a from_json
1157 // method when value_type is BasicJsonType
1158 return i.template get<typename CompatibleArrayType::value_type>();
1159 });
1160 }
1161
1162 template<typename BasicJsonType, typename CompatibleArrayType>
from_json_array_impl(const BasicJsonType & j,CompatibleArrayType & arr,priority_tag<1>)1163 auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1> /*unused*/)
1164 -> decltype(
1165 arr.reserve(std::declval<typename CompatibleArrayType::size_type>()),
1166 void())
1167 {
1168 using std::end;
1169
1170 arr.reserve(j.size());
1171 std::transform(j.begin(), j.end(),
1172 std::inserter(arr, end(arr)), [](const BasicJsonType & i)
1173 {
1174 // get<BasicJsonType>() returns *this, this won't call a from_json
1175 // method when value_type is BasicJsonType
1176 return i.template get<typename CompatibleArrayType::value_type>();
1177 });
1178 }
1179
1180 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)1181 void from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr, priority_tag<2> /*unused*/)
1182 {
1183 for (std::size_t i = 0; i < N; ++i)
1184 {
1185 arr[i] = j.at(i).template get<T>();
1186 }
1187 }
1188
1189 template<typename BasicJsonType, typename CompatibleArrayType,
1190 enable_if_t<is_compatible_array_type<BasicJsonType, CompatibleArrayType>::value and
1191 std::is_convertible<BasicJsonType, typename CompatibleArrayType::value_type>::value and
1192 not std::is_same<typename BasicJsonType::array_t, CompatibleArrayType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleArrayType & arr)1193 void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
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
1200 from_json_array_impl(j, arr, priority_tag<2> {});
1201 }
1202
1203 template<typename BasicJsonType, typename CompatibleObjectType,
1204 enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,CompatibleObjectType & obj)1205 void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
1206 {
1207 if (JSON_UNLIKELY(not j.is_object()))
1208 {
1209 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
1210 }
1211
1212 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
1213 using value_type = typename CompatibleObjectType::value_type;
1214 std::transform(
1215 inner_object->begin(), inner_object->end(),
1216 std::inserter(obj, obj.begin()),
1217 [](typename BasicJsonType::object_t::value_type const & p)
1218 {
1219 return value_type(p.first, p.second.template get<typename CompatibleObjectType::mapped_type>());
1220 });
1221 }
1222
1223 // overload for arithmetic types, not chosen for basic_json template arguments
1224 // (BooleanType, etc..); note: Is it really necessary to provide explicit
1225 // overloads for boolean_t etc. in case of a custom BooleanType which is not
1226 // an arithmetic type?
1227 template<typename BasicJsonType, typename ArithmeticType,
1228 enable_if_t <
1229 std::is_arithmetic<ArithmeticType>::value and
1230 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
1231 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
1232 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
1233 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
1234 int> = 0>
from_json(const BasicJsonType & j,ArithmeticType & val)1235 void from_json(const BasicJsonType& j, ArithmeticType& val)
1236 {
1237 switch (static_cast<value_t>(j))
1238 {
1239 case value_t::number_unsigned:
1240 {
1241 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
1242 break;
1243 }
1244 case value_t::number_integer:
1245 {
1246 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
1247 break;
1248 }
1249 case value_t::number_float:
1250 {
1251 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
1252 break;
1253 }
1254 case value_t::boolean:
1255 {
1256 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
1257 break;
1258 }
1259
1260 default:
1261 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name())));
1262 }
1263 }
1264
1265 template<typename BasicJsonType, typename A1, typename A2>
from_json(const BasicJsonType & j,std::pair<A1,A2> & p)1266 void from_json(const BasicJsonType& j, std::pair<A1, A2>& p)
1267 {
1268 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
1269 }
1270
1271 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
from_json_tuple_impl(const BasicJsonType & j,Tuple & t,index_sequence<Idx...>)1272 void from_json_tuple_impl(const BasicJsonType& j, Tuple& t, index_sequence<Idx...>)
1273 {
1274 t = std::make_tuple(j.at(Idx).template get<typename std::tuple_element<Idx, Tuple>::type>()...);
1275 }
1276
1277 template<typename BasicJsonType, typename... Args>
from_json(const BasicJsonType & j,std::tuple<Args...> & t)1278 void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
1279 {
1280 from_json_tuple_impl(j, t, index_sequence_for<Args...> {});
1281 }
1282
1283 struct to_json_fn
1284 {
1285 private:
1286 template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1287 auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
1288 -> decltype(to_json(j, std::forward<T>(val)), void())
1289 {
1290 return to_json(j, std::forward<T>(val));
1291 }
1292
1293 template<typename BasicJsonType, typename T>
callnlohmann::detail::to_json_fn1294 void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1295 {
1296 static_assert(sizeof(BasicJsonType) == 0,
1297 "could not find to_json() method in T's namespace");
1298 }
1299
1300 public:
1301 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn1302 void operator()(BasicJsonType& j, T&& val) const
1303 noexcept(noexcept(std::declval<to_json_fn>().call(j, std::forward<T>(val), priority_tag<1> {})))
1304 {
1305 return call(j, std::forward<T>(val), priority_tag<1> {});
1306 }
1307 };
1308
1309 struct from_json_fn
1310 {
1311 private:
1312 template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1313 auto call(const BasicJsonType& j, T& val, priority_tag<1> /*unused*/) const
1314 noexcept(noexcept(from_json(j, val)))
1315 -> decltype(from_json(j, val), void())
1316 {
1317 return from_json(j, val);
1318 }
1319
1320 template<typename BasicJsonType, typename T>
callnlohmann::detail::from_json_fn1321 void call(const BasicJsonType& /*unused*/, T& /*unused*/, priority_tag<0> /*unused*/) const noexcept
1322 {
1323 static_assert(sizeof(BasicJsonType) == 0,
1324 "could not find from_json() method in T's namespace");
1325 }
1326
1327 public:
1328 template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn1329 void operator()(const BasicJsonType& j, T& val) const
1330 noexcept(noexcept(std::declval<from_json_fn>().call(j, val, priority_tag<1> {})))
1331 {
1332 return call(j, val, priority_tag<1> {});
1333 }
1334 };
1335
1336 // taken from ranges-v3
1337 template<typename T>
1338 struct static_const
1339 {
1340 static constexpr T value{};
1341 };
1342
1343 template<typename T>
1344 constexpr T static_const<T>::value;
1345
1346 ////////////////////
1347 // input adapters //
1348 ////////////////////
1349
1350 /*!
1351 @brief abstract input adapter interface
1352 Produces a stream of std::char_traits<char>::int_type characters from a
1353 std::istream, a buffer, or some other input type. Accepts the return of exactly
1354 one non-EOF character for future input. The int_type characters returned
1355 consist of all valid char values as positive values (typically unsigned char),
1356 plus an EOF value outside that range, specified by the value of the function
1357 std::char_traits<char>::eof(). This value is typically -1, but could be any
1358 arbitrary value which is not a valid char value.
1359 */
1360 struct input_adapter_protocol
1361 {
1362 /// get a character [0,255] or std::char_traits<char>::eof().
1363 virtual std::char_traits<char>::int_type get_character() = 0;
1364 /// restore the last non-eof() character to input
1365 virtual void unget_character() = 0;
1366 virtual ~input_adapter_protocol() = default;
1367 };
1368
1369 /// a type to simplify interfaces
1370 using input_adapter_t = std::shared_ptr<input_adapter_protocol>;
1371
1372 /*!
1373 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
1374 beginning of input. Does not support changing the underlying std::streambuf
1375 in mid-input. Maintains underlying std::istream and std::streambuf to support
1376 subsequent use of standard std::istream operations to process any input
1377 characters following those used in parsing the JSON input. Clears the
1378 std::istream flags; any input errors (e.g., EOF) will be detected by the first
1379 subsequent call for input from the std::istream.
1380 */
1381 class input_stream_adapter : public input_adapter_protocol
1382 {
1383 public:
~input_stream_adapter()1384 ~input_stream_adapter() override
1385 {
1386 // clear stream flags; we use underlying streambuf I/O, do not
1387 // maintain ifstream flags
1388 is.clear();
1389 }
1390
input_stream_adapter(std::istream & i)1391 explicit input_stream_adapter(std::istream& i)
1392 : is(i), sb(*i.rdbuf())
1393 {
1394 // ignore Byte Order Mark at start of input
1395 std::char_traits<char>::int_type c;
1396 if ((c = get_character()) == 0xEF)
1397 {
1398 if ((c = get_character()) == 0xBB)
1399 {
1400 if ((c = get_character()) == 0xBF)
1401 {
1402 return; // Ignore BOM
1403 }
1404 else if (c != std::char_traits<char>::eof())
1405 {
1406 is.unget();
1407 }
1408 is.putback('\xBB');
1409 }
1410 else if (c != std::char_traits<char>::eof())
1411 {
1412 is.unget();
1413 }
1414 is.putback('\xEF');
1415 }
1416 else if (c != std::char_traits<char>::eof())
1417 {
1418 is.unget(); // Not BOM. Process as usual.
1419 }
1420 }
1421
1422 // delete because of pointer members
1423 input_stream_adapter(const input_stream_adapter&) = delete;
1424 input_stream_adapter& operator=(input_stream_adapter&) = delete;
1425
1426 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
1427 // ensure that std::char_traits<char>::eof() and the character 0xff do not
1428 // end up as the same value, eg. 0xffffffff.
get_character()1429 std::char_traits<char>::int_type get_character() override
1430 {
1431 return sb.sbumpc();
1432 }
1433
unget_character()1434 void unget_character() override
1435 {
1436 sb.sungetc(); // is.unget() avoided for performance
1437 }
1438
1439 private:
1440 /// the associated input stream
1441 std::istream& is;
1442 std::streambuf& sb;
1443 };
1444
1445 /// input adapter for buffer input
1446 class input_buffer_adapter : public input_adapter_protocol
1447 {
1448 public:
input_buffer_adapter(const char * b,const std::size_t l)1449 input_buffer_adapter(const char* b, const std::size_t l)
1450 : cursor(b), limit(b + l), start(b)
1451 {
1452 // skip byte order mark
1453 if (l >= 3 and b[0] == '\xEF' and b[1] == '\xBB' and b[2] == '\xBF')
1454 {
1455 cursor += 3;
1456 }
1457 }
1458
1459 // delete because of pointer members
1460 input_buffer_adapter(const input_buffer_adapter&) = delete;
1461 input_buffer_adapter& operator=(input_buffer_adapter&) = delete;
1462
get_character()1463 std::char_traits<char>::int_type get_character() noexcept override
1464 {
1465 if (JSON_LIKELY(cursor < limit))
1466 {
1467 return std::char_traits<char>::to_int_type(*(cursor++));
1468 }
1469
1470 return std::char_traits<char>::eof();
1471 }
1472
unget_character()1473 void unget_character() noexcept override
1474 {
1475 if (JSON_LIKELY(cursor > start))
1476 {
1477 --cursor;
1478 }
1479 }
1480
1481 private:
1482 /// pointer to the current character
1483 const char* cursor;
1484 /// pointer past the last character
1485 const char* limit;
1486 /// pointer to the first character
1487 const char* start;
1488 };
1489
1490 class input_adapter
1491 {
1492 public:
1493 // native support
1494
1495 /// input adapter for input stream
input_adapter(std::istream & i)1496 input_adapter(std::istream& i)
1497 : ia(std::make_shared<input_stream_adapter>(i)) {}
1498
1499 /// input adapter for input stream
input_adapter(std::istream && i)1500 input_adapter(std::istream&& i)
1501 : ia(std::make_shared<input_stream_adapter>(i)) {}
1502
1503 /// input adapter for buffer
1504 template<typename CharT,
1505 typename std::enable_if<
1506 std::is_pointer<CharT>::value and
1507 std::is_integral<
1508 typename std::remove_pointer<CharT>::type>::value and
1509 sizeof(typename std::remove_pointer<CharT>::type) == 1,
1510 int>::type = 0>
input_adapter(CharT b,std::size_t l)1511 input_adapter(CharT b, std::size_t l)
1512 : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
1513
1514 // derived support
1515
1516 /// input adapter for string literal
1517 template<typename CharT,
1518 typename std::enable_if<
1519 std::is_pointer<CharT>::value and
1520 std::is_integral<
1521 typename std::remove_pointer<CharT>::type>::value and
1522 sizeof(typename std::remove_pointer<CharT>::type) == 1,
1523 int>::type = 0>
input_adapter(CharT b)1524 input_adapter(CharT b)
1525 : input_adapter(reinterpret_cast<const char*>(b),
1526 std::strlen(reinterpret_cast<const char*>(b))) {}
1527
1528 /// input adapter for iterator range with contiguous storage
1529 template<class IteratorType,
1530 typename std::enable_if<
1531 std::is_same<typename std::iterator_traits<IteratorType>::iterator_category,
1532 std::random_access_iterator_tag>::value,
1533 int>::type = 0>
input_adapter(IteratorType first,IteratorType last)1534 input_adapter(IteratorType first, IteratorType last)
1535 {
1536 // assertion to check that the iterator range is indeed contiguous,
1537 // see http://stackoverflow.com/a/35008842/266378 for more discussion
1538 assert(std::accumulate(
1539 first, last, std::pair<bool, int>(true, 0),
1540 [&first](std::pair<bool, int> res, decltype(*first) val)
1541 {
1542 res.first &= (val == *(std::next(std::addressof(*first), res.second++)));
1543 return res;
1544 }).first);
1545
1546 // assertion to check that each element is 1 byte long
1547 static_assert(
1548 sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1,
1549 "each element in the iterator range must have the size of 1 byte");
1550
1551 const auto len = static_cast<size_t>(std::distance(first, last));
1552 if (JSON_LIKELY(len > 0))
1553 {
1554 // there is at least one element: use the address of first
1555 ia = std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(&(*first)), len);
1556 }
1557 else
1558 {
1559 // the address of first cannot be used: use nullptr
1560 ia = std::make_shared<input_buffer_adapter>(nullptr, len);
1561 }
1562 }
1563
1564 /// input adapter for array
1565 template<class T, std::size_t N>
input_adapter(T (& array)[N])1566 input_adapter(T (&array)[N])
1567 : input_adapter(std::begin(array), std::end(array)) {}
1568
1569 /// input adapter for contiguous container
1570 template <
1571 class ContiguousContainer,
1572 typename std::enable_if <
1573 not std::is_pointer<ContiguousContainer>::value and
1574 std::is_base_of<std::random_access_iterator_tag,
1575 typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value,
1576 int >::type = 0 >
input_adapter(const ContiguousContainer & c)1577 input_adapter(const ContiguousContainer& c)
1578 : input_adapter(std::begin(c), std::end(c)) {}
1579
operator input_adapter_t()1580 operator input_adapter_t()
1581 {
1582 return ia;
1583 }
1584
1585 private:
1586 /// the actual adapter
1587 input_adapter_t ia = nullptr;
1588 };
1589
1590 //////////////////////
1591 // lexer and parser //
1592 //////////////////////
1593
1594 /*!
1595 @brief lexical analysis
1596 This class organizes the lexical analysis during JSON deserialization.
1597 */
1598 template<typename BasicJsonType>
1599 class lexer
1600 {
1601 using number_integer_t = typename BasicJsonType::number_integer_t;
1602 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
1603 using number_float_t = typename BasicJsonType::number_float_t;
1604
1605 public:
1606 /// token types for the parser
1607 enum class token_type
1608 {
1609 uninitialized, ///< indicating the scanner is uninitialized
1610 literal_true, ///< the `true` literal
1611 literal_false, ///< the `false` literal
1612 literal_null, ///< the `null` literal
1613 value_string, ///< a string -- use get_string() for actual value
1614 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
1615 value_integer, ///< a signed integer -- use get_number_integer() for actual value
1616 value_float, ///< an floating point number -- use get_number_float() for actual value
1617 begin_array, ///< the character for array begin `[`
1618 begin_object, ///< the character for object begin `{`
1619 end_array, ///< the character for array end `]`
1620 end_object, ///< the character for object end `}`
1621 name_separator, ///< the name separator `:`
1622 value_separator, ///< the value separator `,`
1623 parse_error, ///< indicating a parse error
1624 end_of_input, ///< indicating the end of the input buffer
1625 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
1626 };
1627
1628 /// return name of values of type token_type (only used for errors)
token_type_name(const token_type t)1629 static const char* token_type_name(const token_type t) noexcept
1630 {
1631 switch (t)
1632 {
1633 case token_type::uninitialized:
1634 return "<uninitialized>";
1635 case token_type::literal_true:
1636 return "true literal";
1637 case token_type::literal_false:
1638 return "false literal";
1639 case token_type::literal_null:
1640 return "null literal";
1641 case token_type::value_string:
1642 return "string literal";
1643 case lexer::token_type::value_unsigned:
1644 case lexer::token_type::value_integer:
1645 case lexer::token_type::value_float:
1646 return "number literal";
1647 case token_type::begin_array:
1648 return "'['";
1649 case token_type::begin_object:
1650 return "'{'";
1651 case token_type::end_array:
1652 return "']'";
1653 case token_type::end_object:
1654 return "'}'";
1655 case token_type::name_separator:
1656 return "':'";
1657 case token_type::value_separator:
1658 return "','";
1659 case token_type::parse_error:
1660 return "<parse error>";
1661 case token_type::end_of_input:
1662 return "end of input";
1663 case token_type::literal_or_value:
1664 return "'[', '{', or a literal";
1665 default: // catch non-enum values
1666 return "unknown token"; // LCOV_EXCL_LINE
1667 }
1668 }
1669
lexer(detail::input_adapter_t adapter)1670 explicit lexer(detail::input_adapter_t adapter)
1671 : ia(std::move(adapter)), decimal_point_char(get_decimal_point()) {}
1672
1673 // delete because of pointer members
1674 lexer(const lexer&) = delete;
1675 lexer& operator=(lexer&) = delete;
1676
1677 private:
1678 /////////////////////
1679 // locales
1680 /////////////////////
1681
1682 /// return the locale-dependent decimal point
get_decimal_point()1683 static char get_decimal_point() noexcept
1684 {
1685 const auto loc = localeconv();
1686 assert(loc != nullptr);
1687 return (loc->decimal_point == nullptr) ? '.' : loc->decimal_point[0];
1688 }
1689
1690 /////////////////////
1691 // scan functions
1692 /////////////////////
1693
1694 /*!
1695 @brief get codepoint from 4 hex characters following `\u`
1696 For input "\u c1 c2 c3 c4" the codepoint is:
1697 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
1698 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
1699 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
1700 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
1701 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
1702 between the ASCII value of the character and the desired integer value.
1703 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
1704 non-hex character)
1705 */
get_codepoint()1706 int get_codepoint()
1707 {
1708 // this function only makes sense after reading `\u`
1709 assert(current == 'u');
1710 int codepoint = 0;
1711
1712 const auto factors = { 12, 8, 4, 0 };
1713 for (const auto factor : factors)
1714 {
1715 get();
1716
1717 if (current >= '0' and current <= '9')
1718 {
1719 codepoint += ((current - 0x30) << factor);
1720 }
1721 else if (current >= 'A' and current <= 'F')
1722 {
1723 codepoint += ((current - 0x37) << factor);
1724 }
1725 else if (current >= 'a' and current <= 'f')
1726 {
1727 codepoint += ((current - 0x57) << factor);
1728 }
1729 else
1730 {
1731 return -1;
1732 }
1733 }
1734
1735 assert(0x0000 <= codepoint and codepoint <= 0xFFFF);
1736 return codepoint;
1737 }
1738
1739 /*!
1740 @brief check if the next byte(s) are inside a given range
1741 Adds the current byte and, for each passed range, reads a new byte and
1742 checks if it is inside the range. If a violation was detected, set up an
1743 error message and return false. Otherwise, return true.
1744 @return true if and only if no range violation was detected
1745 */
next_byte_in_range(std::initializer_list<int> ranges)1746 bool next_byte_in_range(std::initializer_list<int> ranges)
1747 {
1748 assert(ranges.size() == 2 or ranges.size() == 4 or ranges.size() == 6);
1749 add(current);
1750
1751 for (auto range = ranges.begin(); range != ranges.end(); ++range)
1752 {
1753 get();
1754 if (JSON_LIKELY(*range <= current and current <= *(++range)))
1755 {
1756 add(current);
1757 }
1758 else
1759 {
1760 error_message = "invalid string: ill-formed UTF-8 byte";
1761 return false;
1762 }
1763 }
1764
1765 return true;
1766 }
1767
1768 /*!
1769 @brief scan a string literal
1770 This function scans a string according to Sect. 7 of RFC 7159. While
1771 scanning, bytes are escaped and copied into buffer yytext. Then the function
1772 returns successfully, yytext is *not* null-terminated (as it may contain \0
1773 bytes), and yytext.size() is the number of bytes in the string.
1774 @return token_type::value_string if string could be successfully scanned,
1775 token_type::parse_error otherwise
1776 @note In case of errors, variable error_message contains a textual
1777 description.
1778 */
scan_string()1779 token_type scan_string()
1780 {
1781 // reset yytext (ignore opening quote)
1782 reset();
1783
1784 // we entered the function by reading an open quote
1785 assert(current == '\"');
1786
1787 while (true)
1788 {
1789 // get next character
1790 switch (get())
1791 {
1792 // end of file while parsing string
1793 case std::char_traits<char>::eof():
1794 {
1795 error_message = "invalid string: missing closing quote";
1796 return token_type::parse_error;
1797 }
1798
1799 // closing quote
1800 case '\"':
1801 {
1802 return token_type::value_string;
1803 }
1804
1805 // escapes
1806 case '\\':
1807 {
1808 switch (get())
1809 {
1810 // quotation mark
1811 case '\"':
1812 add('\"');
1813 break;
1814 // reverse solidus
1815 case '\\':
1816 add('\\');
1817 break;
1818 // solidus
1819 case '/':
1820 add('/');
1821 break;
1822 // backspace
1823 case 'b':
1824 add('\b');
1825 break;
1826 // form feed
1827 case 'f':
1828 add('\f');
1829 break;
1830 // line feed
1831 case 'n':
1832 add('\n');
1833 break;
1834 // carriage return
1835 case 'r':
1836 add('\r');
1837 break;
1838 // tab
1839 case 't':
1840 add('\t');
1841 break;
1842
1843 // unicode escapes
1844 case 'u':
1845 {
1846 int codepoint;
1847 const int codepoint1 = get_codepoint();
1848
1849 if (JSON_UNLIKELY(codepoint1 == -1))
1850 {
1851 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
1852 return token_type::parse_error;
1853 }
1854
1855 // check if code point is a high surrogate
1856 if (0xD800 <= codepoint1 and codepoint1 <= 0xDBFF)
1857 {
1858 // expect next \uxxxx entry
1859 if (JSON_LIKELY(get() == '\\' and get() == 'u'))
1860 {
1861 const int codepoint2 = get_codepoint();
1862
1863 if (JSON_UNLIKELY(codepoint2 == -1))
1864 {
1865 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
1866 return token_type::parse_error;
1867 }
1868
1869 // check if codepoint2 is a low surrogate
1870 if (JSON_LIKELY(0xDC00 <= codepoint2 and codepoint2 <= 0xDFFF))
1871 {
1872 codepoint =
1873 // high surrogate occupies the most significant 22 bits
1874 (codepoint1 << 10)
1875 // low surrogate occupies the least significant 15 bits
1876 + codepoint2
1877 // there is still the 0xD800, 0xDC00 and 0x10000 noise
1878 // in the result so we have to subtract with:
1879 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
1880 - 0x35FDC00;
1881 }
1882 else
1883 {
1884 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1885 return token_type::parse_error;
1886 }
1887 }
1888 else
1889 {
1890 error_message = "invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF";
1891 return token_type::parse_error;
1892 }
1893 }
1894 else
1895 {
1896 if (JSON_UNLIKELY(0xDC00 <= codepoint1 and codepoint1 <= 0xDFFF))
1897 {
1898 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
1899 return token_type::parse_error;
1900 }
1901
1902 // only work with first code point
1903 codepoint = codepoint1;
1904 }
1905
1906 // result of the above calculation yields a proper codepoint
1907 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
1908
1909 // translate code point to bytes
1910 if (codepoint < 0x80)
1911 {
1912 // 1-byte characters: 0xxxxxxx (ASCII)
1913 add(codepoint);
1914 }
1915 else if (codepoint <= 0x7ff)
1916 {
1917 // 2-byte characters: 110xxxxx 10xxxxxx
1918 add(0xC0 | (codepoint >> 6));
1919 add(0x80 | (codepoint & 0x3F));
1920 }
1921 else if (codepoint <= 0xffff)
1922 {
1923 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
1924 add(0xE0 | (codepoint >> 12));
1925 add(0x80 | ((codepoint >> 6) & 0x3F));
1926 add(0x80 | (codepoint & 0x3F));
1927 }
1928 else
1929 {
1930 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1931 add(0xF0 | (codepoint >> 18));
1932 add(0x80 | ((codepoint >> 12) & 0x3F));
1933 add(0x80 | ((codepoint >> 6) & 0x3F));
1934 add(0x80 | (codepoint & 0x3F));
1935 }
1936
1937 break;
1938 }
1939
1940 // other characters after escape
1941 default:
1942 error_message = "invalid string: forbidden character after backslash";
1943 return token_type::parse_error;
1944 }
1945
1946 break;
1947 }
1948
1949 // invalid control characters
1950 case 0x00:
1951 case 0x01:
1952 case 0x02:
1953 case 0x03:
1954 case 0x04:
1955 case 0x05:
1956 case 0x06:
1957 case 0x07:
1958 case 0x08:
1959 case 0x09:
1960 case 0x0a:
1961 case 0x0b:
1962 case 0x0c:
1963 case 0x0d:
1964 case 0x0e:
1965 case 0x0f:
1966 case 0x10:
1967 case 0x11:
1968 case 0x12:
1969 case 0x13:
1970 case 0x14:
1971 case 0x15:
1972 case 0x16:
1973 case 0x17:
1974 case 0x18:
1975 case 0x19:
1976 case 0x1a:
1977 case 0x1b:
1978 case 0x1c:
1979 case 0x1d:
1980 case 0x1e:
1981 case 0x1f:
1982 {
1983 error_message = "invalid string: control character must be escaped";
1984 return token_type::parse_error;
1985 }
1986
1987 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
1988 case 0x20:
1989 case 0x21:
1990 case 0x23:
1991 case 0x24:
1992 case 0x25:
1993 case 0x26:
1994 case 0x27:
1995 case 0x28:
1996 case 0x29:
1997 case 0x2a:
1998 case 0x2b:
1999 case 0x2c:
2000 case 0x2d:
2001 case 0x2e:
2002 case 0x2f:
2003 case 0x30:
2004 case 0x31:
2005 case 0x32:
2006 case 0x33:
2007 case 0x34:
2008 case 0x35:
2009 case 0x36:
2010 case 0x37:
2011 case 0x38:
2012 case 0x39:
2013 case 0x3a:
2014 case 0x3b:
2015 case 0x3c:
2016 case 0x3d:
2017 case 0x3e:
2018 case 0x3f:
2019 case 0x40:
2020 case 0x41:
2021 case 0x42:
2022 case 0x43:
2023 case 0x44:
2024 case 0x45:
2025 case 0x46:
2026 case 0x47:
2027 case 0x48:
2028 case 0x49:
2029 case 0x4a:
2030 case 0x4b:
2031 case 0x4c:
2032 case 0x4d:
2033 case 0x4e:
2034 case 0x4f:
2035 case 0x50:
2036 case 0x51:
2037 case 0x52:
2038 case 0x53:
2039 case 0x54:
2040 case 0x55:
2041 case 0x56:
2042 case 0x57:
2043 case 0x58:
2044 case 0x59:
2045 case 0x5a:
2046 case 0x5b:
2047 case 0x5d:
2048 case 0x5e:
2049 case 0x5f:
2050 case 0x60:
2051 case 0x61:
2052 case 0x62:
2053 case 0x63:
2054 case 0x64:
2055 case 0x65:
2056 case 0x66:
2057 case 0x67:
2058 case 0x68:
2059 case 0x69:
2060 case 0x6a:
2061 case 0x6b:
2062 case 0x6c:
2063 case 0x6d:
2064 case 0x6e:
2065 case 0x6f:
2066 case 0x70:
2067 case 0x71:
2068 case 0x72:
2069 case 0x73:
2070 case 0x74:
2071 case 0x75:
2072 case 0x76:
2073 case 0x77:
2074 case 0x78:
2075 case 0x79:
2076 case 0x7a:
2077 case 0x7b:
2078 case 0x7c:
2079 case 0x7d:
2080 case 0x7e:
2081 case 0x7f:
2082 {
2083 add(current);
2084 break;
2085 }
2086
2087 // U+0080..U+07FF: bytes C2..DF 80..BF
2088 case 0xc2:
2089 case 0xc3:
2090 case 0xc4:
2091 case 0xc5:
2092 case 0xc6:
2093 case 0xc7:
2094 case 0xc8:
2095 case 0xc9:
2096 case 0xca:
2097 case 0xcb:
2098 case 0xcc:
2099 case 0xcd:
2100 case 0xce:
2101 case 0xcf:
2102 case 0xd0:
2103 case 0xd1:
2104 case 0xd2:
2105 case 0xd3:
2106 case 0xd4:
2107 case 0xd5:
2108 case 0xd6:
2109 case 0xd7:
2110 case 0xd8:
2111 case 0xd9:
2112 case 0xda:
2113 case 0xdb:
2114 case 0xdc:
2115 case 0xdd:
2116 case 0xde:
2117 case 0xdf:
2118 {
2119 if (JSON_UNLIKELY(not next_byte_in_range({0x80, 0xBF})))
2120 {
2121 return token_type::parse_error;
2122 }
2123 break;
2124 }
2125
2126 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
2127 case 0xe0:
2128 {
2129 if (JSON_UNLIKELY(not (next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
2130 {
2131 return token_type::parse_error;
2132 }
2133 break;
2134 }
2135
2136 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
2137 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
2138 case 0xe1:
2139 case 0xe2:
2140 case 0xe3:
2141 case 0xe4:
2142 case 0xe5:
2143 case 0xe6:
2144 case 0xe7:
2145 case 0xe8:
2146 case 0xe9:
2147 case 0xea:
2148 case 0xeb:
2149 case 0xec:
2150 case 0xee:
2151 case 0xef:
2152 {
2153 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
2154 {
2155 return token_type::parse_error;
2156 }
2157 break;
2158 }
2159
2160 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
2161 case 0xed:
2162 {
2163 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
2164 {
2165 return token_type::parse_error;
2166 }
2167 break;
2168 }
2169
2170 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
2171 case 0xf0:
2172 {
2173 if (JSON_UNLIKELY(not (next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2174 {
2175 return token_type::parse_error;
2176 }
2177 break;
2178 }
2179
2180 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
2181 case 0xf1:
2182 case 0xf2:
2183 case 0xf3:
2184 {
2185 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
2186 {
2187 return token_type::parse_error;
2188 }
2189 break;
2190 }
2191
2192 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
2193 case 0xf4:
2194 {
2195 if (JSON_UNLIKELY(not (next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
2196 {
2197 return token_type::parse_error;
2198 }
2199 break;
2200 }
2201
2202 // remaining bytes (80..C1 and F5..FF) are ill-formed
2203 default:
2204 {
2205 error_message = "invalid string: ill-formed UTF-8 byte";
2206 return token_type::parse_error;
2207 }
2208 }
2209 }
2210 }
2211
strtof(float & f,const char * str,char ** endptr)2212 static void strtof(float& f, const char* str, char** endptr) noexcept
2213 {
2214 f = std::strtof(str, endptr);
2215 }
2216
strtof(double & f,const char * str,char ** endptr)2217 static void strtof(double& f, const char* str, char** endptr) noexcept
2218 {
2219 f = std::strtod(str, endptr);
2220 }
2221
strtof(long double & f,const char * str,char ** endptr)2222 static void strtof(long double& f, const char* str, char** endptr) noexcept
2223 {
2224 f = std::strtold(str, endptr);
2225 }
2226
2227 /*!
2228 @brief scan a number literal
2229 This function scans a string according to Sect. 6 of RFC 7159.
2230 The function is realized with a deterministic finite state machine derived
2231 from the grammar described in RFC 7159. Starting in state "init", the
2232 input is read and used to determined the next state. Only state "done"
2233 accepts the number. State "error" is a trap state to model errors. In the
2234 table below, "anything" means any character but the ones listed before.
2235 state | 0 | 1-9 | e E | + | - | . | anything
2236 ---------|----------|----------|----------|---------|---------|----------|-----------
2237 init | zero | any1 | [error] | [error] | minus | [error] | [error]
2238 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
2239 zero | done | done | exponent | done | done | decimal1 | done
2240 any1 | any1 | any1 | exponent | done | done | decimal1 | done
2241 decimal1 | decimal2 | [error] | [error] | [error] | [error] | [error] | [error]
2242 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
2243 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
2244 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
2245 any2 | any2 | any2 | done | done | done | done | done
2246 The state machine is realized with one label per state (prefixed with
2247 "scan_number_") and `goto` statements between them. The state machine
2248 contains cycles, but any cycle can be left when EOF is read. Therefore,
2249 the function is guaranteed to terminate.
2250 During scanning, the read bytes are stored in yytext. This string is
2251 then converted to a signed integer, an unsigned integer, or a
2252 floating-point number.
2253 @return token_type::value_unsigned, token_type::value_integer, or
2254 token_type::value_float if number could be successfully scanned,
2255 token_type::parse_error otherwise
2256 @note The scanner is independent of the current locale. Internally, the
2257 locale's decimal point is used instead of `.` to work with the
2258 locale-dependent converters.
2259 */
scan_number()2260 token_type scan_number()
2261 {
2262 // reset yytext to store the number's bytes
2263 reset();
2264
2265 // the type of the parsed number; initially set to unsigned; will be
2266 // changed if minus sign, decimal point or exponent is read
2267 token_type number_type = token_type::value_unsigned;
2268
2269 // state (init): we just found out we need to scan a number
2270 switch (current)
2271 {
2272 case '-':
2273 {
2274 add(current);
2275 goto scan_number_minus;
2276 }
2277
2278 case '0':
2279 {
2280 add(current);
2281 goto scan_number_zero;
2282 }
2283
2284 case '1':
2285 case '2':
2286 case '3':
2287 case '4':
2288 case '5':
2289 case '6':
2290 case '7':
2291 case '8':
2292 case '9':
2293 {
2294 add(current);
2295 goto scan_number_any1;
2296 }
2297
2298 default:
2299 {
2300 // all other characters are rejected outside scan_number()
2301 assert(false); // LCOV_EXCL_LINE
2302 }
2303 }
2304
2305 scan_number_minus:
2306 // state: we just parsed a leading minus sign
2307 number_type = token_type::value_integer;
2308 switch (get())
2309 {
2310 case '0':
2311 {
2312 add(current);
2313 goto scan_number_zero;
2314 }
2315
2316 case '1':
2317 case '2':
2318 case '3':
2319 case '4':
2320 case '5':
2321 case '6':
2322 case '7':
2323 case '8':
2324 case '9':
2325 {
2326 add(current);
2327 goto scan_number_any1;
2328 }
2329
2330 default:
2331 {
2332 error_message = "invalid number; expected digit after '-'";
2333 return token_type::parse_error;
2334 }
2335 }
2336
2337 scan_number_zero:
2338 // state: we just parse a zero (maybe with a leading minus sign)
2339 switch (get())
2340 {
2341 case '.':
2342 {
2343 add(decimal_point_char);
2344 goto scan_number_decimal1;
2345 }
2346
2347 case 'e':
2348 case 'E':
2349 {
2350 add(current);
2351 goto scan_number_exponent;
2352 }
2353
2354 default:
2355 goto scan_number_done;
2356 }
2357
2358 scan_number_any1:
2359 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
2360 switch (get())
2361 {
2362 case '0':
2363 case '1':
2364 case '2':
2365 case '3':
2366 case '4':
2367 case '5':
2368 case '6':
2369 case '7':
2370 case '8':
2371 case '9':
2372 {
2373 add(current);
2374 goto scan_number_any1;
2375 }
2376
2377 case '.':
2378 {
2379 add(decimal_point_char);
2380 goto scan_number_decimal1;
2381 }
2382
2383 case 'e':
2384 case 'E':
2385 {
2386 add(current);
2387 goto scan_number_exponent;
2388 }
2389
2390 default:
2391 goto scan_number_done;
2392 }
2393
2394 scan_number_decimal1:
2395 // state: we just parsed a decimal point
2396 number_type = token_type::value_float;
2397 switch (get())
2398 {
2399 case '0':
2400 case '1':
2401 case '2':
2402 case '3':
2403 case '4':
2404 case '5':
2405 case '6':
2406 case '7':
2407 case '8':
2408 case '9':
2409 {
2410 add(current);
2411 goto scan_number_decimal2;
2412 }
2413
2414 default:
2415 {
2416 error_message = "invalid number; expected digit after '.'";
2417 return token_type::parse_error;
2418 }
2419 }
2420
2421 scan_number_decimal2:
2422 // we just parsed at least one number after a decimal point
2423 switch (get())
2424 {
2425 case '0':
2426 case '1':
2427 case '2':
2428 case '3':
2429 case '4':
2430 case '5':
2431 case '6':
2432 case '7':
2433 case '8':
2434 case '9':
2435 {
2436 add(current);
2437 goto scan_number_decimal2;
2438 }
2439
2440 case 'e':
2441 case 'E':
2442 {
2443 add(current);
2444 goto scan_number_exponent;
2445 }
2446
2447 default:
2448 goto scan_number_done;
2449 }
2450
2451 scan_number_exponent:
2452 // we just parsed an exponent
2453 number_type = token_type::value_float;
2454 switch (get())
2455 {
2456 case '+':
2457 case '-':
2458 {
2459 add(current);
2460 goto scan_number_sign;
2461 }
2462
2463 case '0':
2464 case '1':
2465 case '2':
2466 case '3':
2467 case '4':
2468 case '5':
2469 case '6':
2470 case '7':
2471 case '8':
2472 case '9':
2473 {
2474 add(current);
2475 goto scan_number_any2;
2476 }
2477
2478 default:
2479 {
2480 error_message =
2481 "invalid number; expected '+', '-', or digit after exponent";
2482 return token_type::parse_error;
2483 }
2484 }
2485
2486 scan_number_sign:
2487 // we just parsed an exponent sign
2488 switch (get())
2489 {
2490 case '0':
2491 case '1':
2492 case '2':
2493 case '3':
2494 case '4':
2495 case '5':
2496 case '6':
2497 case '7':
2498 case '8':
2499 case '9':
2500 {
2501 add(current);
2502 goto scan_number_any2;
2503 }
2504
2505 default:
2506 {
2507 error_message = "invalid number; expected digit after exponent sign";
2508 return token_type::parse_error;
2509 }
2510 }
2511
2512 scan_number_any2:
2513 // we just parsed a number after the exponent or exponent sign
2514 switch (get())
2515 {
2516 case '0':
2517 case '1':
2518 case '2':
2519 case '3':
2520 case '4':
2521 case '5':
2522 case '6':
2523 case '7':
2524 case '8':
2525 case '9':
2526 {
2527 add(current);
2528 goto scan_number_any2;
2529 }
2530
2531 default:
2532 goto scan_number_done;
2533 }
2534
2535 scan_number_done:
2536 // unget the character after the number (we only read it to know that
2537 // we are done scanning a number)
2538 unget();
2539
2540 char* endptr = nullptr;
2541 errno = 0;
2542
2543 // try to parse integers first and fall back to floats
2544 if (number_type == token_type::value_unsigned)
2545 {
2546 const auto x = std::strtoull(yytext.data(), &endptr, 10);
2547
2548 // we checked the number format before
2549 assert(endptr == yytext.data() + yytext.size());
2550
2551 if (errno == 0)
2552 {
2553 value_unsigned = static_cast<number_unsigned_t>(x);
2554 if (value_unsigned == x)
2555 {
2556 return token_type::value_unsigned;
2557 }
2558 }
2559 }
2560 else if (number_type == token_type::value_integer)
2561 {
2562 const auto x = std::strtoll(yytext.data(), &endptr, 10);
2563
2564 // we checked the number format before
2565 assert(endptr == yytext.data() + yytext.size());
2566
2567 if (errno == 0)
2568 {
2569 value_integer = static_cast<number_integer_t>(x);
2570 if (value_integer == x)
2571 {
2572 return token_type::value_integer;
2573 }
2574 }
2575 }
2576
2577 // this code is reached if we parse a floating-point number or if an
2578 // integer conversion above failed
2579 strtof(value_float, yytext.data(), &endptr);
2580
2581 // we checked the number format before
2582 assert(endptr == yytext.data() + yytext.size());
2583
2584 return token_type::value_float;
2585 }
2586
2587 /*!
2588 @param[in] literal_text the literal text to expect
2589 @param[in] length the length of the passed literal text
2590 @param[in] return_type the token type to return on success
2591 */
scan_literal(const char * literal_text,const std::size_t length,token_type return_type)2592 token_type scan_literal(const char* literal_text, const std::size_t length,
2593 token_type return_type)
2594 {
2595 assert(current == literal_text[0]);
2596 for (std::size_t i = 1; i < length; ++i)
2597 {
2598 if (JSON_UNLIKELY(get() != literal_text[i]))
2599 {
2600 error_message = "invalid literal";
2601 return token_type::parse_error;
2602 }
2603 }
2604 return return_type;
2605 }
2606
2607 /////////////////////
2608 // input management
2609 /////////////////////
2610
2611 /// reset yytext; current character is beginning of token
reset()2612 void reset() noexcept
2613 {
2614 yytext.clear();
2615 token_string.clear();
2616 token_string.push_back(std::char_traits<char>::to_char_type(current));
2617 }
2618
2619 /*
2620 @brief get next character from the input
2621 This function provides the interface to the used input adapter. It does
2622 not throw in case the input reached EOF, but returns a
2623 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
2624 for use in error messages.
2625 @return character read from the input
2626 */
get()2627 std::char_traits<char>::int_type get()
2628 {
2629 ++chars_read;
2630 current = ia->get_character();
2631 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2632 {
2633 token_string.push_back(std::char_traits<char>::to_char_type(current));
2634 }
2635 return current;
2636 }
2637
2638 /// unget current character (return it again on next get)
unget()2639 void unget()
2640 {
2641 --chars_read;
2642 if (JSON_LIKELY(current != std::char_traits<char>::eof()))
2643 {
2644 ia->unget_character();
2645 assert(token_string.size() != 0);
2646 token_string.pop_back();
2647 }
2648 }
2649
2650 /// add a character to yytext
add(int c)2651 void add(int c)
2652 {
2653 yytext.push_back(std::char_traits<char>::to_char_type(c));
2654 }
2655
2656 public:
2657 /////////////////////
2658 // value getters
2659 /////////////////////
2660
2661 /// return integer value
get_number_integer() const2662 constexpr number_integer_t get_number_integer() const noexcept
2663 {
2664 return value_integer;
2665 }
2666
2667 /// return unsigned integer value
get_number_unsigned() const2668 constexpr number_unsigned_t get_number_unsigned() const noexcept
2669 {
2670 return value_unsigned;
2671 }
2672
2673 /// return floating-point value
get_number_float() const2674 constexpr number_float_t get_number_float() const noexcept
2675 {
2676 return value_float;
2677 }
2678
2679 /// return current string value (implicitly resets the token; useful only once)
move_string()2680 std::string move_string()
2681 {
2682 return std::move(yytext);
2683 }
2684
2685 /////////////////////
2686 // diagnostics
2687 /////////////////////
2688
2689 /// return position of last read token
get_position() const2690 constexpr std::size_t get_position() const noexcept
2691 {
2692 return chars_read;
2693 }
2694
2695 /// return the last read token (for errors only). Will never contain EOF
2696 /// (an arbitrary value that is not a valid char value, often -1), because
2697 /// 255 may legitimately occur. May contain NUL, which should be escaped.
get_token_string() const2698 std::string get_token_string() const
2699 {
2700 // escape control characters
2701 std::string result;
2702 for (auto c : token_string)
2703 {
2704 if ('\x00' <= c and c <= '\x1f')
2705 {
2706 // escape control characters
2707 std::stringstream ss;
2708 ss << "<U+" << std::setw(4) << std::uppercase << std::setfill('0')
2709 << std::hex << static_cast<int>(c) << ">";
2710 result += ss.str();
2711 }
2712 else
2713 {
2714 // add character as is
2715 result.push_back(c);
2716 }
2717 }
2718
2719 return result;
2720 }
2721
2722 /// return syntax error message
get_error_message() const2723 constexpr const char* get_error_message() const noexcept
2724 {
2725 return error_message;
2726 }
2727
2728 /////////////////////
2729 // actual scanner
2730 /////////////////////
2731
scan()2732 token_type scan()
2733 {
2734 // read next character and ignore whitespace
2735 do
2736 {
2737 get();
2738 }
2739 while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
2740
2741 switch (current)
2742 {
2743 // structural characters
2744 case '[':
2745 return token_type::begin_array;
2746 case ']':
2747 return token_type::end_array;
2748 case '{':
2749 return token_type::begin_object;
2750 case '}':
2751 return token_type::end_object;
2752 case ':':
2753 return token_type::name_separator;
2754 case ',':
2755 return token_type::value_separator;
2756
2757 // literals
2758 case 't':
2759 return scan_literal("true", 4, token_type::literal_true);
2760 case 'f':
2761 return scan_literal("false", 5, token_type::literal_false);
2762 case 'n':
2763 return scan_literal("null", 4, token_type::literal_null);
2764
2765 // string
2766 case '\"':
2767 return scan_string();
2768
2769 // number
2770 case '-':
2771 case '0':
2772 case '1':
2773 case '2':
2774 case '3':
2775 case '4':
2776 case '5':
2777 case '6':
2778 case '7':
2779 case '8':
2780 case '9':
2781 return scan_number();
2782
2783 // end of input (the null byte is needed when parsing from
2784 // string literals)
2785 case '\0':
2786 case std::char_traits<char>::eof():
2787 return token_type::end_of_input;
2788
2789 // error
2790 default:
2791 error_message = "invalid literal";
2792 return token_type::parse_error;
2793 }
2794 }
2795
2796 private:
2797 /// input adapter
2798 detail::input_adapter_t ia = nullptr;
2799
2800 /// the current character
2801 std::char_traits<char>::int_type current = std::char_traits<char>::eof();
2802
2803 /// the number of characters read
2804 std::size_t chars_read = 0;
2805
2806 /// raw input token string (for error messages)
2807 std::vector<char> token_string { };
2808
2809 /// buffer for variable-length tokens (numbers, strings)
2810 std::string yytext { };
2811
2812 /// a description of occurred lexer errors
2813 const char* error_message = "";
2814
2815 // number values
2816 number_integer_t value_integer = 0;
2817 number_unsigned_t value_unsigned = 0;
2818 number_float_t value_float = 0;
2819
2820 /// the decimal point
2821 const char decimal_point_char = '.';
2822 };
2823
2824 /*!
2825 @brief syntax analysis
2826 This class implements a recursive decent parser.
2827 */
2828 template<typename BasicJsonType>
2829 class parser
2830 {
2831 using number_integer_t = typename BasicJsonType::number_integer_t;
2832 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
2833 using number_float_t = typename BasicJsonType::number_float_t;
2834 using lexer_t = lexer<BasicJsonType>;
2835 using token_type = typename lexer_t::token_type;
2836
2837 public:
2838 enum class parse_event_t : uint8_t
2839 {
2840 /// the parser read `{` and started to process a JSON object
2841 object_start,
2842 /// the parser read `}` and finished processing a JSON object
2843 object_end,
2844 /// the parser read `[` and started to process a JSON array
2845 array_start,
2846 /// the parser read `]` and finished processing a JSON array
2847 array_end,
2848 /// the parser read a key of a value in an object
2849 key,
2850 /// the parser finished reading a JSON value
2851 value
2852 };
2853
2854 using parser_callback_t =
2855 std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;
2856
2857 /// a parser reading from an input adapter
parser(detail::input_adapter_t adapter,const parser_callback_t cb=nullptr,const bool allow_exceptions_=true)2858 explicit parser(detail::input_adapter_t adapter,
2859 const parser_callback_t cb = nullptr,
2860 const bool allow_exceptions_ = true)
2861 : callback(cb), m_lexer(adapter), allow_exceptions(allow_exceptions_)
2862 {}
2863
2864 /*!
2865 @brief public parser interface
2866 @param[in] strict whether to expect the last token to be EOF
2867 @param[in,out] result parsed JSON value
2868 @throw parse_error.101 in case of an unexpected token
2869 @throw parse_error.102 if to_unicode fails or surrogate error
2870 @throw parse_error.103 if to_unicode fails
2871 */
parse(const bool strict,BasicJsonType & result)2872 void parse(const bool strict, BasicJsonType& result)
2873 {
2874 // read first token
2875 get_token();
2876
2877 parse_internal(true, result);
2878 result.assert_invariant();
2879
2880 // in strict mode, input must be completely read
2881 if (strict)
2882 {
2883 get_token();
2884 expect(token_type::end_of_input);
2885 }
2886
2887 // in case of an error, return discarded value
2888 if (errored)
2889 {
2890 result = value_t::discarded;
2891 return;
2892 }
2893
2894 // set top-level value to null if it was discarded by the callback
2895 // function
2896 if (result.is_discarded())
2897 {
2898 result = nullptr;
2899 }
2900 }
2901
2902 /*!
2903 @brief public accept interface
2904 @param[in] strict whether to expect the last token to be EOF
2905 @return whether the input is a proper JSON text
2906 */
accept(const bool strict=true)2907 bool accept(const bool strict = true)
2908 {
2909 // read first token
2910 get_token();
2911
2912 if (not accept_internal())
2913 {
2914 return false;
2915 }
2916
2917 // strict => last token must be EOF
2918 return not strict or (get_token() == token_type::end_of_input);
2919 }
2920
2921 private:
2922 /*!
2923 @brief the actual parser
2924 @throw parse_error.101 in case of an unexpected token
2925 @throw parse_error.102 if to_unicode fails or surrogate error
2926 @throw parse_error.103 if to_unicode fails
2927 */
parse_internal(bool keep,BasicJsonType & result)2928 void parse_internal(bool keep, BasicJsonType& result)
2929 {
2930 // never parse after a parse error was detected
2931 assert(not errored);
2932
2933 // start with a discarded value
2934 if (not result.is_discarded())
2935 {
2936 result.m_value.destroy(result.m_type);
2937 result.m_type = value_t::discarded;
2938 }
2939
2940 switch (last_token)
2941 {
2942 case token_type::begin_object:
2943 {
2944 if (keep)
2945 {
2946 if (callback)
2947 {
2948 keep = callback(depth++, parse_event_t::object_start, result);
2949 }
2950
2951 if (not callback or keep)
2952 {
2953 // explicitly set result to object to cope with {}
2954 result.m_type = value_t::object;
2955 result.m_value = value_t::object;
2956 }
2957 }
2958
2959 // read next token
2960 get_token();
2961
2962 // closing } -> we are done
2963 if (last_token == token_type::end_object)
2964 {
2965 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
2966 {
2967 result.m_value.destroy(result.m_type);
2968 result.m_type = value_t::discarded;
2969 }
2970 break;
2971 }
2972
2973 // parse values
2974 std::string key;
2975 BasicJsonType value;
2976 while (true)
2977 {
2978 // store key
2979 if (not expect(token_type::value_string))
2980 {
2981 return;
2982 }
2983 key = m_lexer.move_string();
2984
2985 bool keep_tag = false;
2986 if (keep)
2987 {
2988 if (callback)
2989 {
2990 BasicJsonType k(key);
2991 keep_tag = callback(depth, parse_event_t::key, k);
2992 }
2993 else
2994 {
2995 keep_tag = true;
2996 }
2997 }
2998
2999 // parse separator (:)
3000 get_token();
3001 if (not expect(token_type::name_separator))
3002 {
3003 return;
3004 }
3005
3006 // parse and add value
3007 get_token();
3008 value.m_value.destroy(value.m_type);
3009 value.m_type = value_t::discarded;
3010 parse_internal(keep, value);
3011
3012 if (JSON_UNLIKELY(errored))
3013 {
3014 return;
3015 }
3016
3017 if (keep and keep_tag and not value.is_discarded())
3018 {
3019 result.m_value.object->emplace(std::move(key), std::move(value));
3020 }
3021
3022 // comma -> next value
3023 get_token();
3024 if (last_token == token_type::value_separator)
3025 {
3026 get_token();
3027 continue;
3028 }
3029
3030 // closing }
3031 if (not expect(token_type::end_object))
3032 {
3033 return;
3034 }
3035 break;
3036 }
3037
3038 if (keep and callback and not callback(--depth, parse_event_t::object_end, result))
3039 {
3040 result.m_value.destroy(result.m_type);
3041 result.m_type = value_t::discarded;
3042 }
3043 break;
3044 }
3045
3046 case token_type::begin_array:
3047 {
3048 if (keep)
3049 {
3050 if (callback)
3051 {
3052 keep = callback(depth++, parse_event_t::array_start, result);
3053 }
3054
3055 if (not callback or keep)
3056 {
3057 // explicitly set result to array to cope with []
3058 result.m_type = value_t::array;
3059 result.m_value = value_t::array;
3060 }
3061 }
3062
3063 // read next token
3064 get_token();
3065
3066 // closing ] -> we are done
3067 if (last_token == token_type::end_array)
3068 {
3069 if (callback and not callback(--depth, parse_event_t::array_end, result))
3070 {
3071 result.m_value.destroy(result.m_type);
3072 result.m_type = value_t::discarded;
3073 }
3074 break;
3075 }
3076
3077 // parse values
3078 BasicJsonType value;
3079 while (true)
3080 {
3081 // parse value
3082 value.m_value.destroy(value.m_type);
3083 value.m_type = value_t::discarded;
3084 parse_internal(keep, value);
3085
3086 if (JSON_UNLIKELY(errored))
3087 {
3088 return;
3089 }
3090
3091 if (keep and not value.is_discarded())
3092 {
3093 result.m_value.array->push_back(std::move(value));
3094 }
3095
3096 // comma -> next value
3097 get_token();
3098 if (last_token == token_type::value_separator)
3099 {
3100 get_token();
3101 continue;
3102 }
3103
3104 // closing ]
3105 if (not expect(token_type::end_array))
3106 {
3107 return;
3108 }
3109 break;
3110 }
3111
3112 if (keep and callback and not callback(--depth, parse_event_t::array_end, result))
3113 {
3114 result.m_value.destroy(result.m_type);
3115 result.m_type = value_t::discarded;
3116 }
3117 break;
3118 }
3119
3120 case token_type::literal_null:
3121 {
3122 result.m_type = value_t::null;
3123 break;
3124 }
3125
3126 case token_type::value_string:
3127 {
3128 result.m_type = value_t::string;
3129 result.m_value = m_lexer.move_string();
3130 break;
3131 }
3132
3133 case token_type::literal_true:
3134 {
3135 result.m_type = value_t::boolean;
3136 result.m_value = true;
3137 break;
3138 }
3139
3140 case token_type::literal_false:
3141 {
3142 result.m_type = value_t::boolean;
3143 result.m_value = false;
3144 break;
3145 }
3146
3147 case token_type::value_unsigned:
3148 {
3149 result.m_type = value_t::number_unsigned;
3150 result.m_value = m_lexer.get_number_unsigned();
3151 break;
3152 }
3153
3154 case token_type::value_integer:
3155 {
3156 result.m_type = value_t::number_integer;
3157 result.m_value = m_lexer.get_number_integer();
3158 break;
3159 }
3160
3161 case token_type::value_float:
3162 {
3163 result.m_type = value_t::number_float;
3164 result.m_value = m_lexer.get_number_float();
3165
3166 // throw in case of infinity or NAN
3167 if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
3168 {
3169 if (allow_exceptions)
3170 {
3171 JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
3172 m_lexer.get_token_string() + "'"));
3173 }
3174 expect(token_type::uninitialized);
3175 }
3176 break;
3177 }
3178
3179 case token_type::parse_error:
3180 {
3181 // using "uninitialized" to avoid "expected" message
3182 if (not expect(token_type::uninitialized))
3183 {
3184 return;
3185 }
3186 break; // LCOV_EXCL_LINE
3187 }
3188
3189 default:
3190 {
3191 // the last token was unexpected; we expected a value
3192 if (not expect(token_type::literal_or_value))
3193 {
3194 return;
3195 }
3196 break; // LCOV_EXCL_LINE
3197 }
3198 }
3199
3200 if (keep and callback and not callback(depth, parse_event_t::value, result))
3201 {
3202 result.m_type = value_t::discarded;
3203 }
3204 }
3205
3206 /*!
3207 @brief the acutal acceptor
3208 @invariant 1. The last token is not yet processed. Therefore, the caller
3209 of this function must make sure a token has been read.
3210 2. When this function returns, the last token is processed.
3211 That is, the last read character was already considered.
3212 This invariant makes sure that no token needs to be "unput".
3213 */
accept_internal()3214 bool accept_internal()
3215 {
3216 switch (last_token)
3217 {
3218 case token_type::begin_object:
3219 {
3220 // read next token
3221 get_token();
3222
3223 // closing } -> we are done
3224 if (last_token == token_type::end_object)
3225 {
3226 return true;
3227 }
3228
3229 // parse values
3230 while (true)
3231 {
3232 // parse key
3233 if (last_token != token_type::value_string)
3234 {
3235 return false;
3236 }
3237
3238 // parse separator (:)
3239 get_token();
3240 if (last_token != token_type::name_separator)
3241 {
3242 return false;
3243 }
3244
3245 // parse value
3246 get_token();
3247 if (not accept_internal())
3248 {
3249 return false;
3250 }
3251
3252 // comma -> next value
3253 get_token();
3254 if (last_token == token_type::value_separator)
3255 {
3256 get_token();
3257 continue;
3258 }
3259
3260 // closing }
3261 return (last_token == token_type::end_object);
3262 }
3263 }
3264
3265 case token_type::begin_array:
3266 {
3267 // read next token
3268 get_token();
3269
3270 // closing ] -> we are done
3271 if (last_token == token_type::end_array)
3272 {
3273 return true;
3274 }
3275
3276 // parse values
3277 while (true)
3278 {
3279 // parse value
3280 if (not accept_internal())
3281 {
3282 return false;
3283 }
3284
3285 // comma -> next value
3286 get_token();
3287 if (last_token == token_type::value_separator)
3288 {
3289 get_token();
3290 continue;
3291 }
3292
3293 // closing ]
3294 return (last_token == token_type::end_array);
3295 }
3296 }
3297
3298 case token_type::value_float:
3299 {
3300 // reject infinity or NAN
3301 return std::isfinite(m_lexer.get_number_float());
3302 }
3303
3304 case token_type::literal_false:
3305 case token_type::literal_null:
3306 case token_type::literal_true:
3307 case token_type::value_integer:
3308 case token_type::value_string:
3309 case token_type::value_unsigned:
3310 return true;
3311
3312 default: // the last token was unexpected
3313 return false;
3314 }
3315 }
3316
3317 /// get next token from lexer
get_token()3318 token_type get_token()
3319 {
3320 return (last_token = m_lexer.scan());
3321 }
3322
3323 /*!
3324 @throw parse_error.101 if expected token did not occur
3325 */
expect(token_type t)3326 bool expect(token_type t)
3327 {
3328 if (JSON_UNLIKELY(t != last_token))
3329 {
3330 errored = true;
3331 expected = t;
3332 if (allow_exceptions)
3333 {
3334 throw_exception();
3335 }
3336 else
3337 {
3338 return false;
3339 }
3340 }
3341
3342 return true;
3343 }
3344
throw_exception() const3345 [[noreturn]] void throw_exception() const
3346 {
3347 std::string error_msg = "syntax error - ";
3348 if (last_token == token_type::parse_error)
3349 {
3350 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
3351 m_lexer.get_token_string() + "'";
3352 }
3353 else
3354 {
3355 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
3356 }
3357
3358 if (expected != token_type::uninitialized)
3359 {
3360 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
3361 }
3362
3363 JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg));
3364 }
3365
3366 private:
3367 /// current level of recursion
3368 int depth = 0;
3369 /// callback function
3370 const parser_callback_t callback = nullptr;
3371 /// the type of the last read token
3372 token_type last_token = token_type::uninitialized;
3373 /// the lexer
3374 lexer_t m_lexer;
3375 /// whether a syntax error occurred
3376 bool errored = false;
3377 /// possible reason for the syntax error
3378 token_type expected = token_type::uninitialized;
3379 /// whether to throw exceptions in case of errors
3380 const bool allow_exceptions = true;
3381 };
3382
3383 ///////////////
3384 // iterators //
3385 ///////////////
3386
3387 /*!
3388 @brief an iterator for primitive JSON types
3389 This class models an iterator for primitive JSON types (boolean, number,
3390 string). It's only purpose is to allow the iterator/const_iterator classes
3391 to "iterate" over primitive values. Internally, the iterator is modeled by
3392 a `difference_type` variable. Value begin_value (`0`) models the begin,
3393 end_value (`1`) models past the end.
3394 */
3395 class primitive_iterator_t
3396 {
3397 public:
3398 using difference_type = std::ptrdiff_t;
3399
get_value() const3400 constexpr difference_type get_value() const noexcept
3401 {
3402 return m_it;
3403 }
3404
3405 /// set iterator to a defined beginning
set_begin()3406 void set_begin() noexcept
3407 {
3408 m_it = begin_value;
3409 }
3410
3411 /// set iterator to a defined past the end
set_end()3412 void set_end() noexcept
3413 {
3414 m_it = end_value;
3415 }
3416
3417 /// return whether the iterator can be dereferenced
is_begin() const3418 constexpr bool is_begin() const noexcept
3419 {
3420 return m_it == begin_value;
3421 }
3422
3423 /// return whether the iterator is at end
is_end() const3424 constexpr bool is_end() const noexcept
3425 {
3426 return m_it == end_value;
3427 }
3428
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)3429 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3430 {
3431 return lhs.m_it == rhs.m_it;
3432 }
3433
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)3434 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3435 {
3436 return lhs.m_it < rhs.m_it;
3437 }
3438
operator +(difference_type i)3439 primitive_iterator_t operator+(difference_type i)
3440 {
3441 auto result = *this;
3442 result += i;
3443 return result;
3444 }
3445
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)3446 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
3447 {
3448 return lhs.m_it - rhs.m_it;
3449 }
3450
operator <<(std::ostream & os,primitive_iterator_t it)3451 friend std::ostream& operator<<(std::ostream& os, primitive_iterator_t it)
3452 {
3453 return os << it.m_it;
3454 }
3455
operator ++()3456 primitive_iterator_t& operator++()
3457 {
3458 ++m_it;
3459 return *this;
3460 }
3461
operator ++(int)3462 primitive_iterator_t operator++(int)
3463 {
3464 auto result = *this;
3465 m_it++;
3466 return result;
3467 }
3468
operator --()3469 primitive_iterator_t& operator--()
3470 {
3471 --m_it;
3472 return *this;
3473 }
3474
operator --(int)3475 primitive_iterator_t operator--(int)
3476 {
3477 auto result = *this;
3478 m_it--;
3479 return result;
3480 }
3481
operator +=(difference_type n)3482 primitive_iterator_t& operator+=(difference_type n)
3483 {
3484 m_it += n;
3485 return *this;
3486 }
3487
operator -=(difference_type n)3488 primitive_iterator_t& operator-=(difference_type n)
3489 {
3490 m_it -= n;
3491 return *this;
3492 }
3493
3494 private:
3495 static constexpr difference_type begin_value = 0;
3496 static constexpr difference_type end_value = begin_value + 1;
3497
3498 /// iterator as signed integer type
3499 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
3500 };
3501
3502 /*!
3503 @brief an iterator value
3504 @note This structure could easily be a union, but MSVC currently does not allow
3505 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
3506 */
3507 template<typename BasicJsonType> struct internal_iterator
3508 {
3509 /// iterator for JSON objects
3510 typename BasicJsonType::object_t::iterator object_iterator {};
3511 /// iterator for JSON arrays
3512 typename BasicJsonType::array_t::iterator array_iterator {};
3513 /// generic iterator for all other types
3514 primitive_iterator_t primitive_iterator {};
3515 };
3516
3517 template<typename IteratorType> class iteration_proxy;
3518
3519 /*!
3520 @brief a template for a random access iterator for the @ref basic_json class
3521 This class implements a both iterators (iterator and const_iterator) for the
3522 @ref basic_json class.
3523 @note An iterator is called *initialized* when a pointer to a JSON value has
3524 been set (e.g., by a constructor or a copy assignment). If the iterator is
3525 default-constructed, it is *uninitialized* and most methods are undefined.
3526 **The library uses assertions to detect calls on uninitialized iterators.**
3527 @requirement The class satisfies the following concept requirements:
3528 -
3529 [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
3530 The iterator that can be moved to point (forward and backward) to any
3531 element in constant time.
3532 @since version 1.0.0, simplified in version 2.0.9
3533 */
3534 template<typename BasicJsonType>
3535 class iter_impl : public std::iterator<std::random_access_iterator_tag, BasicJsonType>
3536 {
3537 /// allow basic_json to access private members
3538 friend iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
3539 friend BasicJsonType;
3540 friend iteration_proxy<iter_impl>;
3541
3542 using object_t = typename BasicJsonType::object_t;
3543 using array_t = typename BasicJsonType::array_t;
3544 // make sure BasicJsonType is basic_json or const basic_json
3545 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
3546 "iter_impl only accepts (const) basic_json");
3547
3548 public:
3549 /// the type of the values when the iterator is dereferenced
3550 using value_type = typename BasicJsonType::value_type;
3551 /// a type to represent differences between iterators
3552 using difference_type = typename BasicJsonType::difference_type;
3553 /// defines a pointer to the type iterated over (value_type)
3554 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
3555 typename BasicJsonType::const_pointer,
3556 typename BasicJsonType::pointer>::type;
3557 /// defines a reference to the type iterated over (value_type)
3558 using reference =
3559 typename std::conditional<std::is_const<BasicJsonType>::value,
3560 typename BasicJsonType::const_reference,
3561 typename BasicJsonType::reference>::type;
3562 /// the category of the iterator
3563 using iterator_category = std::bidirectional_iterator_tag;
3564
3565 /// default constructor
3566 iter_impl() = default;
3567
3568 /*!
3569 @brief constructor for a given JSON instance
3570 @param[in] object pointer to a JSON object for this iterator
3571 @pre object != nullptr
3572 @post The iterator is initialized; i.e. `m_object != nullptr`.
3573 */
iter_impl(pointer object)3574 explicit iter_impl(pointer object) noexcept : m_object(object)
3575 {
3576 assert(m_object != nullptr);
3577
3578 switch (m_object->m_type)
3579 {
3580 case value_t::object:
3581 {
3582 m_it.object_iterator = typename object_t::iterator();
3583 break;
3584 }
3585
3586 case value_t::array:
3587 {
3588 m_it.array_iterator = typename array_t::iterator();
3589 break;
3590 }
3591
3592 default:
3593 {
3594 m_it.primitive_iterator = primitive_iterator_t();
3595 break;
3596 }
3597 }
3598 }
3599
3600 /*!
3601 @note The conventional copy constructor and copy assignment are implicitly
3602 defined. Combined with the following converting constructor and
3603 assignment, they support: (1) copy from iterator to iterator, (2)
3604 copy from const iterator to const iterator, and (3) conversion from
3605 iterator to const iterator. However conversion from const iterator
3606 to iterator is not defined.
3607 */
3608
3609 /*!
3610 @brief converting constructor
3611 @param[in] other non-const iterator to copy from
3612 @note It is not checked whether @a other is initialized.
3613 */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)3614 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3615 : m_object(other.m_object), m_it(other.m_it) {}
3616
3617 /*!
3618 @brief converting assignment
3619 @param[in,out] other non-const iterator to copy from
3620 @return const/non-const iterator
3621 @note It is not checked whether @a other is initialized.
3622 */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)3623 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
3624 {
3625 m_object = other.m_object;
3626 m_it = other.m_it;
3627 return *this;
3628 }
3629
3630 private:
3631 /*!
3632 @brief set the iterator to the first value
3633 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3634 */
set_begin()3635 void set_begin() noexcept
3636 {
3637 assert(m_object != nullptr);
3638
3639 switch (m_object->m_type)
3640 {
3641 case value_t::object:
3642 {
3643 m_it.object_iterator = m_object->m_value.object->begin();
3644 break;
3645 }
3646
3647 case value_t::array:
3648 {
3649 m_it.array_iterator = m_object->m_value.array->begin();
3650 break;
3651 }
3652
3653 case value_t::null:
3654 {
3655 // set to end so begin()==end() is true: null is empty
3656 m_it.primitive_iterator.set_end();
3657 break;
3658 }
3659
3660 default:
3661 {
3662 m_it.primitive_iterator.set_begin();
3663 break;
3664 }
3665 }
3666 }
3667
3668 /*!
3669 @brief set the iterator past the last value
3670 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3671 */
set_end()3672 void set_end() noexcept
3673 {
3674 assert(m_object != nullptr);
3675
3676 switch (m_object->m_type)
3677 {
3678 case value_t::object:
3679 {
3680 m_it.object_iterator = m_object->m_value.object->end();
3681 break;
3682 }
3683
3684 case value_t::array:
3685 {
3686 m_it.array_iterator = m_object->m_value.array->end();
3687 break;
3688 }
3689
3690 default:
3691 {
3692 m_it.primitive_iterator.set_end();
3693 break;
3694 }
3695 }
3696 }
3697
3698 public:
3699 /*!
3700 @brief return a reference to the value pointed to by the iterator
3701 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3702 */
operator *() const3703 reference operator*() const
3704 {
3705 assert(m_object != nullptr);
3706
3707 switch (m_object->m_type)
3708 {
3709 case value_t::object:
3710 {
3711 assert(m_it.object_iterator != m_object->m_value.object->end());
3712 return m_it.object_iterator->second;
3713 }
3714
3715 case value_t::array:
3716 {
3717 assert(m_it.array_iterator != m_object->m_value.array->end());
3718 return *m_it.array_iterator;
3719 }
3720
3721 case value_t::null:
3722 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3723
3724 default:
3725 {
3726 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3727 {
3728 return *m_object;
3729 }
3730
3731 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3732 }
3733 }
3734 }
3735
3736 /*!
3737 @brief dereference the iterator
3738 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3739 */
operator ->() const3740 pointer operator->() const
3741 {
3742 assert(m_object != nullptr);
3743
3744 switch (m_object->m_type)
3745 {
3746 case value_t::object:
3747 {
3748 assert(m_it.object_iterator != m_object->m_value.object->end());
3749 return &(m_it.object_iterator->second);
3750 }
3751
3752 case value_t::array:
3753 {
3754 assert(m_it.array_iterator != m_object->m_value.array->end());
3755 return &*m_it.array_iterator;
3756 }
3757
3758 default:
3759 {
3760 if (JSON_LIKELY(m_it.primitive_iterator.is_begin()))
3761 {
3762 return m_object;
3763 }
3764
3765 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
3766 }
3767 }
3768 }
3769
3770 /*!
3771 @brief post-increment (it++)
3772 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3773 */
operator ++(int)3774 iter_impl operator++(int)
3775 {
3776 auto result = *this;
3777 ++(*this);
3778 return result;
3779 }
3780
3781 /*!
3782 @brief pre-increment (++it)
3783 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3784 */
operator ++()3785 iter_impl& operator++()
3786 {
3787 assert(m_object != nullptr);
3788
3789 switch (m_object->m_type)
3790 {
3791 case value_t::object:
3792 {
3793 std::advance(m_it.object_iterator, 1);
3794 break;
3795 }
3796
3797 case value_t::array:
3798 {
3799 std::advance(m_it.array_iterator, 1);
3800 break;
3801 }
3802
3803 default:
3804 {
3805 ++m_it.primitive_iterator;
3806 break;
3807 }
3808 }
3809
3810 return *this;
3811 }
3812
3813 /*!
3814 @brief post-decrement (it--)
3815 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3816 */
operator --(int)3817 iter_impl operator--(int)
3818 {
3819 auto result = *this;
3820 --(*this);
3821 return result;
3822 }
3823
3824 /*!
3825 @brief pre-decrement (--it)
3826 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3827 */
operator --()3828 iter_impl& operator--()
3829 {
3830 assert(m_object != nullptr);
3831
3832 switch (m_object->m_type)
3833 {
3834 case value_t::object:
3835 {
3836 std::advance(m_it.object_iterator, -1);
3837 break;
3838 }
3839
3840 case value_t::array:
3841 {
3842 std::advance(m_it.array_iterator, -1);
3843 break;
3844 }
3845
3846 default:
3847 {
3848 --m_it.primitive_iterator;
3849 break;
3850 }
3851 }
3852
3853 return *this;
3854 }
3855
3856 /*!
3857 @brief comparison: equal
3858 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3859 */
operator ==(const iter_impl & other) const3860 bool operator==(const iter_impl& other) const
3861 {
3862 // if objects are not the same, the comparison is undefined
3863 if (JSON_UNLIKELY(m_object != other.m_object))
3864 {
3865 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
3866 }
3867
3868 assert(m_object != nullptr);
3869
3870 switch (m_object->m_type)
3871 {
3872 case value_t::object:
3873 return (m_it.object_iterator == other.m_it.object_iterator);
3874
3875 case value_t::array:
3876 return (m_it.array_iterator == other.m_it.array_iterator);
3877
3878 default:
3879 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
3880 }
3881 }
3882
3883 /*!
3884 @brief comparison: not equal
3885 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3886 */
operator !=(const iter_impl & other) const3887 bool operator!=(const iter_impl& other) const
3888 {
3889 return not operator==(other);
3890 }
3891
3892 /*!
3893 @brief comparison: smaller
3894 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3895 */
operator <(const iter_impl & other) const3896 bool operator<(const iter_impl& other) const
3897 {
3898 // if objects are not the same, the comparison is undefined
3899 if (JSON_UNLIKELY(m_object != other.m_object))
3900 {
3901 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers"));
3902 }
3903
3904 assert(m_object != nullptr);
3905
3906 switch (m_object->m_type)
3907 {
3908 case value_t::object:
3909 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators"));
3910
3911 case value_t::array:
3912 return (m_it.array_iterator < other.m_it.array_iterator);
3913
3914 default:
3915 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
3916 }
3917 }
3918
3919 /*!
3920 @brief comparison: less than or equal
3921 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3922 */
operator <=(const iter_impl & other) const3923 bool operator<=(const iter_impl& other) const
3924 {
3925 return not other.operator < (*this);
3926 }
3927
3928 /*!
3929 @brief comparison: greater than
3930 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3931 */
operator >(const iter_impl & other) const3932 bool operator>(const iter_impl& other) const
3933 {
3934 return not operator<=(other);
3935 }
3936
3937 /*!
3938 @brief comparison: greater than or equal
3939 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3940 */
operator >=(const iter_impl & other) const3941 bool operator>=(const iter_impl& other) const
3942 {
3943 return not operator<(other);
3944 }
3945
3946 /*!
3947 @brief add to iterator
3948 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3949 */
operator +=(difference_type i)3950 iter_impl& operator+=(difference_type i)
3951 {
3952 assert(m_object != nullptr);
3953
3954 switch (m_object->m_type)
3955 {
3956 case value_t::object:
3957 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
3958
3959 case value_t::array:
3960 {
3961 std::advance(m_it.array_iterator, i);
3962 break;
3963 }
3964
3965 default:
3966 {
3967 m_it.primitive_iterator += i;
3968 break;
3969 }
3970 }
3971
3972 return *this;
3973 }
3974
3975 /*!
3976 @brief subtract from iterator
3977 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3978 */
operator -=(difference_type i)3979 iter_impl& operator-=(difference_type i)
3980 {
3981 return operator+=(-i);
3982 }
3983
3984 /*!
3985 @brief add to iterator
3986 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3987 */
operator +(difference_type i) const3988 iter_impl operator+(difference_type i) const
3989 {
3990 auto result = *this;
3991 result += i;
3992 return result;
3993 }
3994
3995 /*!
3996 @brief addition of distance and iterator
3997 @pre The iterator is initialized; i.e. `m_object != nullptr`.
3998 */
operator +(difference_type i,const iter_impl & it)3999 friend iter_impl operator+(difference_type i, const iter_impl& it)
4000 {
4001 auto result = it;
4002 result += i;
4003 return result;
4004 }
4005
4006 /*!
4007 @brief subtract from iterator
4008 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4009 */
operator -(difference_type i) const4010 iter_impl operator-(difference_type i) const
4011 {
4012 auto result = *this;
4013 result -= i;
4014 return result;
4015 }
4016
4017 /*!
4018 @brief return difference
4019 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4020 */
operator -(const iter_impl & other) const4021 difference_type operator-(const iter_impl& other) const
4022 {
4023 assert(m_object != nullptr);
4024
4025 switch (m_object->m_type)
4026 {
4027 case value_t::object:
4028 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators"));
4029
4030 case value_t::array:
4031 return m_it.array_iterator - other.m_it.array_iterator;
4032
4033 default:
4034 return m_it.primitive_iterator - other.m_it.primitive_iterator;
4035 }
4036 }
4037
4038 /*!
4039 @brief access to successor
4040 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4041 */
operator [](difference_type n) const4042 reference operator[](difference_type n) const
4043 {
4044 assert(m_object != nullptr);
4045
4046 switch (m_object->m_type)
4047 {
4048 case value_t::object:
4049 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators"));
4050
4051 case value_t::array:
4052 return *std::next(m_it.array_iterator, n);
4053
4054 case value_t::null:
4055 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4056
4057 default:
4058 {
4059 if (JSON_LIKELY(m_it.primitive_iterator.get_value() == -n))
4060 {
4061 return *m_object;
4062 }
4063
4064 JSON_THROW(invalid_iterator::create(214, "cannot get value"));
4065 }
4066 }
4067 }
4068
4069 /*!
4070 @brief return the key of an object iterator
4071 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4072 */
key() const4073 typename object_t::key_type key() const
4074 {
4075 assert(m_object != nullptr);
4076
4077 if (JSON_LIKELY(m_object->is_object()))
4078 {
4079 return m_it.object_iterator->first;
4080 }
4081
4082 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators"));
4083 }
4084
4085 /*!
4086 @brief return the value of an iterator
4087 @pre The iterator is initialized; i.e. `m_object != nullptr`.
4088 */
value() const4089 reference value() const
4090 {
4091 return operator*();
4092 }
4093
4094 private:
4095 /// associated JSON instance
4096 pointer m_object = nullptr;
4097 /// the actual iterator of the associated instance
4098 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it = {};
4099 };
4100
4101 /// proxy class for the iterator_wrapper functions
4102 template<typename IteratorType> class iteration_proxy
4103 {
4104 private:
4105 /// helper class for iteration
4106 class iteration_proxy_internal
4107 {
4108 private:
4109 /// the iterator
4110 IteratorType anchor;
4111 /// an index for arrays (used to create key names)
4112 std::size_t array_index = 0;
4113
4114 public:
iteration_proxy_internal(IteratorType it)4115 explicit iteration_proxy_internal(IteratorType it) noexcept : anchor(it) {}
4116
4117 /// dereference operator (needed for range-based for)
operator *()4118 iteration_proxy_internal& operator*()
4119 {
4120 return *this;
4121 }
4122
4123 /// increment operator (needed for range-based for)
operator ++()4124 iteration_proxy_internal& operator++()
4125 {
4126 ++anchor;
4127 ++array_index;
4128
4129 return *this;
4130 }
4131
4132 /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_internal & o) const4133 bool operator!=(const iteration_proxy_internal& o) const noexcept
4134 {
4135 return anchor != o.anchor;
4136 }
4137
4138 /// return key of the iterator
key() const4139 std::string key() const
4140 {
4141 assert(anchor.m_object != nullptr);
4142
4143 switch (anchor.m_object->type())
4144 {
4145 // use integer array index as key
4146 case value_t::array:
4147 return std::to_string(array_index);
4148
4149 // use key from the object
4150 case value_t::object:
4151 return anchor.key();
4152
4153 // use an empty key for all primitive types
4154 default:
4155 return "";
4156 }
4157 }
4158
4159 /// return value of the iterator
value() const4160 typename IteratorType::reference value() const
4161 {
4162 return anchor.value();
4163 }
4164 };
4165
4166 /// the container to iterate
4167 typename IteratorType::reference container;
4168
4169 public:
4170 /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)4171 explicit iteration_proxy(typename IteratorType::reference cont)
4172 : container(cont) {}
4173
4174 /// return iterator begin (needed for range-based for)
begin()4175 iteration_proxy_internal begin() noexcept
4176 {
4177 return iteration_proxy_internal(container.begin());
4178 }
4179
4180 /// return iterator end (needed for range-based for)
end()4181 iteration_proxy_internal end() noexcept
4182 {
4183 return iteration_proxy_internal(container.end());
4184 }
4185 };
4186
4187 /*!
4188 @brief a template for a reverse iterator class
4189 @tparam Base the base iterator type to reverse. Valid types are @ref
4190 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
4191 create @ref const_reverse_iterator).
4192 @requirement The class satisfies the following concept requirements:
4193 -
4194 [RandomAccessIterator](http://en.cppreference.com/w/cpp/concept/RandomAccessIterator):
4195 The iterator that can be moved to point (forward and backward) to any
4196 element in constant time.
4197 - [OutputIterator](http://en.cppreference.com/w/cpp/concept/OutputIterator):
4198 It is possible to write to the pointed-to element (only if @a Base is
4199 @ref iterator).
4200 @since version 1.0.0
4201 */
4202 template<typename Base>
4203 class json_reverse_iterator : public std::reverse_iterator<Base>
4204 {
4205 public:
4206 using difference_type = std::ptrdiff_t;
4207 /// shortcut to the reverse iterator adaptor
4208 using base_iterator = std::reverse_iterator<Base>;
4209 /// the reference type for the pointed-to element
4210 using reference = typename Base::reference;
4211
4212 /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)4213 json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
4214 : base_iterator(it) {}
4215
4216 /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)4217 json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
4218
4219 /// post-increment (it++)
operator ++(int)4220 json_reverse_iterator operator++(int)
4221 {
4222 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
4223 }
4224
4225 /// pre-increment (++it)
operator ++()4226 json_reverse_iterator& operator++()
4227 {
4228 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
4229 }
4230
4231 /// post-decrement (it--)
operator --(int)4232 json_reverse_iterator operator--(int)
4233 {
4234 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
4235 }
4236
4237 /// pre-decrement (--it)
operator --()4238 json_reverse_iterator& operator--()
4239 {
4240 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
4241 }
4242
4243 /// add to iterator
operator +=(difference_type i)4244 json_reverse_iterator& operator+=(difference_type i)
4245 {
4246 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
4247 }
4248
4249 /// add to iterator
operator +(difference_type i) const4250 json_reverse_iterator operator+(difference_type i) const
4251 {
4252 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
4253 }
4254
4255 /// subtract from iterator
operator -(difference_type i) const4256 json_reverse_iterator operator-(difference_type i) const
4257 {
4258 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
4259 }
4260
4261 /// return difference
operator -(const json_reverse_iterator & other) const4262 difference_type operator-(const json_reverse_iterator& other) const
4263 {
4264 return base_iterator(*this) - base_iterator(other);
4265 }
4266
4267 /// access to successor
operator [](difference_type n) const4268 reference operator[](difference_type n) const
4269 {
4270 return *(this->operator+(n));
4271 }
4272
4273 /// return the key of an object iterator
key() const4274 auto key() const -> decltype(std::declval<Base>().key())
4275 {
4276 auto it = --this->base();
4277 return it.key();
4278 }
4279
4280 /// return the value of an iterator
value() const4281 reference value() const
4282 {
4283 auto it = --this->base();
4284 return it.operator * ();
4285 }
4286 };
4287
4288 /////////////////////
4289 // output adapters //
4290 /////////////////////
4291
4292 /// abstract output adapter interface
4293 template<typename CharType> struct output_adapter_protocol
4294 {
4295 virtual void write_character(CharType c) = 0;
4296 virtual void write_characters(const CharType* s, std::size_t length) = 0;
4297 virtual ~output_adapter_protocol() = default;
4298 };
4299
4300 /// a type to simplify interfaces
4301 template<typename CharType>
4302 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
4303
4304 /// output adapter for byte vectors
4305 template<typename CharType>
4306 class output_vector_adapter : public output_adapter_protocol<CharType>
4307 {
4308 public:
output_vector_adapter(std::vector<CharType> & vec)4309 explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
4310
write_character(CharType c)4311 void write_character(CharType c) override
4312 {
4313 v.push_back(c);
4314 }
4315
write_characters(const CharType * s,std::size_t length)4316 void write_characters(const CharType* s, std::size_t length) override
4317 {
4318 std::copy(s, s + length, std::back_inserter(v));
4319 }
4320
4321 private:
4322 std::vector<CharType>& v;
4323 };
4324
4325 /// output adapter for output streams
4326 template<typename CharType>
4327 class output_stream_adapter : public output_adapter_protocol<CharType>
4328 {
4329 public:
output_stream_adapter(std::basic_ostream<CharType> & s)4330 explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
4331
write_character(CharType c)4332 void write_character(CharType c) override
4333 {
4334 stream.put(c);
4335 }
4336
write_characters(const CharType * s,std::size_t length)4337 void write_characters(const CharType* s, std::size_t length) override
4338 {
4339 stream.write(s, static_cast<std::streamsize>(length));
4340 }
4341
4342 private:
4343 std::basic_ostream<CharType>& stream;
4344 };
4345
4346 /// output adapter for basic_string
4347 template<typename CharType>
4348 class output_string_adapter : public output_adapter_protocol<CharType>
4349 {
4350 public:
output_string_adapter(std::basic_string<CharType> & s)4351 explicit output_string_adapter(std::basic_string<CharType>& s) : str(s) {}
4352
write_character(CharType c)4353 void write_character(CharType c) override
4354 {
4355 str.push_back(c);
4356 }
4357
write_characters(const CharType * s,std::size_t length)4358 void write_characters(const CharType* s, std::size_t length) override
4359 {
4360 str.append(s, length);
4361 }
4362
4363 private:
4364 std::basic_string<CharType>& str;
4365 };
4366
4367 template<typename CharType>
4368 class output_adapter
4369 {
4370 public:
output_adapter(std::vector<CharType> & vec)4371 output_adapter(std::vector<CharType>& vec)
4372 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
4373
output_adapter(std::basic_ostream<CharType> & s)4374 output_adapter(std::basic_ostream<CharType>& s)
4375 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
4376
output_adapter(std::basic_string<CharType> & s)4377 output_adapter(std::basic_string<CharType>& s)
4378 : oa(std::make_shared<output_string_adapter<CharType>>(s)) {}
4379
operator output_adapter_t<CharType>()4380 operator output_adapter_t<CharType>()
4381 {
4382 return oa;
4383 }
4384
4385 private:
4386 output_adapter_t<CharType> oa = nullptr;
4387 };
4388
4389 //////////////////////////////
4390 // binary reader and writer //
4391 //////////////////////////////
4392
4393 /*!
4394 @brief deserialization of CBOR and MessagePack values
4395 */
4396 template<typename BasicJsonType>
4397 class binary_reader
4398 {
4399 using number_integer_t = typename BasicJsonType::number_integer_t;
4400 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
4401
4402 public:
4403 /*!
4404 @brief create a binary reader
4405 @param[in] adapter input adapter to read from
4406 */
binary_reader(input_adapter_t adapter)4407 explicit binary_reader(input_adapter_t adapter) : ia(std::move(adapter))
4408 {
4409 assert(ia);
4410 }
4411
4412 /*!
4413 @brief create a JSON value from CBOR input
4414 @param[in] strict whether to expect the input to be consumed completed
4415 @return JSON value created from CBOR input
4416 @throw parse_error.110 if input ended unexpectedly or the end of file was
4417 not reached when @a strict was set to true
4418 @throw parse_error.112 if unsupported byte was read
4419 */
parse_cbor(const bool strict)4420 BasicJsonType parse_cbor(const bool strict)
4421 {
4422 const auto res = parse_cbor_internal();
4423 if (strict)
4424 {
4425 get();
4426 check_eof(true);
4427 }
4428 return res;
4429 }
4430
4431 /*!
4432 @brief create a JSON value from MessagePack input
4433 @param[in] strict whether to expect the input to be consumed completed
4434 @return JSON value created from MessagePack input
4435 @throw parse_error.110 if input ended unexpectedly or the end of file was
4436 not reached when @a strict was set to true
4437 @throw parse_error.112 if unsupported byte was read
4438 */
parse_msgpack(const bool strict)4439 BasicJsonType parse_msgpack(const bool strict)
4440 {
4441 const auto res = parse_msgpack_internal();
4442 if (strict)
4443 {
4444 get();
4445 check_eof(true);
4446 }
4447 return res;
4448 }
4449
4450 /*!
4451 @brief determine system byte order
4452 @return true if and only if system's byte order is little endian
4453 @note from http://stackoverflow.com/a/1001328/266378
4454 */
little_endianess(int num=1)4455 static constexpr bool little_endianess(int num = 1) noexcept
4456 {
4457 return (*reinterpret_cast<char*>(&num) == 1);
4458 }
4459
4460 private:
4461 /*!
4462 @param[in] get_char whether a new character should be retrieved from the
4463 input (true, default) or whether the last read
4464 character should be considered instead
4465 */
parse_cbor_internal(const bool get_char=true)4466 BasicJsonType parse_cbor_internal(const bool get_char = true)
4467 {
4468 switch (get_char ? get() : current)
4469 {
4470 // EOF
4471 case std::char_traits<char>::eof():
4472 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4473
4474 // Integer 0x00..0x17 (0..23)
4475 case 0x00:
4476 case 0x01:
4477 case 0x02:
4478 case 0x03:
4479 case 0x04:
4480 case 0x05:
4481 case 0x06:
4482 case 0x07:
4483 case 0x08:
4484 case 0x09:
4485 case 0x0a:
4486 case 0x0b:
4487 case 0x0c:
4488 case 0x0d:
4489 case 0x0e:
4490 case 0x0f:
4491 case 0x10:
4492 case 0x11:
4493 case 0x12:
4494 case 0x13:
4495 case 0x14:
4496 case 0x15:
4497 case 0x16:
4498 case 0x17:
4499 return static_cast<number_unsigned_t>(current);
4500
4501 case 0x18: // Unsigned integer (one-byte uint8_t follows)
4502 return get_number<uint8_t>();
4503
4504 case 0x19: // Unsigned integer (two-byte uint16_t follows)
4505 return get_number<uint16_t>();
4506
4507 case 0x1a: // Unsigned integer (four-byte uint32_t follows)
4508 return get_number<uint32_t>();
4509
4510 case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
4511 return get_number<uint64_t>();
4512
4513 // Negative integer -1-0x00..-1-0x17 (-1..-24)
4514 case 0x20:
4515 case 0x21:
4516 case 0x22:
4517 case 0x23:
4518 case 0x24:
4519 case 0x25:
4520 case 0x26:
4521 case 0x27:
4522 case 0x28:
4523 case 0x29:
4524 case 0x2a:
4525 case 0x2b:
4526 case 0x2c:
4527 case 0x2d:
4528 case 0x2e:
4529 case 0x2f:
4530 case 0x30:
4531 case 0x31:
4532 case 0x32:
4533 case 0x33:
4534 case 0x34:
4535 case 0x35:
4536 case 0x36:
4537 case 0x37:
4538 return static_cast<int8_t>(0x20 - 1 - current);
4539
4540 case 0x38: // Negative integer (one-byte uint8_t follows)
4541 {
4542 // must be uint8_t !
4543 return static_cast<number_integer_t>(-1) - get_number<uint8_t>();
4544 }
4545
4546 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
4547 {
4548 return static_cast<number_integer_t>(-1) - get_number<uint16_t>();
4549 }
4550
4551 case 0x3a: // Negative integer -1-n (four-byte uint32_t follows)
4552 {
4553 return static_cast<number_integer_t>(-1) - get_number<uint32_t>();
4554 }
4555
4556 case 0x3b: // Negative integer -1-n (eight-byte uint64_t follows)
4557 {
4558 return static_cast<number_integer_t>(-1) -
4559 static_cast<number_integer_t>(get_number<uint64_t>());
4560 }
4561
4562 // UTF-8 string (0x00..0x17 bytes follow)
4563 case 0x60:
4564 case 0x61:
4565 case 0x62:
4566 case 0x63:
4567 case 0x64:
4568 case 0x65:
4569 case 0x66:
4570 case 0x67:
4571 case 0x68:
4572 case 0x69:
4573 case 0x6a:
4574 case 0x6b:
4575 case 0x6c:
4576 case 0x6d:
4577 case 0x6e:
4578 case 0x6f:
4579 case 0x70:
4580 case 0x71:
4581 case 0x72:
4582 case 0x73:
4583 case 0x74:
4584 case 0x75:
4585 case 0x76:
4586 case 0x77:
4587 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
4588 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
4589 case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
4590 case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
4591 case 0x7f: // UTF-8 string (indefinite length)
4592 {
4593 return get_cbor_string();
4594 }
4595
4596 // array (0x00..0x17 data items follow)
4597 case 0x80:
4598 case 0x81:
4599 case 0x82:
4600 case 0x83:
4601 case 0x84:
4602 case 0x85:
4603 case 0x86:
4604 case 0x87:
4605 case 0x88:
4606 case 0x89:
4607 case 0x8a:
4608 case 0x8b:
4609 case 0x8c:
4610 case 0x8d:
4611 case 0x8e:
4612 case 0x8f:
4613 case 0x90:
4614 case 0x91:
4615 case 0x92:
4616 case 0x93:
4617 case 0x94:
4618 case 0x95:
4619 case 0x96:
4620 case 0x97:
4621 {
4622 return get_cbor_array(current & 0x1f);
4623 }
4624
4625 case 0x98: // array (one-byte uint8_t for n follows)
4626 {
4627 return get_cbor_array(get_number<uint8_t>());
4628 }
4629
4630 case 0x99: // array (two-byte uint16_t for n follow)
4631 {
4632 return get_cbor_array(get_number<uint16_t>());
4633 }
4634
4635 case 0x9a: // array (four-byte uint32_t for n follow)
4636 {
4637 return get_cbor_array(get_number<uint32_t>());
4638 }
4639
4640 case 0x9b: // array (eight-byte uint64_t for n follow)
4641 {
4642 return get_cbor_array(get_number<uint64_t>());
4643 }
4644
4645 case 0x9f: // array (indefinite length)
4646 {
4647 BasicJsonType result = value_t::array;
4648 while (get() != 0xff)
4649 {
4650 result.push_back(parse_cbor_internal(false));
4651 }
4652 return result;
4653 }
4654
4655 // map (0x00..0x17 pairs of data items follow)
4656 case 0xa0:
4657 case 0xa1:
4658 case 0xa2:
4659 case 0xa3:
4660 case 0xa4:
4661 case 0xa5:
4662 case 0xa6:
4663 case 0xa7:
4664 case 0xa8:
4665 case 0xa9:
4666 case 0xaa:
4667 case 0xab:
4668 case 0xac:
4669 case 0xad:
4670 case 0xae:
4671 case 0xaf:
4672 case 0xb0:
4673 case 0xb1:
4674 case 0xb2:
4675 case 0xb3:
4676 case 0xb4:
4677 case 0xb5:
4678 case 0xb6:
4679 case 0xb7:
4680 {
4681 return get_cbor_object(current & 0x1f);
4682 }
4683
4684 case 0xb8: // map (one-byte uint8_t for n follows)
4685 {
4686 return get_cbor_object(get_number<uint8_t>());
4687 }
4688
4689 case 0xb9: // map (two-byte uint16_t for n follow)
4690 {
4691 return get_cbor_object(get_number<uint16_t>());
4692 }
4693
4694 case 0xba: // map (four-byte uint32_t for n follow)
4695 {
4696 return get_cbor_object(get_number<uint32_t>());
4697 }
4698
4699 case 0xbb: // map (eight-byte uint64_t for n follow)
4700 {
4701 return get_cbor_object(get_number<uint64_t>());
4702 }
4703
4704 case 0xbf: // map (indefinite length)
4705 {
4706 BasicJsonType result = value_t::object;
4707 while (get() != 0xff)
4708 {
4709 auto key = get_cbor_string();
4710 result[key] = parse_cbor_internal();
4711 }
4712 return result;
4713 }
4714
4715 case 0xf4: // false
4716 {
4717 return false;
4718 }
4719
4720 case 0xf5: // true
4721 {
4722 return true;
4723 }
4724
4725 case 0xf6: // null
4726 {
4727 return value_t::null;
4728 }
4729
4730 case 0xf9: // Half-Precision Float (two-byte IEEE 754)
4731 {
4732 const int byte1 = get();
4733 check_eof();
4734 const int byte2 = get();
4735 check_eof();
4736
4737 // code from RFC 7049, Appendix D, Figure 3:
4738 // As half-precision floating-point numbers were only added
4739 // to IEEE 754 in 2008, today's programming platforms often
4740 // still only have limited support for them. It is very
4741 // easy to include at least decoding support for them even
4742 // without such support. An example of a small decoder for
4743 // half-precision floating-point numbers in the C language
4744 // is shown in Fig. 3.
4745 const int half = (byte1 << 8) + byte2;
4746 const int exp = (half >> 10) & 0x1f;
4747 const int mant = half & 0x3ff;
4748 double val;
4749 if (exp == 0)
4750 {
4751 val = std::ldexp(mant, -24);
4752 }
4753 else if (exp != 31)
4754 {
4755 val = std::ldexp(mant + 1024, exp - 25);
4756 }
4757 else
4758 {
4759 val = (mant == 0) ? std::numeric_limits<double>::infinity()
4760 : std::numeric_limits<double>::quiet_NaN();
4761 }
4762 return (half & 0x8000) != 0 ? -val : val;
4763 }
4764
4765 case 0xfa: // Single-Precision Float (four-byte IEEE 754)
4766 {
4767 return get_number<float>();
4768 }
4769
4770 case 0xfb: // Double-Precision Float (eight-byte IEEE 754)
4771 {
4772 return get_number<double>();
4773 }
4774
4775 default: // anything else (0xFF is handled inside the other types)
4776 {
4777 std::stringstream ss;
4778 ss << std::setw(2) << std::setfill('0') << std::hex << current;
4779 JSON_THROW(parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + ss.str()));
4780 }
4781 }
4782 }
4783
parse_msgpack_internal()4784 BasicJsonType parse_msgpack_internal()
4785 {
4786 switch (get())
4787 {
4788 // EOF
4789 case std::char_traits<char>::eof():
4790 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
4791
4792 // positive fixint
4793 case 0x00:
4794 case 0x01:
4795 case 0x02:
4796 case 0x03:
4797 case 0x04:
4798 case 0x05:
4799 case 0x06:
4800 case 0x07:
4801 case 0x08:
4802 case 0x09:
4803 case 0x0a:
4804 case 0x0b:
4805 case 0x0c:
4806 case 0x0d:
4807 case 0x0e:
4808 case 0x0f:
4809 case 0x10:
4810 case 0x11:
4811 case 0x12:
4812 case 0x13:
4813 case 0x14:
4814 case 0x15:
4815 case 0x16:
4816 case 0x17:
4817 case 0x18:
4818 case 0x19:
4819 case 0x1a:
4820 case 0x1b:
4821 case 0x1c:
4822 case 0x1d:
4823 case 0x1e:
4824 case 0x1f:
4825 case 0x20:
4826 case 0x21:
4827 case 0x22:
4828 case 0x23:
4829 case 0x24:
4830 case 0x25:
4831 case 0x26:
4832 case 0x27:
4833 case 0x28:
4834 case 0x29:
4835 case 0x2a:
4836 case 0x2b:
4837 case 0x2c:
4838 case 0x2d:
4839 case 0x2e:
4840 case 0x2f:
4841 case 0x30:
4842 case 0x31:
4843 case 0x32:
4844 case 0x33:
4845 case 0x34:
4846 case 0x35:
4847 case 0x36:
4848 case 0x37:
4849 case 0x38:
4850 case 0x39:
4851 case 0x3a:
4852 case 0x3b:
4853 case 0x3c:
4854 case 0x3d:
4855 case 0x3e:
4856 case 0x3f:
4857 case 0x40:
4858 case 0x41:
4859 case 0x42:
4860 case 0x43:
4861 case 0x44:
4862 case 0x45:
4863 case 0x46:
4864 case 0x47:
4865 case 0x48:
4866 case 0x49:
4867 case 0x4a:
4868 case 0x4b:
4869 case 0x4c:
4870 case 0x4d:
4871 case 0x4e:
4872 case 0x4f:
4873 case 0x50:
4874 case 0x51:
4875 case 0x52:
4876 case 0x53:
4877 case 0x54:
4878 case 0x55:
4879 case 0x56:
4880 case 0x57:
4881 case 0x58:
4882 case 0x59:
4883 case 0x5a:
4884 case 0x5b:
4885 case 0x5c:
4886 case 0x5d:
4887 case 0x5e:
4888 case 0x5f:
4889 case 0x60:
4890 case 0x61:
4891 case 0x62:
4892 case 0x63:
4893 case 0x64:
4894 case 0x65:
4895 case 0x66:
4896 case 0x67:
4897 case 0x68:
4898 case 0x69:
4899 case 0x6a:
4900 case 0x6b:
4901 case 0x6c:
4902 case 0x6d:
4903 case 0x6e:
4904 case 0x6f:
4905 case 0x70:
4906 case 0x71:
4907 case 0x72:
4908 case 0x73:
4909 case 0x74:
4910 case 0x75:
4911 case 0x76:
4912 case 0x77:
4913 case 0x78:
4914 case 0x79:
4915 case 0x7a:
4916 case 0x7b:
4917 case 0x7c:
4918 case 0x7d:
4919 case 0x7e:
4920 case 0x7f:
4921 return static_cast<number_unsigned_t>(current);
4922
4923 // fixmap
4924 case 0x80:
4925 case 0x81:
4926 case 0x82:
4927 case 0x83:
4928 case 0x84:
4929 case 0x85:
4930 case 0x86:
4931 case 0x87:
4932 case 0x88:
4933 case 0x89:
4934 case 0x8a:
4935 case 0x8b:
4936 case 0x8c:
4937 case 0x8d:
4938 case 0x8e:
4939 case 0x8f:
4940 {
4941 return get_msgpack_object(current & 0x0f);
4942 }
4943
4944 // fixarray
4945 case 0x90:
4946 case 0x91:
4947 case 0x92:
4948 case 0x93:
4949 case 0x94:
4950 case 0x95:
4951 case 0x96:
4952 case 0x97:
4953 case 0x98:
4954 case 0x99:
4955 case 0x9a:
4956 case 0x9b:
4957 case 0x9c:
4958 case 0x9d:
4959 case 0x9e:
4960 case 0x9f:
4961 {
4962 return get_msgpack_array(current & 0x0f);
4963 }
4964
4965 // fixstr
4966 case 0xa0:
4967 case 0xa1:
4968 case 0xa2:
4969 case 0xa3:
4970 case 0xa4:
4971 case 0xa5:
4972 case 0xa6:
4973 case 0xa7:
4974 case 0xa8:
4975 case 0xa9:
4976 case 0xaa:
4977 case 0xab:
4978 case 0xac:
4979 case 0xad:
4980 case 0xae:
4981 case 0xaf:
4982 case 0xb0:
4983 case 0xb1:
4984 case 0xb2:
4985 case 0xb3:
4986 case 0xb4:
4987 case 0xb5:
4988 case 0xb6:
4989 case 0xb7:
4990 case 0xb8:
4991 case 0xb9:
4992 case 0xba:
4993 case 0xbb:
4994 case 0xbc:
4995 case 0xbd:
4996 case 0xbe:
4997 case 0xbf:
4998 return get_msgpack_string();
4999
5000 case 0xc0: // nil
5001 return value_t::null;
5002
5003 case 0xc2: // false
5004 return false;
5005
5006 case 0xc3: // true
5007 return true;
5008
5009 case 0xca: // float 32
5010 return get_number<float>();
5011
5012 case 0xcb: // float 64
5013 return get_number<double>();
5014
5015 case 0xcc: // uint 8
5016 return get_number<uint8_t>();
5017
5018 case 0xcd: // uint 16
5019 return get_number<uint16_t>();
5020
5021 case 0xce: // uint 32
5022 return get_number<uint32_t>();
5023
5024 case 0xcf: // uint 64
5025 return get_number<uint64_t>();
5026
5027 case 0xd0: // int 8
5028 return get_number<int8_t>();
5029
5030 case 0xd1: // int 16
5031 return get_number<int16_t>();
5032
5033 case 0xd2: // int 32
5034 return get_number<int32_t>();
5035
5036 case 0xd3: // int 64
5037 return get_number<int64_t>();
5038
5039 case 0xd9: // str 8
5040 case 0xda: // str 16
5041 case 0xdb: // str 32
5042 return get_msgpack_string();
5043
5044 case 0xdc: // array 16
5045 {
5046 return get_msgpack_array(get_number<uint16_t>());
5047 }
5048
5049 case 0xdd: // array 32
5050 {
5051 return get_msgpack_array(get_number<uint32_t>());
5052 }
5053
5054 case 0xde: // map 16
5055 {
5056 return get_msgpack_object(get_number<uint16_t>());
5057 }
5058
5059 case 0xdf: // map 32
5060 {
5061 return get_msgpack_object(get_number<uint32_t>());
5062 }
5063
5064 // positive fixint
5065 case 0xe0:
5066 case 0xe1:
5067 case 0xe2:
5068 case 0xe3:
5069 case 0xe4:
5070 case 0xe5:
5071 case 0xe6:
5072 case 0xe7:
5073 case 0xe8:
5074 case 0xe9:
5075 case 0xea:
5076 case 0xeb:
5077 case 0xec:
5078 case 0xed:
5079 case 0xee:
5080 case 0xef:
5081 case 0xf0:
5082 case 0xf1:
5083 case 0xf2:
5084 case 0xf3:
5085 case 0xf4:
5086 case 0xf5:
5087 case 0xf6:
5088 case 0xf7:
5089 case 0xf8:
5090 case 0xf9:
5091 case 0xfa:
5092 case 0xfb:
5093 case 0xfc:
5094 case 0xfd:
5095 case 0xfe:
5096 case 0xff:
5097 return static_cast<int8_t>(current);
5098
5099 default: // anything else
5100 {
5101 std::stringstream ss;
5102 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5103 JSON_THROW(parse_error::create(112, chars_read,
5104 "error reading MessagePack; last byte: 0x" + ss.str()));
5105 }
5106 }
5107 }
5108
5109 /*!
5110 @brief get next character from the input
5111 This function provides the interface to the used input adapter. It does
5112 not throw in case the input reached EOF, but returns a -'ve valued
5113 `std::char_traits<char>::eof()` in that case.
5114 @return character read from the input
5115 */
get()5116 int get()
5117 {
5118 ++chars_read;
5119 return (current = ia->get_character());
5120 }
5121
5122 /*
5123 @brief read a number from the input
5124 @tparam NumberType the type of the number
5125 @return number of type @a NumberType
5126 @note This function needs to respect the system's endianess, because
5127 bytes in CBOR and MessagePack are stored in network order (big
5128 endian) and therefore need reordering on little endian systems.
5129 @throw parse_error.110 if input has less than `sizeof(NumberType)` bytes
5130 */
get_number()5131 template<typename NumberType> NumberType get_number()
5132 {
5133 // step 1: read input into array with system's byte order
5134 std::array<uint8_t, sizeof(NumberType)> vec;
5135 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
5136 {
5137 get();
5138 check_eof();
5139
5140 // reverse byte order prior to conversion if necessary
5141 if (is_little_endian)
5142 {
5143 vec[sizeof(NumberType) - i - 1] = static_cast<uint8_t>(current);
5144 }
5145 else
5146 {
5147 vec[i] = static_cast<uint8_t>(current); // LCOV_EXCL_LINE
5148 }
5149 }
5150
5151 // step 2: convert array into number of type T and return
5152 NumberType result;
5153 std::memcpy(&result, vec.data(), sizeof(NumberType));
5154 return result;
5155 }
5156
5157 /*!
5158 @brief create a string by reading characters from the input
5159 @param[in] len number of bytes to read
5160 @note We can not reserve @a len bytes for the result, because @a len
5161 may be too large. Usually, @ref check_eof() detects the end of
5162 the input before we run out of string memory.
5163 @return string created by reading @a len bytes
5164 @throw parse_error.110 if input has less than @a len bytes
5165 */
5166 template<typename NumberType>
get_string(const NumberType len)5167 std::string get_string(const NumberType len)
5168 {
5169 std::string result;
5170 std::generate_n(std::back_inserter(result), len, [this]()
5171 {
5172 get();
5173 check_eof();
5174 return static_cast<char>(current);
5175 });
5176 return result;
5177 }
5178
5179 /*!
5180 @brief reads a CBOR string
5181 This function first reads starting bytes to determine the expected
5182 string length and then copies this number of bytes into a string.
5183 Additionally, CBOR's strings with indefinite lengths are supported.
5184 @return string
5185 @throw parse_error.110 if input ended
5186 @throw parse_error.113 if an unexpected byte is read
5187 */
get_cbor_string()5188 std::string get_cbor_string()
5189 {
5190 check_eof();
5191
5192 switch (current)
5193 {
5194 // UTF-8 string (0x00..0x17 bytes follow)
5195 case 0x60:
5196 case 0x61:
5197 case 0x62:
5198 case 0x63:
5199 case 0x64:
5200 case 0x65:
5201 case 0x66:
5202 case 0x67:
5203 case 0x68:
5204 case 0x69:
5205 case 0x6a:
5206 case 0x6b:
5207 case 0x6c:
5208 case 0x6d:
5209 case 0x6e:
5210 case 0x6f:
5211 case 0x70:
5212 case 0x71:
5213 case 0x72:
5214 case 0x73:
5215 case 0x74:
5216 case 0x75:
5217 case 0x76:
5218 case 0x77:
5219 {
5220 return get_string(current & 0x1f);
5221 }
5222
5223 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
5224 {
5225 return get_string(get_number<uint8_t>());
5226 }
5227
5228 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
5229 {
5230 return get_string(get_number<uint16_t>());
5231 }
5232
5233 case 0x7a: // UTF-8 string (four-byte uint32_t for n follow)
5234 {
5235 return get_string(get_number<uint32_t>());
5236 }
5237
5238 case 0x7b: // UTF-8 string (eight-byte uint64_t for n follow)
5239 {
5240 return get_string(get_number<uint64_t>());
5241 }
5242
5243 case 0x7f: // UTF-8 string (indefinite length)
5244 {
5245 std::string result;
5246 while (get() != 0xff)
5247 {
5248 check_eof();
5249 result.push_back(static_cast<char>(current));
5250 }
5251 return result;
5252 }
5253
5254 default:
5255 {
5256 std::stringstream ss;
5257 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5258 JSON_THROW(parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + ss.str()));
5259 }
5260 }
5261 }
5262
5263 template<typename NumberType>
get_cbor_array(const NumberType len)5264 BasicJsonType get_cbor_array(const NumberType len)
5265 {
5266 BasicJsonType result = value_t::array;
5267 std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5268 {
5269 return parse_cbor_internal();
5270 });
5271 return result;
5272 }
5273
5274 template<typename NumberType>
get_cbor_object(const NumberType len)5275 BasicJsonType get_cbor_object(const NumberType len)
5276 {
5277 BasicJsonType result = value_t::object;
5278 std::generate_n(std::inserter(*result.m_value.object,
5279 result.m_value.object->end()),
5280 len, [this]()
5281 {
5282 get();
5283 auto key = get_cbor_string();
5284 auto val = parse_cbor_internal();
5285 return std::make_pair(std::move(key), std::move(val));
5286 });
5287 return result;
5288 }
5289
5290 /*!
5291 @brief reads a MessagePack string
5292 This function first reads starting bytes to determine the expected
5293 string length and then copies this number of bytes into a string.
5294 @return string
5295 @throw parse_error.110 if input ended
5296 @throw parse_error.113 if an unexpected byte is read
5297 */
get_msgpack_string()5298 std::string get_msgpack_string()
5299 {
5300 check_eof();
5301
5302 switch (current)
5303 {
5304 // fixstr
5305 case 0xa0:
5306 case 0xa1:
5307 case 0xa2:
5308 case 0xa3:
5309 case 0xa4:
5310 case 0xa5:
5311 case 0xa6:
5312 case 0xa7:
5313 case 0xa8:
5314 case 0xa9:
5315 case 0xaa:
5316 case 0xab:
5317 case 0xac:
5318 case 0xad:
5319 case 0xae:
5320 case 0xaf:
5321 case 0xb0:
5322 case 0xb1:
5323 case 0xb2:
5324 case 0xb3:
5325 case 0xb4:
5326 case 0xb5:
5327 case 0xb6:
5328 case 0xb7:
5329 case 0xb8:
5330 case 0xb9:
5331 case 0xba:
5332 case 0xbb:
5333 case 0xbc:
5334 case 0xbd:
5335 case 0xbe:
5336 case 0xbf:
5337 {
5338 return get_string(current & 0x1f);
5339 }
5340
5341 case 0xd9: // str 8
5342 {
5343 return get_string(get_number<uint8_t>());
5344 }
5345
5346 case 0xda: // str 16
5347 {
5348 return get_string(get_number<uint16_t>());
5349 }
5350
5351 case 0xdb: // str 32
5352 {
5353 return get_string(get_number<uint32_t>());
5354 }
5355
5356 default:
5357 {
5358 std::stringstream ss;
5359 ss << std::setw(2) << std::setfill('0') << std::hex << current;
5360 JSON_THROW(parse_error::create(113, chars_read,
5361 "expected a MessagePack string; last byte: 0x" + ss.str()));
5362 }
5363 }
5364 }
5365
5366 template<typename NumberType>
get_msgpack_array(const NumberType len)5367 BasicJsonType get_msgpack_array(const NumberType len)
5368 {
5369 BasicJsonType result = value_t::array;
5370 std::generate_n(std::back_inserter(*result.m_value.array), len, [this]()
5371 {
5372 return parse_msgpack_internal();
5373 });
5374 return result;
5375 }
5376
5377 template<typename NumberType>
get_msgpack_object(const NumberType len)5378 BasicJsonType get_msgpack_object(const NumberType len)
5379 {
5380 BasicJsonType result = value_t::object;
5381 std::generate_n(std::inserter(*result.m_value.object,
5382 result.m_value.object->end()),
5383 len, [this]()
5384 {
5385 get();
5386 auto key = get_msgpack_string();
5387 auto val = parse_msgpack_internal();
5388 return std::make_pair(std::move(key), std::move(val));
5389 });
5390 return result;
5391 }
5392
5393 /*!
5394 @brief check if input ended
5395 @throw parse_error.110 if input ended
5396 */
check_eof(const bool expect_eof=false) const5397 void check_eof(const bool expect_eof = false) const
5398 {
5399 if (expect_eof)
5400 {
5401 if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
5402 {
5403 JSON_THROW(parse_error::create(110, chars_read, "expected end of input"));
5404 }
5405 }
5406 else
5407 {
5408 if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
5409 {
5410 JSON_THROW(parse_error::create(110, chars_read, "unexpected end of input"));
5411 }
5412 }
5413 }
5414
5415 private:
5416 /// input adapter
5417 input_adapter_t ia = nullptr;
5418
5419 /// the current character
5420 int current = std::char_traits<char>::eof();
5421
5422 /// the number of characters read
5423 std::size_t chars_read = 0;
5424
5425 /// whether we can assume little endianess
5426 const bool is_little_endian = little_endianess();
5427 };
5428
5429 /*!
5430 @brief serialization to CBOR and MessagePack values
5431 */
5432 template<typename BasicJsonType, typename CharType>
5433 class binary_writer
5434 {
5435 public:
5436 /*!
5437 @brief create a binary writer
5438 @param[in] adapter output adapter to write to
5439 */
binary_writer(output_adapter_t<CharType> adapter)5440 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(adapter)
5441 {
5442 assert(oa);
5443 }
5444
5445 /*!
5446 @brief[in] j JSON value to serialize
5447 */
write_cbor(const BasicJsonType & j)5448 void write_cbor(const BasicJsonType& j)
5449 {
5450 switch (j.type())
5451 {
5452 case value_t::null:
5453 {
5454 oa->write_character(static_cast<CharType>(0xf6));
5455 break;
5456 }
5457
5458 case value_t::boolean:
5459 {
5460 oa->write_character(j.m_value.boolean
5461 ? static_cast<CharType>(0xf5)
5462 : static_cast<CharType>(0xf4));
5463 break;
5464 }
5465
5466 case value_t::number_integer:
5467 {
5468 if (j.m_value.number_integer >= 0)
5469 {
5470 // CBOR does not differentiate between positive signed
5471 // integers and unsigned integers. Therefore, we used the
5472 // code from the value_t::number_unsigned case here.
5473 if (j.m_value.number_integer <= 0x17)
5474 {
5475 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5476 }
5477 else if (j.m_value.number_integer <= (std::numeric_limits<uint8_t>::max)())
5478 {
5479 oa->write_character(static_cast<CharType>(0x18));
5480 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5481 }
5482 else if (j.m_value.number_integer <= (std::numeric_limits<uint16_t>::max)())
5483 {
5484 oa->write_character(static_cast<CharType>(0x19));
5485 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5486 }
5487 else if (j.m_value.number_integer <= (std::numeric_limits<uint32_t>::max)())
5488 {
5489 oa->write_character(static_cast<CharType>(0x1a));
5490 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5491 }
5492 else
5493 {
5494 oa->write_character(static_cast<CharType>(0x1b));
5495 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5496 }
5497 }
5498 else
5499 {
5500 // The conversions below encode the sign in the first
5501 // byte, and the value is converted to a positive number.
5502 const auto positive_number = -1 - j.m_value.number_integer;
5503 if (j.m_value.number_integer >= -24)
5504 {
5505 write_number(static_cast<uint8_t>(0x20 + positive_number));
5506 }
5507 else if (positive_number <= (std::numeric_limits<uint8_t>::max)())
5508 {
5509 oa->write_character(static_cast<CharType>(0x38));
5510 write_number(static_cast<uint8_t>(positive_number));
5511 }
5512 else if (positive_number <= (std::numeric_limits<uint16_t>::max)())
5513 {
5514 oa->write_character(static_cast<CharType>(0x39));
5515 write_number(static_cast<uint16_t>(positive_number));
5516 }
5517 else if (positive_number <= (std::numeric_limits<uint32_t>::max)())
5518 {
5519 oa->write_character(static_cast<CharType>(0x3a));
5520 write_number(static_cast<uint32_t>(positive_number));
5521 }
5522 else
5523 {
5524 oa->write_character(static_cast<CharType>(0x3b));
5525 write_number(static_cast<uint64_t>(positive_number));
5526 }
5527 }
5528 break;
5529 }
5530
5531 case value_t::number_unsigned:
5532 {
5533 if (j.m_value.number_unsigned <= 0x17)
5534 {
5535 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5536 }
5537 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5538 {
5539 oa->write_character(static_cast<CharType>(0x18));
5540 write_number(static_cast<uint8_t>(j.m_value.number_unsigned));
5541 }
5542 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5543 {
5544 oa->write_character(static_cast<CharType>(0x19));
5545 write_number(static_cast<uint16_t>(j.m_value.number_unsigned));
5546 }
5547 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5548 {
5549 oa->write_character(static_cast<CharType>(0x1a));
5550 write_number(static_cast<uint32_t>(j.m_value.number_unsigned));
5551 }
5552 else
5553 {
5554 oa->write_character(static_cast<CharType>(0x1b));
5555 write_number(static_cast<uint64_t>(j.m_value.number_unsigned));
5556 }
5557 break;
5558 }
5559
5560 case value_t::number_float: // Double-Precision Float
5561 {
5562 oa->write_character(static_cast<CharType>(0xfb));
5563 write_number(j.m_value.number_float);
5564 break;
5565 }
5566
5567 case value_t::string:
5568 {
5569 // step 1: write control byte and the string length
5570 const auto N = j.m_value.string->size();
5571 if (N <= 0x17)
5572 {
5573 write_number(static_cast<uint8_t>(0x60 + N));
5574 }
5575 else if (N <= 0xff)
5576 {
5577 oa->write_character(static_cast<CharType>(0x78));
5578 write_number(static_cast<uint8_t>(N));
5579 }
5580 else if (N <= 0xffff)
5581 {
5582 oa->write_character(static_cast<CharType>(0x79));
5583 write_number(static_cast<uint16_t>(N));
5584 }
5585 else if (N <= 0xffffffff)
5586 {
5587 oa->write_character(static_cast<CharType>(0x7a));
5588 write_number(static_cast<uint32_t>(N));
5589 }
5590 // LCOV_EXCL_START
5591 else if (N <= 0xffffffffffffffff)
5592 {
5593 oa->write_character(static_cast<CharType>(0x7b));
5594 write_number(static_cast<uint64_t>(N));
5595 }
5596 // LCOV_EXCL_STOP
5597
5598 // step 2: write the string
5599 oa->write_characters(
5600 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
5601 j.m_value.string->size());
5602 break;
5603 }
5604
5605 case value_t::array:
5606 {
5607 // step 1: write control byte and the array size
5608 const auto N = j.m_value.array->size();
5609 if (N <= 0x17)
5610 {
5611 write_number(static_cast<uint8_t>(0x80 + N));
5612 }
5613 else if (N <= 0xff)
5614 {
5615 oa->write_character(static_cast<CharType>(0x98));
5616 write_number(static_cast<uint8_t>(N));
5617 }
5618 else if (N <= 0xffff)
5619 {
5620 oa->write_character(static_cast<CharType>(0x99));
5621 write_number(static_cast<uint16_t>(N));
5622 }
5623 else if (N <= 0xffffffff)
5624 {
5625 oa->write_character(static_cast<CharType>(0x9a));
5626 write_number(static_cast<uint32_t>(N));
5627 }
5628 // LCOV_EXCL_START
5629 else if (N <= 0xffffffffffffffff)
5630 {
5631 oa->write_character(static_cast<CharType>(0x9b));
5632 write_number(static_cast<uint64_t>(N));
5633 }
5634 // LCOV_EXCL_STOP
5635
5636 // step 2: write each element
5637 for (const auto& el : *j.m_value.array)
5638 {
5639 write_cbor(el);
5640 }
5641 break;
5642 }
5643
5644 case value_t::object:
5645 {
5646 // step 1: write control byte and the object size
5647 const auto N = j.m_value.object->size();
5648 if (N <= 0x17)
5649 {
5650 write_number(static_cast<uint8_t>(0xa0 + N));
5651 }
5652 else if (N <= 0xff)
5653 {
5654 oa->write_character(static_cast<CharType>(0xb8));
5655 write_number(static_cast<uint8_t>(N));
5656 }
5657 else if (N <= 0xffff)
5658 {
5659 oa->write_character(static_cast<CharType>(0xb9));
5660 write_number(static_cast<uint16_t>(N));
5661 }
5662 else if (N <= 0xffffffff)
5663 {
5664 oa->write_character(static_cast<CharType>(0xba));
5665 write_number(static_cast<uint32_t>(N));
5666 }
5667 // LCOV_EXCL_START
5668 else if (N <= 0xffffffffffffffff)
5669 {
5670 oa->write_character(static_cast<CharType>(0xbb));
5671 write_number(static_cast<uint64_t>(N));
5672 }
5673 // LCOV_EXCL_STOP
5674
5675 // step 2: write each element
5676 for (const auto& el : *j.m_value.object)
5677 {
5678 write_cbor(el.first);
5679 write_cbor(el.second);
5680 }
5681 break;
5682 }
5683
5684 default:
5685 break;
5686 }
5687 }
5688
5689 /*!
5690 @brief[in] j JSON value to serialize
5691 */
write_msgpack(const BasicJsonType & j)5692 void write_msgpack(const BasicJsonType& j)
5693 {
5694 switch (j.type())
5695 {
5696 case value_t::null: // nil
5697 {
5698 oa->write_character(static_cast<CharType>(0xc0));
5699 break;
5700 }
5701
5702 case value_t::boolean: // true and false
5703 {
5704 oa->write_character(j.m_value.boolean
5705 ? static_cast<CharType>(0xc3)
5706 : static_cast<CharType>(0xc2));
5707 break;
5708 }
5709
5710 case value_t::number_integer:
5711 {
5712 if (j.m_value.number_integer >= 0)
5713 {
5714 // MessagePack does not differentiate between positive
5715 // signed integers and unsigned integers. Therefore, we used
5716 // the code from the value_t::number_unsigned case here.
5717 if (j.m_value.number_unsigned < 128)
5718 {
5719 // positive fixnum
5720 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5721 }
5722 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5723 {
5724 // uint 8
5725 oa->write_character(static_cast<CharType>(0xcc));
5726 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5727 }
5728 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5729 {
5730 // uint 16
5731 oa->write_character(static_cast<CharType>(0xcd));
5732 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5733 }
5734 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5735 {
5736 // uint 32
5737 oa->write_character(static_cast<CharType>(0xce));
5738 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5739 }
5740 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5741 {
5742 // uint 64
5743 oa->write_character(static_cast<CharType>(0xcf));
5744 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5745 }
5746 }
5747 else
5748 {
5749 if (j.m_value.number_integer >= -32)
5750 {
5751 // negative fixnum
5752 write_number(static_cast<int8_t>(j.m_value.number_integer));
5753 }
5754 else if (j.m_value.number_integer >= (std::numeric_limits<int8_t>::min)() and
5755 j.m_value.number_integer <= (std::numeric_limits<int8_t>::max)())
5756 {
5757 // int 8
5758 oa->write_character(static_cast<CharType>(0xd0));
5759 write_number(static_cast<int8_t>(j.m_value.number_integer));
5760 }
5761 else if (j.m_value.number_integer >= (std::numeric_limits<int16_t>::min)() and
5762 j.m_value.number_integer <= (std::numeric_limits<int16_t>::max)())
5763 {
5764 // int 16
5765 oa->write_character(static_cast<CharType>(0xd1));
5766 write_number(static_cast<int16_t>(j.m_value.number_integer));
5767 }
5768 else if (j.m_value.number_integer >= (std::numeric_limits<int32_t>::min)() and
5769 j.m_value.number_integer <= (std::numeric_limits<int32_t>::max)())
5770 {
5771 // int 32
5772 oa->write_character(static_cast<CharType>(0xd2));
5773 write_number(static_cast<int32_t>(j.m_value.number_integer));
5774 }
5775 else if (j.m_value.number_integer >= (std::numeric_limits<int64_t>::min)() and
5776 j.m_value.number_integer <= (std::numeric_limits<int64_t>::max)())
5777 {
5778 // int 64
5779 oa->write_character(static_cast<CharType>(0xd3));
5780 write_number(static_cast<int64_t>(j.m_value.number_integer));
5781 }
5782 }
5783 break;
5784 }
5785
5786 case value_t::number_unsigned:
5787 {
5788 if (j.m_value.number_unsigned < 128)
5789 {
5790 // positive fixnum
5791 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5792 }
5793 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint8_t>::max)())
5794 {
5795 // uint 8
5796 oa->write_character(static_cast<CharType>(0xcc));
5797 write_number(static_cast<uint8_t>(j.m_value.number_integer));
5798 }
5799 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint16_t>::max)())
5800 {
5801 // uint 16
5802 oa->write_character(static_cast<CharType>(0xcd));
5803 write_number(static_cast<uint16_t>(j.m_value.number_integer));
5804 }
5805 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint32_t>::max)())
5806 {
5807 // uint 32
5808 oa->write_character(static_cast<CharType>(0xce));
5809 write_number(static_cast<uint32_t>(j.m_value.number_integer));
5810 }
5811 else if (j.m_value.number_unsigned <= (std::numeric_limits<uint64_t>::max)())
5812 {
5813 // uint 64
5814 oa->write_character(static_cast<CharType>(0xcf));
5815 write_number(static_cast<uint64_t>(j.m_value.number_integer));
5816 }
5817 break;
5818 }
5819
5820 case value_t::number_float: // float 64
5821 {
5822 oa->write_character(static_cast<CharType>(0xcb));
5823 write_number(j.m_value.number_float);
5824 break;
5825 }
5826
5827 case value_t::string:
5828 {
5829 // step 1: write control byte and the string length
5830 const auto N = j.m_value.string->size();
5831 if (N <= 31)
5832 {
5833 // fixstr
5834 write_number(static_cast<uint8_t>(0xa0 | N));
5835 }
5836 else if (N <= 255)
5837 {
5838 // str 8
5839 oa->write_character(static_cast<CharType>(0xd9));
5840 write_number(static_cast<uint8_t>(N));
5841 }
5842 else if (N <= 65535)
5843 {
5844 // str 16
5845 oa->write_character(static_cast<CharType>(0xda));
5846 write_number(static_cast<uint16_t>(N));
5847 }
5848 else if (N <= 4294967295)
5849 {
5850 // str 32
5851 oa->write_character(static_cast<CharType>(0xdb));
5852 write_number(static_cast<uint32_t>(N));
5853 }
5854
5855 // step 2: write the string
5856 oa->write_characters(
5857 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
5858 j.m_value.string->size());
5859 break;
5860 }
5861
5862 case value_t::array:
5863 {
5864 // step 1: write control byte and the array size
5865 const auto N = j.m_value.array->size();
5866 if (N <= 15)
5867 {
5868 // fixarray
5869 write_number(static_cast<uint8_t>(0x90 | N));
5870 }
5871 else if (N <= 0xffff)
5872 {
5873 // array 16
5874 oa->write_character(static_cast<CharType>(0xdc));
5875 write_number(static_cast<uint16_t>(N));
5876 }
5877 else if (N <= 0xffffffff)
5878 {
5879 // array 32
5880 oa->write_character(static_cast<CharType>(0xdd));
5881 write_number(static_cast<uint32_t>(N));
5882 }
5883
5884 // step 2: write each element
5885 for (const auto& el : *j.m_value.array)
5886 {
5887 write_msgpack(el);
5888 }
5889 break;
5890 }
5891
5892 case value_t::object:
5893 {
5894 // step 1: write control byte and the object size
5895 const auto N = j.m_value.object->size();
5896 if (N <= 15)
5897 {
5898 // fixmap
5899 write_number(static_cast<uint8_t>(0x80 | (N & 0xf)));
5900 }
5901 else if (N <= 65535)
5902 {
5903 // map 16
5904 oa->write_character(static_cast<CharType>(0xde));
5905 write_number(static_cast<uint16_t>(N));
5906 }
5907 else if (N <= 4294967295)
5908 {
5909 // map 32
5910 oa->write_character(static_cast<CharType>(0xdf));
5911 write_number(static_cast<uint32_t>(N));
5912 }
5913
5914 // step 2: write each element
5915 for (const auto& el : *j.m_value.object)
5916 {
5917 write_msgpack(el.first);
5918 write_msgpack(el.second);
5919 }
5920 break;
5921 }
5922
5923 default:
5924 break;
5925 }
5926 }
5927
5928 private:
5929 /*
5930 @brief write a number to output input
5931 @param[in] n number of type @a NumberType
5932 @tparam NumberType the type of the number
5933 @note This function needs to respect the system's endianess, because bytes
5934 in CBOR and MessagePack are stored in network order (big endian) and
5935 therefore need reordering on little endian systems.
5936 */
write_number(NumberType n)5937 template<typename NumberType> void write_number(NumberType n)
5938 {
5939 // step 1: write number to array of length NumberType
5940 std::array<CharType, sizeof(NumberType)> vec;
5941 std::memcpy(vec.data(), &n, sizeof(NumberType));
5942
5943 // step 2: write array to output (with possible reordering)
5944 if (is_little_endian)
5945 {
5946 // reverse byte order prior to conversion if necessary
5947 std::reverse(vec.begin(), vec.end());
5948 }
5949
5950 oa->write_characters(vec.data(), sizeof(NumberType));
5951 }
5952
5953 private:
5954 /// whether we can assume little endianess
5955 const bool is_little_endian = binary_reader<BasicJsonType>::little_endianess();
5956
5957 /// the output
5958 output_adapter_t<CharType> oa = nullptr;
5959 };
5960
5961 ///////////////////
5962 // serialization //
5963 ///////////////////
5964
5965 template<typename BasicJsonType>
5966 class serializer
5967 {
5968 using string_t = typename BasicJsonType::string_t;
5969 using number_float_t = typename BasicJsonType::number_float_t;
5970 using number_integer_t = typename BasicJsonType::number_integer_t;
5971 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5972 public:
5973 /*!
5974 @param[in] s output stream to serialize to
5975 @param[in] ichar indentation character to use
5976 */
serializer(output_adapter_t<char> s,const char ichar)5977 serializer(output_adapter_t<char> s, const char ichar)
5978 : o(std::move(s)), loc(std::localeconv()),
5979 thousands_sep(loc->thousands_sep == nullptr ? '\0' : loc->thousands_sep[0]),
5980 decimal_point(loc->decimal_point == nullptr ? '\0' : loc->decimal_point[0]),
5981 indent_char(ichar), indent_string(512, indent_char) {}
5982
5983 // delete because of pointer members
5984 serializer(const serializer&) = delete;
5985 serializer& operator=(const serializer&) = delete;
5986
5987 /*!
5988 @brief internal implementation of the serialization function
5989 This function is called by the public member function dump and organizes
5990 the serialization internally. The indentation level is propagated as
5991 additional parameter. In case of arrays and objects, the function is
5992 called recursively.
5993 - strings and object keys are escaped using `escape_string()`
5994 - integer numbers are converted implicitly via `operator<<`
5995 - floating-point numbers are converted to a string using `"%g"` format
5996 @param[in] val value to serialize
5997 @param[in] pretty_print whether the output shall be pretty-printed
5998 @param[in] indent_step the indent level
5999 @param[in] current_indent the current indent level (only used internally)
6000 */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)6001 void dump(const BasicJsonType& val, const bool pretty_print,
6002 const bool ensure_ascii,
6003 const unsigned int indent_step,
6004 const unsigned int current_indent = 0)
6005 {
6006 switch (val.m_type)
6007 {
6008 case value_t::object:
6009 {
6010 if (val.m_value.object->empty())
6011 {
6012 o->write_characters("{}", 2);
6013 return;
6014 }
6015
6016 if (pretty_print)
6017 {
6018 o->write_characters("{\n", 2);
6019
6020 // variable to hold indentation for recursive calls
6021 const auto new_indent = current_indent + indent_step;
6022 if (JSON_UNLIKELY(indent_string.size() < new_indent))
6023 {
6024 indent_string.resize(indent_string.size() * 2, ' ');
6025 }
6026
6027 // first n-1 elements
6028 auto i = val.m_value.object->cbegin();
6029 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6030 {
6031 o->write_characters(indent_string.c_str(), new_indent);
6032 o->write_character('\"');
6033 dump_escaped(i->first, ensure_ascii);
6034 o->write_characters("\": ", 3);
6035 dump(i->second, true, ensure_ascii, indent_step, new_indent);
6036 o->write_characters(",\n", 2);
6037 }
6038
6039 // last element
6040 assert(i != val.m_value.object->cend());
6041 assert(std::next(i) == val.m_value.object->cend());
6042 o->write_characters(indent_string.c_str(), new_indent);
6043 o->write_character('\"');
6044 dump_escaped(i->first, ensure_ascii);
6045 o->write_characters("\": ", 3);
6046 dump(i->second, true, ensure_ascii, indent_step, new_indent);
6047
6048 o->write_character('\n');
6049 o->write_characters(indent_string.c_str(), current_indent);
6050 o->write_character('}');
6051 }
6052 else
6053 {
6054 o->write_character('{');
6055
6056 // first n-1 elements
6057 auto i = val.m_value.object->cbegin();
6058 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
6059 {
6060 o->write_character('\"');
6061 dump_escaped(i->first, ensure_ascii);
6062 o->write_characters("\":", 2);
6063 dump(i->second, false, ensure_ascii, indent_step, current_indent);
6064 o->write_character(',');
6065 }
6066
6067 // last element
6068 assert(i != val.m_value.object->cend());
6069 assert(std::next(i) == val.m_value.object->cend());
6070 o->write_character('\"');
6071 dump_escaped(i->first, ensure_ascii);
6072 o->write_characters("\":", 2);
6073 dump(i->second, false, ensure_ascii, indent_step, current_indent);
6074
6075 o->write_character('}');
6076 }
6077
6078 return;
6079 }
6080
6081 case value_t::array:
6082 {
6083 if (val.m_value.array->empty())
6084 {
6085 o->write_characters("[]", 2);
6086 return;
6087 }
6088
6089 if (pretty_print)
6090 {
6091 o->write_characters("[\n", 2);
6092
6093 // variable to hold indentation for recursive calls
6094 const auto new_indent = current_indent + indent_step;
6095 if (JSON_UNLIKELY(indent_string.size() < new_indent))
6096 {
6097 indent_string.resize(indent_string.size() * 2, ' ');
6098 }
6099
6100 // first n-1 elements
6101 for (auto i = val.m_value.array->cbegin();
6102 i != val.m_value.array->cend() - 1; ++i)
6103 {
6104 o->write_characters(indent_string.c_str(), new_indent);
6105 dump(*i, true, ensure_ascii, indent_step, new_indent);
6106 o->write_characters(",\n", 2);
6107 }
6108
6109 // last element
6110 assert(not val.m_value.array->empty());
6111 o->write_characters(indent_string.c_str(), new_indent);
6112 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
6113
6114 o->write_character('\n');
6115 o->write_characters(indent_string.c_str(), current_indent);
6116 o->write_character(']');
6117 }
6118 else
6119 {
6120 o->write_character('[');
6121
6122 // first n-1 elements
6123 for (auto i = val.m_value.array->cbegin();
6124 i != val.m_value.array->cend() - 1; ++i)
6125 {
6126 dump(*i, false, ensure_ascii, indent_step, current_indent);
6127 o->write_character(',');
6128 }
6129
6130 // last element
6131 assert(not val.m_value.array->empty());
6132 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
6133
6134 o->write_character(']');
6135 }
6136
6137 return;
6138 }
6139
6140 case value_t::string:
6141 {
6142 o->write_character('\"');
6143 dump_escaped(*val.m_value.string, ensure_ascii);
6144 o->write_character('\"');
6145 return;
6146 }
6147
6148 case value_t::boolean:
6149 {
6150 if (val.m_value.boolean)
6151 {
6152 o->write_characters("true", 4);
6153 }
6154 else
6155 {
6156 o->write_characters("false", 5);
6157 }
6158 return;
6159 }
6160
6161 case value_t::number_integer:
6162 {
6163 dump_integer(val.m_value.number_integer);
6164 return;
6165 }
6166
6167 case value_t::number_unsigned:
6168 {
6169 dump_integer(val.m_value.number_unsigned);
6170 return;
6171 }
6172
6173 case value_t::number_float:
6174 {
6175 dump_float(val.m_value.number_float);
6176 return;
6177 }
6178
6179 case value_t::discarded:
6180 {
6181 o->write_characters("<discarded>", 11);
6182 return;
6183 }
6184
6185 case value_t::null:
6186 {
6187 o->write_characters("null", 4);
6188 return;
6189 }
6190 }
6191 }
6192
6193 private:
6194 /*!
6195 @brief returns the number of expected bytes following in UTF-8 string
6196 @param[in] u the first byte of a UTF-8 string
6197 @return the number of expected bytes following
6198 */
bytes_following(const uint8_t u)6199 static constexpr std::size_t bytes_following(const uint8_t u)
6200 {
6201 return ((u <= 127) ? 0
6202 : ((192 <= u and u <= 223) ? 1
6203 : ((224 <= u and u <= 239) ? 2
6204 : ((240 <= u and u <= 247) ? 3 : std::string::npos))));
6205 }
6206
6207 /*!
6208 @brief calculates the extra space to escape a JSON string
6209 @param[in] s the string to escape
6210 @param[in] ensure_ascii whether to escape non-ASCII characters with
6211 \uXXXX sequences
6212 @return the number of characters required to escape string @a s
6213 @complexity Linear in the length of string @a s.
6214 */
extra_space(const string_t & s,const bool ensure_ascii)6215 static std::size_t extra_space(const string_t& s,
6216 const bool ensure_ascii) noexcept
6217 {
6218 std::size_t res = 0;
6219
6220 for (std::size_t i = 0; i < s.size(); ++i)
6221 {
6222 switch (s[i])
6223 {
6224 // control characters that can be escaped with a backslash
6225 case '"':
6226 case '\\':
6227 case '\b':
6228 case '\f':
6229 case '\n':
6230 case '\r':
6231 case '\t':
6232 {
6233 // from c (1 byte) to \x (2 bytes)
6234 res += 1;
6235 break;
6236 }
6237
6238 // control characters that need \uxxxx escaping
6239 case 0x00:
6240 case 0x01:
6241 case 0x02:
6242 case 0x03:
6243 case 0x04:
6244 case 0x05:
6245 case 0x06:
6246 case 0x07:
6247 case 0x0b:
6248 case 0x0e:
6249 case 0x0f:
6250 case 0x10:
6251 case 0x11:
6252 case 0x12:
6253 case 0x13:
6254 case 0x14:
6255 case 0x15:
6256 case 0x16:
6257 case 0x17:
6258 case 0x18:
6259 case 0x19:
6260 case 0x1a:
6261 case 0x1b:
6262 case 0x1c:
6263 case 0x1d:
6264 case 0x1e:
6265 case 0x1f:
6266 {
6267 // from c (1 byte) to \uxxxx (6 bytes)
6268 res += 5;
6269 break;
6270 }
6271
6272 default:
6273 {
6274 if (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F))
6275 {
6276 const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
6277 if (bytes == std::string::npos)
6278 {
6279 // invalid characters are treated as is, so no
6280 // additional space will be used
6281 break;
6282 }
6283
6284 if (bytes == 3)
6285 {
6286 // codepoints that need 4 bytes (i.e., 3 additional
6287 // bytes) in UTF-8 need a surrogate pair when \u
6288 // escaping is used: from 4 bytes to \uxxxx\uxxxx
6289 // (12 bytes)
6290 res += (12 - bytes - 1);
6291 }
6292 else
6293 {
6294 // from x bytes to \uxxxx (6 bytes)
6295 res += (6 - bytes - 1);
6296 }
6297
6298 // skip the additional bytes
6299 i += bytes;
6300 }
6301 break;
6302 }
6303 }
6304 }
6305
6306 return res;
6307 }
6308
escape_codepoint(int codepoint,string_t & result,std::size_t & pos)6309 static void escape_codepoint(int codepoint, string_t& result, std::size_t& pos)
6310 {
6311 // expecting a proper codepoint
6312 assert(0x00 <= codepoint and codepoint <= 0x10FFFF);
6313
6314 // the last written character was the backslash before the 'u'
6315 assert(result[pos] == '\\');
6316
6317 // write the 'u'
6318 result[++pos] = 'u';
6319
6320 // convert a number 0..15 to its hex representation (0..f)
6321 static const std::array<char, 16> hexify =
6322 {
6323 {
6324 '0', '1', '2', '3', '4', '5', '6', '7',
6325 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
6326 }
6327 };
6328
6329 if (codepoint < 0x10000)
6330 {
6331 // codepoints U+0000..U+FFFF can be represented as \uxxxx.
6332 result[++pos] = hexify[(codepoint >> 12) & 0x0F];
6333 result[++pos] = hexify[(codepoint >> 8) & 0x0F];
6334 result[++pos] = hexify[(codepoint >> 4) & 0x0F];
6335 result[++pos] = hexify[codepoint & 0x0F];
6336 }
6337 else
6338 {
6339 // codepoints U+10000..U+10FFFF need a surrogate pair to be
6340 // represented as \uxxxx\uxxxx.
6341 // http://www.unicode.org/faq/utf_bom.html#utf16-4
6342 codepoint -= 0x10000;
6343 const int high_surrogate = 0xD800 | ((codepoint >> 10) & 0x3FF);
6344 const int low_surrogate = 0xDC00 | (codepoint & 0x3FF);
6345 result[++pos] = hexify[(high_surrogate >> 12) & 0x0F];
6346 result[++pos] = hexify[(high_surrogate >> 8) & 0x0F];
6347 result[++pos] = hexify[(high_surrogate >> 4) & 0x0F];
6348 result[++pos] = hexify[high_surrogate & 0x0F];
6349 ++pos; // backslash is already in output
6350 result[++pos] = 'u';
6351 result[++pos] = hexify[(low_surrogate >> 12) & 0x0F];
6352 result[++pos] = hexify[(low_surrogate >> 8) & 0x0F];
6353 result[++pos] = hexify[(low_surrogate >> 4) & 0x0F];
6354 result[++pos] = hexify[low_surrogate & 0x0F];
6355 }
6356
6357 ++pos;
6358 }
6359
6360 /*!
6361 @brief dump escaped string
6362 Escape a string by replacing certain special characters by a sequence of an
6363 escape character (backslash) and another character and other control
6364 characters by a sequence of "\u" followed by a four-digit hex
6365 representation. The escaped string is written to output stream @a o.
6366 @param[in] s the string to escape
6367 @param[in] ensure_ascii whether to escape non-ASCII characters with
6368 \uXXXX sequences
6369 @complexity Linear in the length of string @a s.
6370 */
dump_escaped(const string_t & s,const bool ensure_ascii) const6371 void dump_escaped(const string_t& s, const bool ensure_ascii) const
6372 {
6373 const auto space = extra_space(s, ensure_ascii);
6374 if (space == 0)
6375 {
6376 o->write_characters(s.c_str(), s.size());
6377 return;
6378 }
6379
6380 // create a result string of necessary size
6381 string_t result(s.size() + space, '\\');
6382 std::size_t pos = 0;
6383
6384 for (std::size_t i = 0; i < s.size(); ++i)
6385 {
6386 switch (s[i])
6387 {
6388 case '"': // quotation mark (0x22)
6389 {
6390 result[pos + 1] = '"';
6391 pos += 2;
6392 break;
6393 }
6394
6395 case '\\': // reverse solidus (0x5c)
6396 {
6397 // nothing to change
6398 pos += 2;
6399 break;
6400 }
6401
6402 case '\b': // backspace (0x08)
6403 {
6404 result[pos + 1] = 'b';
6405 pos += 2;
6406 break;
6407 }
6408
6409 case '\f': // formfeed (0x0c)
6410 {
6411 result[pos + 1] = 'f';
6412 pos += 2;
6413 break;
6414 }
6415
6416 case '\n': // newline (0x0a)
6417 {
6418 result[pos + 1] = 'n';
6419 pos += 2;
6420 break;
6421 }
6422
6423 case '\r': // carriage return (0x0d)
6424 {
6425 result[pos + 1] = 'r';
6426 pos += 2;
6427 break;
6428 }
6429
6430 case '\t': // horizontal tab (0x09)
6431 {
6432 result[pos + 1] = 't';
6433 pos += 2;
6434 break;
6435 }
6436
6437 default:
6438 {
6439 // escape control characters (0x00..0x1F) or, if
6440 // ensure_ascii parameter is used, non-ASCII characters
6441 if ((0x00 <= s[i] and s[i] <= 0x1F) or
6442 (ensure_ascii and (s[i] & 0x80 or s[i] == 0x7F)))
6443 {
6444 const auto bytes = bytes_following(static_cast<uint8_t>(s[i]));
6445 if (bytes == std::string::npos)
6446 {
6447 // copy invalid character as is
6448 result[pos++] = s[i];
6449 break;
6450 }
6451
6452 // check that the additional bytes are present
6453 assert(i + bytes < s.size());
6454
6455 // to use \uxxxx escaping, we first need to caluclate
6456 // the codepoint from the UTF-8 bytes
6457 int codepoint = 0;
6458
6459 assert(0 <= bytes and bytes <= 3);
6460 switch (bytes)
6461 {
6462 case 0:
6463 {
6464 codepoint = s[i] & 0xFF;
6465 break;
6466 }
6467
6468 case 1:
6469 {
6470 codepoint = ((s[i] & 0x3F) << 6)
6471 + (s[i + 1] & 0x7F);
6472 break;
6473 }
6474
6475 case 2:
6476 {
6477 codepoint = ((s[i] & 0x1F) << 12)
6478 + ((s[i + 1] & 0x7F) << 6)
6479 + (s[i + 2] & 0x7F);
6480 break;
6481 }
6482
6483 case 3:
6484 {
6485 codepoint = ((s[i] & 0xF) << 18)
6486 + ((s[i + 1] & 0x7F) << 12)
6487 + ((s[i + 2] & 0x7F) << 6)
6488 + (s[i + 3] & 0x7F);
6489 break;
6490 }
6491
6492 default:
6493 break; // LCOV_EXCL_LINE
6494 }
6495
6496 escape_codepoint(codepoint, result, pos);
6497 i += bytes;
6498 }
6499 else
6500 {
6501 // all other characters are added as-is
6502 result[pos++] = s[i];
6503 }
6504 break;
6505 }
6506 }
6507 }
6508
6509 assert(pos == result.size());
6510 o->write_characters(result.c_str(), result.size());
6511 }
6512
6513 /*!
6514 @brief dump an integer
6515 Dump a given integer to output stream @a o. Works internally with
6516 @a number_buffer.
6517 @param[in] x integer number (signed or unsigned) to dump
6518 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
6519 */
6520 template <
6521 typename NumberType,
6522 detail::enable_if_t<std::is_same<NumberType, number_unsigned_t>::value or
6523 std::is_same<NumberType, number_integer_t>::value,
6524 int> = 0 >
dump_integer(NumberType x)6525 void dump_integer(NumberType x)
6526 {
6527 // special case for "0"
6528 if (x == 0)
6529 {
6530 o->write_character('0');
6531 return;
6532 }
6533
6534 const bool is_negative = (x <= 0) and (x != 0); // see issue #755
6535 std::size_t i = 0;
6536
6537 while (x != 0)
6538 {
6539 // spare 1 byte for '\0'
6540 assert(i < number_buffer.size() - 1);
6541
6542 const auto digit = std::labs(static_cast<long>(x % 10));
6543 number_buffer[i++] = static_cast<char>('0' + digit);
6544 x /= 10;
6545 }
6546
6547 if (is_negative)
6548 {
6549 // make sure there is capacity for the '-'
6550 assert(i < number_buffer.size() - 2);
6551 number_buffer[i++] = '-';
6552 }
6553
6554 std::reverse(number_buffer.begin(), number_buffer.begin() + i);
6555 o->write_characters(number_buffer.data(), i);
6556 }
6557
6558 /*!
6559 @brief dump a floating-point number
6560 Dump a given floating-point number to output stream @a o. Works internally
6561 with @a number_buffer.
6562 @param[in] x floating-point number to dump
6563 */
dump_float(number_float_t x)6564 void dump_float(number_float_t x)
6565 {
6566 // NaN / inf
6567 if (not std::isfinite(x) or std::isnan(x))
6568 {
6569 o->write_characters("null", 4);
6570 return;
6571 }
6572
6573 // get number of digits for a text -> float -> text round-trip
6574 static constexpr auto d = std::numeric_limits<number_float_t>::digits10;
6575
6576 // the actual conversion
6577 std::ptrdiff_t len = snprintf(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
6578
6579 // negative value indicates an error
6580 assert(len > 0);
6581 // check if buffer was large enough
6582 assert(static_cast<std::size_t>(len) < number_buffer.size());
6583
6584 // erase thousands separator
6585 if (thousands_sep != '\0')
6586 {
6587 const auto end = std::remove(number_buffer.begin(),
6588 number_buffer.begin() + len, thousands_sep);
6589 std::fill(end, number_buffer.end(), '\0');
6590 assert((end - number_buffer.begin()) <= len);
6591 len = (end - number_buffer.begin());
6592 }
6593
6594 // convert decimal point to '.'
6595 if (decimal_point != '\0' and decimal_point != '.')
6596 {
6597 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
6598 if (dec_pos != number_buffer.end())
6599 {
6600 *dec_pos = '.';
6601 }
6602 }
6603
6604 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
6605
6606 // determine if need to append ".0"
6607 const bool value_is_int_like =
6608 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
6609 [](char c)
6610 {
6611 return (c == '.' or c == 'e');
6612 });
6613
6614 if (value_is_int_like)
6615 {
6616 o->write_characters(".0", 2);
6617 }
6618 }
6619
6620 private:
6621 /// the output of the serializer
6622 output_adapter_t<char> o = nullptr;
6623
6624 /// a (hopefully) large enough character buffer
6625 std::array<char, 64> number_buffer{{}};
6626
6627 /// the locale
6628 const std::lconv* loc = nullptr;
6629 /// the locale's thousand separator character
6630 const char thousands_sep = '\0';
6631 /// the locale's decimal point character
6632 const char decimal_point = '\0';
6633
6634 /// the indentation character
6635 const char indent_char;
6636
6637 /// the indentation string
6638 string_t indent_string;
6639 };
6640
6641 template<typename BasicJsonType>
6642 class json_ref
6643 {
6644 public:
6645 using value_type = BasicJsonType;
6646
json_ref(value_type && value)6647 json_ref(value_type&& value)
6648 : owned_value(std::move(value)),
6649 value_ref(&owned_value),
6650 is_rvalue(true)
6651 {}
6652
json_ref(const value_type & value)6653 json_ref(const value_type& value)
6654 : value_ref(const_cast<value_type*>(&value)),
6655 is_rvalue(false)
6656 {}
6657
json_ref(std::initializer_list<json_ref> init)6658 json_ref(std::initializer_list<json_ref> init)
6659 : owned_value(init),
6660 value_ref(&owned_value),
6661 is_rvalue(true)
6662 {}
6663
6664 template <class... Args>
json_ref(Args...args)6665 json_ref(Args... args)
6666 : owned_value(std::forward<Args>(args)...),
6667 value_ref(&owned_value),
6668 is_rvalue(true)
6669 {}
6670
6671 // class should be movable only
6672 json_ref(json_ref&&) = default;
6673 json_ref(const json_ref&) = delete;
6674 json_ref& operator=(const json_ref&) = delete;
6675
moved_or_copied() const6676 value_type moved_or_copied() const
6677 {
6678 if (is_rvalue)
6679 {
6680 return std::move(*value_ref);
6681 }
6682 return *value_ref;
6683 }
6684
operator *() const6685 value_type const& operator*() const
6686 {
6687 return *static_cast<value_type const*>(value_ref);
6688 }
6689
operator ->() const6690 value_type const* operator->() const
6691 {
6692 return static_cast<value_type const*>(value_ref);
6693 }
6694
6695 private:
6696 mutable value_type owned_value = nullptr;
6697 value_type* value_ref = nullptr;
6698 const bool is_rvalue;
6699 };
6700
6701 } // namespace detail
6702
6703 /// namespace to hold default `to_json` / `from_json` functions
6704 namespace
6705 {
6706 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value;
6707 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value;
6708 }
6709
6710
6711 /*!
6712 @brief default JSONSerializer template argument
6713 This serializer ignores the template arguments and uses ADL
6714 ([argument-dependent lookup](http://en.cppreference.com/w/cpp/language/adl))
6715 for serialization.
6716 */
6717 template<typename, typename>
6718 struct adl_serializer
6719 {
6720 /*!
6721 @brief convert a JSON value to any value type
6722 This function is usually called by the `get()` function of the
6723 @ref basic_json class (either explicit or via conversion operators).
6724 @param[in] j JSON value to read from
6725 @param[in,out] val value to write to
6726 */
6727 template<typename BasicJsonType, typename ValueType>
from_jsonnlohmann::adl_serializer6728 static void from_json(BasicJsonType&& j, ValueType& val) noexcept(
6729 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
6730 {
6731 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
6732 }
6733
6734 /*!
6735 @brief convert any value type to a JSON value
6736 This function is usually called by the constructors of the @ref basic_json
6737 class.
6738 @param[in,out] j JSON value to write to
6739 @param[in] val value to read from
6740 */
6741 template<typename BasicJsonType, typename ValueType>
to_jsonnlohmann::adl_serializer6742 static void to_json(BasicJsonType& j, ValueType&& val) noexcept(
6743 noexcept(::nlohmann::to_json(j, std::forward<ValueType>(val))))
6744 {
6745 ::nlohmann::to_json(j, std::forward<ValueType>(val));
6746 }
6747 };
6748
6749 /*!
6750 @brief JSON Pointer
6751 A JSON pointer defines a string syntax for identifying a specific value
6752 within a JSON document. It can be used with functions `at` and
6753 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
6754 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
6755 @since version 2.0.0
6756 */
6757 class json_pointer
6758 {
6759 /// allow basic_json to access private members
6760 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6761 friend class basic_json;
6762
6763 public:
6764 /*!
6765 @brief create JSON pointer
6766 Create a JSON pointer according to the syntax described in
6767 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
6768 @param[in] s string representing the JSON pointer; if omitted, the empty
6769 string is assumed which references the whole JSON value
6770 @throw parse_error.107 if the given JSON pointer @a s is nonempty and
6771 does not begin with a slash (`/`); see example below
6772 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s
6773 is not followed by `0` (representing `~`) or `1` (representing `/`);
6774 see example below
6775 @liveexample{The example shows the construction several valid JSON
6776 pointers as well as the exceptional behavior.,json_pointer}
6777 @since version 2.0.0
6778 */
json_pointer(const std::string & s="")6779 explicit json_pointer(const std::string& s = "") : reference_tokens(split(s)) {}
6780
6781 /*!
6782 @brief return a string representation of the JSON pointer
6783 @invariant For each JSON pointer `ptr`, it holds:
6784 @code {.cpp}
6785 ptr == json_pointer(ptr.to_string());
6786 @endcode
6787 @return a string representation of the JSON pointer
6788 @liveexample{The example shows the result of `to_string`.,
6789 json_pointer__to_string}
6790 @since version 2.0.0
6791 */
to_string() const6792 std::string to_string() const noexcept
6793 {
6794 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
6795 std::string{},
6796 [](const std::string & a, const std::string & b)
6797 {
6798 return a + "/" + escape(b);
6799 });
6800 }
6801
6802 /// @copydoc to_string()
operator std::string() const6803 operator std::string() const
6804 {
6805 return to_string();
6806 }
6807
6808 private:
6809 /*!
6810 @brief remove and return last reference pointer
6811 @throw out_of_range.405 if JSON pointer has no parent
6812 */
pop_back()6813 std::string pop_back()
6814 {
6815 if (JSON_UNLIKELY(is_root()))
6816 {
6817 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
6818 }
6819
6820 auto last = reference_tokens.back();
6821 reference_tokens.pop_back();
6822 return last;
6823 }
6824
6825 /// return whether pointer points to the root document
is_root() const6826 bool is_root() const
6827 {
6828 return reference_tokens.empty();
6829 }
6830
top() const6831 json_pointer top() const
6832 {
6833 if (JSON_UNLIKELY(is_root()))
6834 {
6835 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent"));
6836 }
6837
6838 json_pointer result = *this;
6839 result.reference_tokens = {reference_tokens[0]};
6840 return result;
6841 }
6842
6843
6844 /*!
6845 @brief create and return a reference to the pointed to value
6846 @complexity Linear in the number of reference tokens.
6847 @throw parse_error.109 if array index is not a number
6848 @throw type_error.313 if value cannot be unflattened
6849 */
6850 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6851 NLOHMANN_BASIC_JSON_TPL& get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const;
6852
6853 /*!
6854 @brief return a reference to the pointed to value
6855 @note This version does not throw if a value is not present, but tries to
6856 create nested values instead. For instance, calling this function
6857 with pointer `"/this/that"` on a null value is equivalent to calling
6858 `operator[]("this").operator[]("that")` on that value, effectively
6859 changing the null value to an object.
6860 @param[in] ptr a JSON value
6861 @return reference to the JSON value pointed to by the JSON pointer
6862 @complexity Linear in the length of the JSON pointer.
6863 @throw parse_error.106 if an array index begins with '0'
6864 @throw parse_error.109 if an array index was not a number
6865 @throw out_of_range.404 if the JSON pointer can not be resolved
6866 */
6867 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6868 NLOHMANN_BASIC_JSON_TPL& get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
6869
6870 /*!
6871 @throw parse_error.106 if an array index begins with '0'
6872 @throw parse_error.109 if an array index was not a number
6873 @throw out_of_range.402 if the array index '-' is used
6874 @throw out_of_range.404 if the JSON pointer can not be resolved
6875 */
6876 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6877 NLOHMANN_BASIC_JSON_TPL& get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const;
6878
6879 /*!
6880 @brief return a const reference to the pointed to value
6881 @param[in] ptr a JSON value
6882 @return const reference to the JSON value pointed to by the JSON
6883 pointer
6884 @throw parse_error.106 if an array index begins with '0'
6885 @throw parse_error.109 if an array index was not a number
6886 @throw out_of_range.402 if the array index '-' is used
6887 @throw out_of_range.404 if the JSON pointer can not be resolved
6888 */
6889 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6890 const NLOHMANN_BASIC_JSON_TPL& get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
6891
6892 /*!
6893 @throw parse_error.106 if an array index begins with '0'
6894 @throw parse_error.109 if an array index was not a number
6895 @throw out_of_range.402 if the array index '-' is used
6896 @throw out_of_range.404 if the JSON pointer can not be resolved
6897 */
6898 NLOHMANN_BASIC_JSON_TPL_DECLARATION
6899 const NLOHMANN_BASIC_JSON_TPL& get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const;
6900
6901 /*!
6902 @brief split the string input to reference tokens
6903 @note This function is only called by the json_pointer constructor.
6904 All exceptions below are documented there.
6905 @throw parse_error.107 if the pointer is not empty or begins with '/'
6906 @throw parse_error.108 if character '~' is not followed by '0' or '1'
6907 */
split(const std::string & reference_string)6908 static std::vector<std::string> split(const std::string& reference_string)
6909 {
6910 std::vector<std::string> result;
6911
6912 // special case: empty reference string -> no reference tokens
6913 if (reference_string.empty())
6914 {
6915 return result;
6916 }
6917
6918 // check if nonempty reference string begins with slash
6919 if (JSON_UNLIKELY(reference_string[0] != '/'))
6920 {
6921 JSON_THROW(detail::parse_error::create(107, 1,
6922 "JSON pointer must be empty or begin with '/' - was: '" +
6923 reference_string + "'"));
6924 }
6925
6926 // extract the reference tokens:
6927 // - slash: position of the last read slash (or end of string)
6928 // - start: position after the previous slash
6929 for (
6930 // search for the first slash after the first character
6931 std::size_t slash = reference_string.find_first_of('/', 1),
6932 // set the beginning of the first reference token
6933 start = 1;
6934 // we can stop if start == string::npos+1 = 0
6935 start != 0;
6936 // set the beginning of the next reference token
6937 // (will eventually be 0 if slash == std::string::npos)
6938 start = slash + 1,
6939 // find next slash
6940 slash = reference_string.find_first_of('/', start))
6941 {
6942 // use the text between the beginning of the reference token
6943 // (start) and the last slash (slash).
6944 auto reference_token = reference_string.substr(start, slash - start);
6945
6946 // check reference tokens are properly escaped
6947 for (std::size_t pos = reference_token.find_first_of('~');
6948 pos != std::string::npos;
6949 pos = reference_token.find_first_of('~', pos + 1))
6950 {
6951 assert(reference_token[pos] == '~');
6952
6953 // ~ must be followed by 0 or 1
6954 if (JSON_UNLIKELY(pos == reference_token.size() - 1 or
6955 (reference_token[pos + 1] != '0' and
6956 reference_token[pos + 1] != '1')))
6957 {
6958 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'"));
6959 }
6960 }
6961
6962 // finally, store the reference token
6963 unescape(reference_token);
6964 result.push_back(reference_token);
6965 }
6966
6967 return result;
6968 }
6969
6970 /*!
6971 @brief replace all occurrences of a substring by another string
6972 @param[in,out] s the string to manipulate; changed so that all
6973 occurrences of @a f are replaced with @a t
6974 @param[in] f the substring to replace with @a t
6975 @param[in] t the string to replace @a f
6976 @pre The search string @a f must not be empty. **This precondition is
6977 enforced with an assertion.**
6978 @since version 2.0.0
6979 */
replace_substring(std::string & s,const std::string & f,const std::string & t)6980 static void replace_substring(std::string& s, const std::string& f,
6981 const std::string& t)
6982 {
6983 assert(not f.empty());
6984 for (auto pos = s.find(f); // find first occurrence of f
6985 pos != std::string::npos; // make sure f was found
6986 s.replace(pos, f.size(), t), // replace with t, and
6987 pos = s.find(f, pos + t.size())) // find next occurrence of f
6988 {}
6989 }
6990
6991 /// escape "~"" to "~0" and "/" to "~1"
escape(std::string s)6992 static std::string escape(std::string s)
6993 {
6994 replace_substring(s, "~", "~0");
6995 replace_substring(s, "/", "~1");
6996 return s;
6997 }
6998
6999 /// unescape "~1" to tilde and "~0" to slash (order is important!)
unescape(std::string & s)7000 static void unescape(std::string& s)
7001 {
7002 replace_substring(s, "~1", "/");
7003 replace_substring(s, "~0", "~");
7004 }
7005
7006 /*!
7007 @param[in] reference_string the reference string to the current value
7008 @param[in] value the value to consider
7009 @param[in,out] result the result object to insert values to
7010 @note Empty objects or arrays are flattened to `null`.
7011 */
7012 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7013 static void flatten(const std::string& reference_string,
7014 const NLOHMANN_BASIC_JSON_TPL& value,
7015 NLOHMANN_BASIC_JSON_TPL& result);
7016
7017 /*!
7018 @param[in] value flattened JSON
7019 @return unflattened JSON
7020 @throw parse_error.109 if array index is not a number
7021 @throw type_error.314 if value is not an object
7022 @throw type_error.315 if object values are not primitive
7023 @throw type_error.313 if value cannot be unflattened
7024 */
7025 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7026 static NLOHMANN_BASIC_JSON_TPL
7027 unflatten(const NLOHMANN_BASIC_JSON_TPL& value);
7028
7029 friend bool operator==(json_pointer const& lhs,
7030 json_pointer const& rhs) noexcept;
7031
7032 friend bool operator!=(json_pointer const& lhs,
7033 json_pointer const& rhs) noexcept;
7034
7035 /// the reference tokens
7036 std::vector<std::string> reference_tokens;
7037 };
7038
7039 /*!
7040 @brief a class to store JSON values
7041 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
7042 in @ref object_t)
7043 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
7044 in @ref array_t)
7045 @tparam StringType type for JSON strings and object keys (`std::string` by
7046 default; will be used in @ref string_t)
7047 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
7048 in @ref boolean_t)
7049 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
7050 default; will be used in @ref number_integer_t)
7051 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
7052 `uint64_t` by default; will be used in @ref number_unsigned_t)
7053 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
7054 default; will be used in @ref number_float_t)
7055 @tparam AllocatorType type of the allocator to use (`std::allocator` by
7056 default)
7057 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
7058 and `from_json()` (@ref adl_serializer by default)
7059 @requirement The class satisfies the following concept requirements:
7060 - Basic
7061 - [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible):
7062 JSON values can be default constructed. The result will be a JSON null
7063 value.
7064 - [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible):
7065 A JSON value can be constructed from an rvalue argument.
7066 - [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible):
7067 A JSON value can be copy-constructed from an lvalue expression.
7068 - [MoveAssignable](http://en.cppreference.com/w/cpp/concept/MoveAssignable):
7069 A JSON value van be assigned from an rvalue argument.
7070 - [CopyAssignable](http://en.cppreference.com/w/cpp/concept/CopyAssignable):
7071 A JSON value can be copy-assigned from an lvalue expression.
7072 - [Destructible](http://en.cppreference.com/w/cpp/concept/Destructible):
7073 JSON values can be destructed.
7074 - Layout
7075 - [StandardLayoutType](http://en.cppreference.com/w/cpp/concept/StandardLayoutType):
7076 JSON values have
7077 [standard layout](http://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
7078 All non-static data members are private and standard layout types, the
7079 class has no virtual functions or (virtual) base classes.
7080 - Library-wide
7081 - [EqualityComparable](http://en.cppreference.com/w/cpp/concept/EqualityComparable):
7082 JSON values can be compared with `==`, see @ref
7083 operator==(const_reference,const_reference).
7084 - [LessThanComparable](http://en.cppreference.com/w/cpp/concept/LessThanComparable):
7085 JSON values can be compared with `<`, see @ref
7086 operator<(const_reference,const_reference).
7087 - [Swappable](http://en.cppreference.com/w/cpp/concept/Swappable):
7088 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
7089 other compatible types, using unqualified function call @ref swap().
7090 - [NullablePointer](http://en.cppreference.com/w/cpp/concept/NullablePointer):
7091 JSON values can be compared against `std::nullptr_t` objects which are used
7092 to model the `null` value.
7093 - Container
7094 - [Container](http://en.cppreference.com/w/cpp/concept/Container):
7095 JSON values can be used like STL containers and provide iterator access.
7096 - [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer);
7097 JSON values can be used like STL containers and provide reverse iterator
7098 access.
7099 @invariant The member variables @a m_value and @a m_type have the following
7100 relationship:
7101 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
7102 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
7103 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
7104 The invariants are checked by member function assert_invariant().
7105 @internal
7106 @note ObjectType trick from http://stackoverflow.com/a/9860911
7107 @endinternal
7108 @see [RFC 7159: The JavaScript Object Notation (JSON) Data Interchange
7109 Format](http://rfc7159.net/rfc7159)
7110 @since version 1.0.0
7111 @nosubgrouping
7112 */
7113 NLOHMANN_BASIC_JSON_TPL_DECLARATION
7114 class basic_json
7115 {
7116 private:
7117 template<detail::value_t> friend struct detail::external_constructor;
7118 friend ::nlohmann::json_pointer;
7119 friend ::nlohmann::detail::parser<basic_json>;
7120 friend ::nlohmann::detail::serializer<basic_json>;
7121 template<typename BasicJsonType>
7122 friend class ::nlohmann::detail::iter_impl;
7123 template<typename BasicJsonType, typename CharType>
7124 friend class ::nlohmann::detail::binary_writer;
7125 template<typename BasicJsonType>
7126 friend class ::nlohmann::detail::binary_reader;
7127
7128 /// workaround type for MSVC
7129 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
7130
7131 // convenience aliases for types residing in namespace detail;
7132 using lexer = ::nlohmann::detail::lexer<basic_json>;
7133 using parser = ::nlohmann::detail::parser<basic_json>;
7134
7135 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
7136 template<typename BasicJsonType>
7137 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
7138 template<typename BasicJsonType>
7139 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
7140 template<typename Iterator>
7141 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
7142 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
7143
7144 template<typename CharType>
7145 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
7146
7147 using binary_reader = ::nlohmann::detail::binary_reader<basic_json>;
7148 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
7149
7150 using serializer = ::nlohmann::detail::serializer<basic_json>;
7151
7152 public:
7153 using value_t = detail::value_t;
7154 // forward declarations
7155 using json_pointer = ::nlohmann::json_pointer;
7156 template<typename T, typename SFINAE>
7157 using json_serializer = JSONSerializer<T, SFINAE>;
7158
7159 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
7160
7161 ////////////////
7162 // exceptions //
7163 ////////////////
7164
7165 /// @name exceptions
7166 /// Classes to implement user-defined exceptions.
7167 /// @{
7168
7169 /// @copydoc detail::exception
7170 using exception = detail::exception;
7171 /// @copydoc detail::parse_error
7172 using parse_error = detail::parse_error;
7173 /// @copydoc detail::invalid_iterator
7174 using invalid_iterator = detail::invalid_iterator;
7175 /// @copydoc detail::type_error
7176 using type_error = detail::type_error;
7177 /// @copydoc detail::out_of_range
7178 using out_of_range = detail::out_of_range;
7179 /// @copydoc detail::other_error
7180 using other_error = detail::other_error;
7181
7182 /// @}
7183
7184
7185 /////////////////////
7186 // container types //
7187 /////////////////////
7188
7189 /// @name container types
7190 /// The canonic container types to use @ref basic_json like any other STL
7191 /// container.
7192 /// @{
7193
7194 /// the type of elements in a basic_json container
7195 using value_type = basic_json;
7196
7197 /// the type of an element reference
7198 using reference = value_type&;
7199 /// the type of an element const reference
7200 using const_reference = const value_type&;
7201
7202 /// a type to represent differences between iterators
7203 using difference_type = std::ptrdiff_t;
7204 /// a type to represent container sizes
7205 using size_type = std::size_t;
7206
7207 /// the allocator type
7208 using allocator_type = AllocatorType<basic_json>;
7209
7210 /// the type of an element pointer
7211 using pointer = typename std::allocator_traits<allocator_type>::pointer;
7212 /// the type of an element const pointer
7213 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
7214
7215 /// an iterator for a basic_json container
7216 using iterator = iter_impl<basic_json>;
7217 /// a const iterator for a basic_json container
7218 using const_iterator = iter_impl<const basic_json>;
7219 /// a reverse iterator for a basic_json container
7220 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
7221 /// a const reverse iterator for a basic_json container
7222 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
7223
7224 /// @}
7225
7226
7227 /*!
7228 @brief returns the allocator associated with the container
7229 */
get_allocator()7230 static allocator_type get_allocator()
7231 {
7232 return allocator_type();
7233 }
7234
7235 /*!
7236 @brief returns version information on the library
7237 This function returns a JSON object with information about the library,
7238 including the version number and information on the platform and compiler.
7239 @return JSON object holding version information
7240 key | description
7241 ----------- | ---------------
7242 `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).
7243 `copyright` | The copyright line for the library as string.
7244 `name` | The name of the library as string.
7245 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
7246 `url` | The URL of the project as string.
7247 `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).
7248 @liveexample{The following code shows an example output of the `meta()`
7249 function.,meta}
7250 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7251 changes to any JSON value.
7252 @complexity Constant.
7253 @since 2.1.0
7254 */
meta()7255 static basic_json meta()
7256 {
7257 basic_json result;
7258
7259 result["copyright"] = "(C) 2013-2017 Niels Lohmann";
7260 result["name"] = "JSON for Modern C++";
7261 result["url"] = "https://github.com/nlohmann/json";
7262 result["version"] =
7263 {
7264 {"string", "2.1.1"}, {"major", 2}, {"minor", 1}, {"patch", 1}
7265 };
7266
7267 #ifdef _WIN32
7268 result["platform"] = "win32";
7269 #elif defined __linux__
7270 result["platform"] = "linux";
7271 #elif defined __APPLE__
7272 result["platform"] = "apple";
7273 #elif defined __unix__
7274 result["platform"] = "unix";
7275 #else
7276 result["platform"] = "unknown";
7277 #endif
7278
7279 #if defined(__ICC) || defined(__INTEL_COMPILER)
7280 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
7281 #elif defined(__clang__)
7282 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
7283 #elif defined(__GNUC__) || defined(__GNUG__)
7284 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
7285 #elif defined(__HP_cc) || defined(__HP_aCC)
7286 result["compiler"] = "hp"
7287 #elif defined(__IBMCPP__)
7288 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
7289 #elif defined(_MSC_VER)
7290 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
7291 #elif defined(__PGI)
7292 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
7293 #elif defined(__SUNPRO_CC)
7294 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
7295 #else
7296 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
7297 #endif
7298
7299 #ifdef __cplusplus
7300 result["compiler"]["c++"] = std::to_string(__cplusplus);
7301 #else
7302 result["compiler"]["c++"] = "unknown";
7303 #endif
7304 return result;
7305 }
7306
7307
7308 ///////////////////////////
7309 // JSON value data types //
7310 ///////////////////////////
7311
7312 /// @name JSON value data types
7313 /// The data types to store a JSON value. These types are derived from
7314 /// the template arguments passed to class @ref basic_json.
7315 /// @{
7316
7317 /*!
7318 @brief a type for an object
7319 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON objects as follows:
7320 > An object is an unordered collection of zero or more name/value pairs,
7321 > where a name is a string and a value is a string, number, boolean, null,
7322 > object, or array.
7323 To store objects in C++, a type is defined by the template parameters
7324 described below.
7325 @tparam ObjectType the container to store objects (e.g., `std::map` or
7326 `std::unordered_map`)
7327 @tparam StringType the type of the keys or names (e.g., `std::string`).
7328 The comparison function `std::less<StringType>` is used to order elements
7329 inside the container.
7330 @tparam AllocatorType the allocator to use for objects (e.g.,
7331 `std::allocator`)
7332 #### Default type
7333 With the default values for @a ObjectType (`std::map`), @a StringType
7334 (`std::string`), and @a AllocatorType (`std::allocator`), the default
7335 value for @a object_t is:
7336 @code {.cpp}
7337 std::map<
7338 std::string, // key_type
7339 basic_json, // value_type
7340 std::less<std::string>, // key_compare
7341 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
7342 >
7343 @endcode
7344 #### Behavior
7345 The choice of @a object_t influences the behavior of the JSON class. With
7346 the default type, objects have the following behavior:
7347 - When all names are unique, objects will be interoperable in the sense
7348 that all software implementations receiving that object will agree on
7349 the name-value mappings.
7350 - When the names within an object are not unique, later stored name/value
7351 pairs overwrite previously stored name/value pairs, leaving the used
7352 names unique. For instance, `{"key": 1}` and `{"key": 2, "key": 1}` will
7353 be treated as equal and both stored as `{"key": 1}`.
7354 - Internally, name/value pairs are stored in lexicographical order of the
7355 names. Objects will also be serialized (see @ref dump) in this order.
7356 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
7357 and serialized as `{"a": 2, "b": 1}`.
7358 - When comparing objects, the order of the name/value pairs is irrelevant.
7359 This makes objects interoperable in the sense that they will not be
7360 affected by these differences. For instance, `{"b": 1, "a": 2}` and
7361 `{"a": 2, "b": 1}` will be treated as equal.
7362 #### Limits
7363 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7364 > An implementation may set limits on the maximum depth of nesting.
7365 In this class, the object's limit of nesting is not explicitly constrained.
7366 However, a maximum depth of nesting may be introduced by the compiler or
7367 runtime environment. A theoretical limit can be queried by calling the
7368 @ref max_size function of a JSON object.
7369 #### Storage
7370 Objects are stored as pointers in a @ref basic_json type. That is, for any
7371 access to object values, a pointer of type `object_t*` must be
7372 dereferenced.
7373 @sa @ref array_t -- type for an array value
7374 @since version 1.0.0
7375 @note The order name/value pairs are added to the object is *not*
7376 preserved by the library. Therefore, iterating an object may return
7377 name/value pairs in a different order than they were originally stored. In
7378 fact, keys will be traversed in alphabetical order as `std::map` with
7379 `std::less` is used by default. Please note this behavior conforms to [RFC
7380 7159](http://rfc7159.net/rfc7159), because any order implements the
7381 specified "unordered" nature of JSON objects.
7382 */
7383
7384 #if defined(JSON_HAS_CPP_14)
7385 // Use transparent comparator if possible, combined with perfect forwarding
7386 // on find() and count() calls prevents unnecessary string construction.
7387 using object_comparator_t = std::less<>;
7388 #else
7389 using object_comparator_t = std::less<StringType>;
7390 #endif
7391 using object_t = ObjectType<StringType,
7392 basic_json,
7393 object_comparator_t,
7394 AllocatorType<std::pair<const StringType,
7395 basic_json>>>;
7396
7397 /*!
7398 @brief a type for an array
7399 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON arrays as follows:
7400 > An array is an ordered sequence of zero or more values.
7401 To store objects in C++, a type is defined by the template parameters
7402 explained below.
7403 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
7404 `std::list`)
7405 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
7406 #### Default type
7407 With the default values for @a ArrayType (`std::vector`) and @a
7408 AllocatorType (`std::allocator`), the default value for @a array_t is:
7409 @code {.cpp}
7410 std::vector<
7411 basic_json, // value_type
7412 std::allocator<basic_json> // allocator_type
7413 >
7414 @endcode
7415 #### Limits
7416 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7417 > An implementation may set limits on the maximum depth of nesting.
7418 In this class, the array's limit of nesting is not explicitly constrained.
7419 However, a maximum depth of nesting may be introduced by the compiler or
7420 runtime environment. A theoretical limit can be queried by calling the
7421 @ref max_size function of a JSON array.
7422 #### Storage
7423 Arrays are stored as pointers in a @ref basic_json type. That is, for any
7424 access to array values, a pointer of type `array_t*` must be dereferenced.
7425 @sa @ref object_t -- type for an object value
7426 @since version 1.0.0
7427 */
7428 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
7429
7430 /*!
7431 @brief a type for a string
7432 [RFC 7159](http://rfc7159.net/rfc7159) describes JSON strings as follows:
7433 > A string is a sequence of zero or more Unicode characters.
7434 To store objects in C++, a type is defined by the template parameter
7435 described below. Unicode values are split by the JSON class into
7436 byte-sized characters during deserialization.
7437 @tparam StringType the container to store strings (e.g., `std::string`).
7438 Note this container is used for keys/names in objects, see @ref object_t.
7439 #### Default type
7440 With the default values for @a StringType (`std::string`), the default
7441 value for @a string_t is:
7442 @code {.cpp}
7443 std::string
7444 @endcode
7445 #### Encoding
7446 Strings are stored in UTF-8 encoding. Therefore, functions like
7447 `std::string::size()` or `std::string::length()` return the number of
7448 bytes in the string rather than the number of characters or glyphs.
7449 #### String comparison
7450 [RFC 7159](http://rfc7159.net/rfc7159) states:
7451 > Software implementations are typically required to test names of object
7452 > members for equality. Implementations that transform the textual
7453 > representation into sequences of Unicode code units and then perform the
7454 > comparison numerically, code unit by code unit, are interoperable in the
7455 > sense that implementations will agree in all cases on equality or
7456 > inequality of two strings. For example, implementations that compare
7457 > strings with escaped characters unconverted may incorrectly find that
7458 > `"a\\b"` and `"a\u005Cb"` are not equal.
7459 This implementation is interoperable as it does compare strings code unit
7460 by code unit.
7461 #### Storage
7462 String values are stored as pointers in a @ref basic_json type. That is,
7463 for any access to string values, a pointer of type `string_t*` must be
7464 dereferenced.
7465 @since version 1.0.0
7466 */
7467 using string_t = StringType;
7468
7469 /*!
7470 @brief a type for a boolean
7471 [RFC 7159](http://rfc7159.net/rfc7159) implicitly describes a boolean as a
7472 type which differentiates the two literals `true` and `false`.
7473 To store objects in C++, a type is defined by the template parameter @a
7474 BooleanType which chooses the type to use.
7475 #### Default type
7476 With the default values for @a BooleanType (`bool`), the default value for
7477 @a boolean_t is:
7478 @code {.cpp}
7479 bool
7480 @endcode
7481 #### Storage
7482 Boolean values are stored directly inside a @ref basic_json type.
7483 @since version 1.0.0
7484 */
7485 using boolean_t = BooleanType;
7486
7487 /*!
7488 @brief a type for a number (integer)
7489 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7490 > The representation of numbers is similar to that used in most
7491 > programming languages. A number is represented in base 10 using decimal
7492 > digits. It contains an integer component that may be prefixed with an
7493 > optional minus sign, which may be followed by a fraction part and/or an
7494 > exponent part. Leading zeros are not allowed. (...) Numeric values that
7495 > cannot be represented in the grammar below (such as Infinity and NaN)
7496 > are not permitted.
7497 This description includes both integer and floating-point numbers.
7498 However, C++ allows more precise storage if it is known whether the number
7499 is a signed integer, an unsigned integer or a floating-point number.
7500 Therefore, three different types, @ref number_integer_t, @ref
7501 number_unsigned_t and @ref number_float_t are used.
7502 To store integer numbers in C++, a type is defined by the template
7503 parameter @a NumberIntegerType which chooses the type to use.
7504 #### Default type
7505 With the default values for @a NumberIntegerType (`int64_t`), the default
7506 value for @a number_integer_t is:
7507 @code {.cpp}
7508 int64_t
7509 @endcode
7510 #### Default behavior
7511 - The restrictions about leading zeros is not enforced in C++. Instead,
7512 leading zeros in integer literals lead to an interpretation as octal
7513 number. Internally, the value will be stored as decimal number. For
7514 instance, the C++ integer literal `010` will be serialized to `8`.
7515 During deserialization, leading zeros yield an error.
7516 - Not-a-number (NaN) values will be serialized to `null`.
7517 #### Limits
7518 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7519 > An implementation may set limits on the range and precision of numbers.
7520 When the default type is used, the maximal integer number that can be
7521 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
7522 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
7523 that are out of range will yield over/underflow when used in a
7524 constructor. During deserialization, too large or small integer numbers
7525 will be automatically be stored as @ref number_unsigned_t or @ref
7526 number_float_t.
7527 [RFC 7159](http://rfc7159.net/rfc7159) further states:
7528 > Note that when such software is used, numbers that are integers and are
7529 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
7530 > that implementations will agree exactly on their numeric values.
7531 As this range is a subrange of the exactly supported range [INT64_MIN,
7532 INT64_MAX], this class's integer type is interoperable.
7533 #### Storage
7534 Integer number values are stored directly inside a @ref basic_json type.
7535 @sa @ref number_float_t -- type for number values (floating-point)
7536 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
7537 @since version 1.0.0
7538 */
7539 using number_integer_t = NumberIntegerType;
7540
7541 /*!
7542 @brief a type for a number (unsigned)
7543 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7544 > The representation of numbers is similar to that used in most
7545 > programming languages. A number is represented in base 10 using decimal
7546 > digits. It contains an integer component that may be prefixed with an
7547 > optional minus sign, which may be followed by a fraction part and/or an
7548 > exponent part. Leading zeros are not allowed. (...) Numeric values that
7549 > cannot be represented in the grammar below (such as Infinity and NaN)
7550 > are not permitted.
7551 This description includes both integer and floating-point numbers.
7552 However, C++ allows more precise storage if it is known whether the number
7553 is a signed integer, an unsigned integer or a floating-point number.
7554 Therefore, three different types, @ref number_integer_t, @ref
7555 number_unsigned_t and @ref number_float_t are used.
7556 To store unsigned integer numbers in C++, a type is defined by the
7557 template parameter @a NumberUnsignedType which chooses the type to use.
7558 #### Default type
7559 With the default values for @a NumberUnsignedType (`uint64_t`), the
7560 default value for @a number_unsigned_t is:
7561 @code {.cpp}
7562 uint64_t
7563 @endcode
7564 #### Default behavior
7565 - The restrictions about leading zeros is not enforced in C++. Instead,
7566 leading zeros in integer literals lead to an interpretation as octal
7567 number. Internally, the value will be stored as decimal number. For
7568 instance, the C++ integer literal `010` will be serialized to `8`.
7569 During deserialization, leading zeros yield an error.
7570 - Not-a-number (NaN) values will be serialized to `null`.
7571 #### Limits
7572 [RFC 7159](http://rfc7159.net/rfc7159) specifies:
7573 > An implementation may set limits on the range and precision of numbers.
7574 When the default type is used, the maximal integer number that can be
7575 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
7576 number that can be stored is `0`. Integer numbers that are out of range
7577 will yield over/underflow when used in a constructor. During
7578 deserialization, too large or small integer numbers will be automatically
7579 be stored as @ref number_integer_t or @ref number_float_t.
7580 [RFC 7159](http://rfc7159.net/rfc7159) further states:
7581 > Note that when such software is used, numbers that are integers and are
7582 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
7583 > that implementations will agree exactly on their numeric values.
7584 As this range is a subrange (when considered in conjunction with the
7585 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
7586 this class's integer type is interoperable.
7587 #### Storage
7588 Integer number values are stored directly inside a @ref basic_json type.
7589 @sa @ref number_float_t -- type for number values (floating-point)
7590 @sa @ref number_integer_t -- type for number values (integer)
7591 @since version 2.0.0
7592 */
7593 using number_unsigned_t = NumberUnsignedType;
7594
7595 /*!
7596 @brief a type for a number (floating-point)
7597 [RFC 7159](http://rfc7159.net/rfc7159) describes numbers as follows:
7598 > The representation of numbers is similar to that used in most
7599 > programming languages. A number is represented in base 10 using decimal
7600 > digits. It contains an integer component that may be prefixed with an
7601 > optional minus sign, which may be followed by a fraction part and/or an
7602 > exponent part. Leading zeros are not allowed. (...) Numeric values that
7603 > cannot be represented in the grammar below (such as Infinity and NaN)
7604 > are not permitted.
7605 This description includes both integer and floating-point numbers.
7606 However, C++ allows more precise storage if it is known whether the number
7607 is a signed integer, an unsigned integer or a floating-point number.
7608 Therefore, three different types, @ref number_integer_t, @ref
7609 number_unsigned_t and @ref number_float_t are used.
7610 To store floating-point numbers in C++, a type is defined by the template
7611 parameter @a NumberFloatType which chooses the type to use.
7612 #### Default type
7613 With the default values for @a NumberFloatType (`double`), the default
7614 value for @a number_float_t is:
7615 @code {.cpp}
7616 double
7617 @endcode
7618 #### Default behavior
7619 - The restrictions about leading zeros is not enforced in C++. Instead,
7620 leading zeros in floating-point literals will be ignored. Internally,
7621 the value will be stored as decimal number. For instance, the C++
7622 floating-point literal `01.2` will be serialized to `1.2`. During
7623 deserialization, leading zeros yield an error.
7624 - Not-a-number (NaN) values will be serialized to `null`.
7625 #### Limits
7626 [RFC 7159](http://rfc7159.net/rfc7159) states:
7627 > This specification allows implementations to set limits on the range and
7628 > precision of numbers accepted. Since software that implements IEEE
7629 > 754-2008 binary64 (double precision) numbers is generally available and
7630 > widely used, good interoperability can be achieved by implementations
7631 > that expect no more precision or range than these provide, in the sense
7632 > that implementations will approximate JSON numbers within the expected
7633 > precision.
7634 This implementation does exactly follow this approach, as it uses double
7635 precision floating-point numbers. Note values smaller than
7636 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
7637 will be stored as NaN internally and be serialized to `null`.
7638 #### Storage
7639 Floating-point number values are stored directly inside a @ref basic_json
7640 type.
7641 @sa @ref number_integer_t -- type for number values (integer)
7642 @sa @ref number_unsigned_t -- type for number values (unsigned integer)
7643 @since version 1.0.0
7644 */
7645 using number_float_t = NumberFloatType;
7646
7647 /// @}
7648
7649 private:
7650
7651 /// helper for exception-safe object creation
7652 template<typename T, typename... Args>
create(Args &&...args)7653 static T* create(Args&& ... args)
7654 {
7655 AllocatorType<T> alloc;
7656 auto deleter = [&](T * object)
7657 {
7658 alloc.deallocate(object, 1);
7659 };
7660 std::unique_ptr<T, decltype(deleter)> object(alloc.allocate(1), deleter);
7661 alloc.construct(object.get(), std::forward<Args>(args)...);
7662 assert(object != nullptr);
7663 return object.release();
7664 }
7665
7666 ////////////////////////
7667 // JSON value storage //
7668 ////////////////////////
7669
7670 /*!
7671 @brief a JSON value
7672 The actual storage for a JSON value of the @ref basic_json class. This
7673 union combines the different storage types for the JSON value types
7674 defined in @ref value_t.
7675 JSON type | value_t type | used type
7676 --------- | --------------- | ------------------------
7677 object | object | pointer to @ref object_t
7678 array | array | pointer to @ref array_t
7679 string | string | pointer to @ref string_t
7680 boolean | boolean | @ref boolean_t
7681 number | number_integer | @ref number_integer_t
7682 number | number_unsigned | @ref number_unsigned_t
7683 number | number_float | @ref number_float_t
7684 null | null | *no value is stored*
7685 @note Variable-length types (objects, arrays, and strings) are stored as
7686 pointers. The size of the union should not exceed 64 bits if the default
7687 value types are used.
7688 @since version 1.0.0
7689 */
7690 union json_value
7691 {
7692 /// object (stored with pointer to save storage)
7693 object_t* object;
7694 /// array (stored with pointer to save storage)
7695 array_t* array;
7696 /// string (stored with pointer to save storage)
7697 string_t* string;
7698 /// boolean
7699 boolean_t boolean;
7700 /// number (integer)
7701 number_integer_t number_integer;
7702 /// number (unsigned integer)
7703 number_unsigned_t number_unsigned;
7704 /// number (floating-point)
7705 number_float_t number_float;
7706
7707 /// default constructor (for null values)
7708 json_value() = default;
7709 /// constructor for booleans
json_value(boolean_t v)7710 json_value(boolean_t v) noexcept : boolean(v) {}
7711 /// constructor for numbers (integer)
json_value(number_integer_t v)7712 json_value(number_integer_t v) noexcept : number_integer(v) {}
7713 /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)7714 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
7715 /// constructor for numbers (floating-point)
json_value(number_float_t v)7716 json_value(number_float_t v) noexcept : number_float(v) {}
7717 /// constructor for empty values of a given type
json_value(value_t t)7718 json_value(value_t t)
7719 {
7720 switch (t)
7721 {
7722 case value_t::object:
7723 {
7724 object = create<object_t>();
7725 break;
7726 }
7727
7728 case value_t::array:
7729 {
7730 array = create<array_t>();
7731 break;
7732 }
7733
7734 case value_t::string:
7735 {
7736 string = create<string_t>("");
7737 break;
7738 }
7739
7740 case value_t::boolean:
7741 {
7742 boolean = boolean_t(false);
7743 break;
7744 }
7745
7746 case value_t::number_integer:
7747 {
7748 number_integer = number_integer_t(0);
7749 break;
7750 }
7751
7752 case value_t::number_unsigned:
7753 {
7754 number_unsigned = number_unsigned_t(0);
7755 break;
7756 }
7757
7758 case value_t::number_float:
7759 {
7760 number_float = number_float_t(0.0);
7761 break;
7762 }
7763
7764 case value_t::null:
7765 {
7766 break;
7767 }
7768
7769 default:
7770 {
7771 if (JSON_UNLIKELY(t == value_t::null))
7772 {
7773 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 2.1.1")); // LCOV_EXCL_LINE
7774 }
7775 break;
7776 }
7777 }
7778 }
7779
7780 /// constructor for strings
json_value(const string_t & value)7781 json_value(const string_t& value)
7782 {
7783 string = create<string_t>(value);
7784 }
7785
7786 /// constructor for rvalue strings
json_value(string_t && value)7787 json_value(string_t&& value)
7788 {
7789 string = create<string_t>(std::move(value));
7790 }
7791
7792 /// constructor for objects
json_value(const object_t & value)7793 json_value(const object_t& value)
7794 {
7795 object = create<object_t>(value);
7796 }
7797
7798 /// constructor for rvalue objects
json_value(object_t && value)7799 json_value(object_t&& value)
7800 {
7801 object = create<object_t>(std::move(value));
7802 }
7803
7804 /// constructor for arrays
json_value(const array_t & value)7805 json_value(const array_t& value)
7806 {
7807 array = create<array_t>(value);
7808 }
7809
7810 /// constructor for rvalue arrays
json_value(array_t && value)7811 json_value(array_t&& value)
7812 {
7813 array = create<array_t>(std::move(value));
7814 }
7815
destroy(value_t t)7816 void destroy(value_t t)
7817 {
7818 switch (t)
7819 {
7820 case value_t::object:
7821 {
7822 AllocatorType<object_t> alloc;
7823 alloc.destroy(object);
7824 alloc.deallocate(object, 1);
7825 break;
7826 }
7827
7828 case value_t::array:
7829 {
7830 AllocatorType<array_t> alloc;
7831 alloc.destroy(array);
7832 alloc.deallocate(array, 1);
7833 break;
7834 }
7835
7836 case value_t::string:
7837 {
7838 AllocatorType<string_t> alloc;
7839 alloc.destroy(string);
7840 alloc.deallocate(string, 1);
7841 break;
7842 }
7843
7844 default:
7845 {
7846 break;
7847 }
7848 }
7849 }
7850 };
7851
7852 /*!
7853 @brief checks the class invariants
7854 This function asserts the class invariants. It needs to be called at the
7855 end of every constructor to make sure that created objects respect the
7856 invariant. Furthermore, it has to be called each time the type of a JSON
7857 value is changed, because the invariant expresses a relationship between
7858 @a m_type and @a m_value.
7859 */
assert_invariant() const7860 void assert_invariant() const
7861 {
7862 assert(m_type != value_t::object or m_value.object != nullptr);
7863 assert(m_type != value_t::array or m_value.array != nullptr);
7864 assert(m_type != value_t::string or m_value.string != nullptr);
7865 }
7866
7867 public:
7868 //////////////////////////
7869 // JSON parser callback //
7870 //////////////////////////
7871
7872 using parse_event_t = typename parser::parse_event_t;
7873
7874 /*!
7875 @brief per-element parser callback type
7876 With a parser callback function, the result of parsing a JSON text can be
7877 influenced. When passed to @ref parse, it is called on certain events
7878 (passed as @ref parse_event_t via parameter @a event) with a set recursion
7879 depth @a depth and context JSON value @a parsed. The return value of the
7880 callback function is a boolean indicating whether the element that emitted
7881 the callback shall be kept or not.
7882 We distinguish six scenarios (determined by the event type) in which the
7883 callback function can be called. The following table describes the values
7884 of the parameters @a depth, @a event, and @a parsed.
7885 parameter @a event | description | parameter @a depth | parameter @a parsed
7886 ------------------ | ----------- | ------------------ | -------------------
7887 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
7888 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
7889 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
7890 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
7891 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
7892 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
7893 @image html callback_events.png "Example when certain parse events are triggered"
7894 Discarding a value (i.e., returning `false`) has different effects
7895 depending on the context in which function was called:
7896 - Discarded values in structured types are skipped. That is, the parser
7897 will behave as if the discarded value was never read.
7898 - In case a value outside a structured type is skipped, it is replaced
7899 with `null`. This case happens if the top-level element is skipped.
7900 @param[in] depth the depth of the recursion during parsing
7901 @param[in] event an event of type parse_event_t indicating the context in
7902 the callback function has been called
7903 @param[in,out] parsed the current intermediate parse result; note that
7904 writing to this value has no effect for parse_event_t::key events
7905 @return Whether the JSON value which called the function during parsing
7906 should be kept (`true`) or not (`false`). In the latter case, it is either
7907 skipped completely or replaced by an empty discarded object.
7908 @sa @ref parse for examples
7909 @since version 1.0.0
7910 */
7911 using parser_callback_t = typename parser::parser_callback_t;
7912
7913
7914 //////////////////
7915 // constructors //
7916 //////////////////
7917
7918 /// @name constructors and destructors
7919 /// Constructors of class @ref basic_json, copy/move constructor, copy
7920 /// assignment, static functions creating objects, and the destructor.
7921 /// @{
7922
7923 /*!
7924 @brief create an empty value with a given type
7925 Create an empty JSON value with a given type. The value will be default
7926 initialized with an empty value which depends on the type:
7927 Value type | initial value
7928 ----------- | -------------
7929 null | `null`
7930 boolean | `false`
7931 string | `""`
7932 number | `0`
7933 object | `{}`
7934 array | `[]`
7935 @param[in] v the type of the value to create
7936 @complexity Constant.
7937 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
7938 changes to any JSON value.
7939 @liveexample{The following code shows the constructor for different @ref
7940 value_t values,basic_json__value_t}
7941 @sa @ref clear() -- restores the postcondition of this constructor
7942 @since version 1.0.0
7943 */
basic_json(const value_t v)7944 basic_json(const value_t v)
7945 : m_type(v), m_value(v)
7946 {
7947 assert_invariant();
7948 }
7949
7950 /*!
7951 @brief create a null object
7952 Create a `null` JSON value. It either takes a null pointer as parameter
7953 (explicitly creating `null`) or no parameter (implicitly creating `null`).
7954 The passed null pointer itself is not read -- it is only used to choose
7955 the right constructor.
7956 @complexity Constant.
7957 @exceptionsafety No-throw guarantee: this constructor never throws
7958 exceptions.
7959 @liveexample{The following code shows the constructor with and without a
7960 null pointer parameter.,basic_json__nullptr_t}
7961 @since version 1.0.0
7962 */
basic_json(std::nullptr_t=nullptr)7963 basic_json(std::nullptr_t = nullptr) noexcept
7964 : basic_json(value_t::null)
7965 {
7966 assert_invariant();
7967 }
7968
7969 /*!
7970 @brief create a JSON value
7971 This is a "catch all" constructor for all compatible JSON types; that is,
7972 types for which a `to_json()` method exsits. The constructor forwards the
7973 parameter @a val to that method (to `json_serializer<U>::to_json` method
7974 with `U = uncvref_t<CompatibleType>`, to be exact).
7975 Template type @a CompatibleType includes, but is not limited to, the
7976 following types:
7977 - **arrays**: @ref array_t and all kinds of compatible containers such as
7978 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
7979 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
7980 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
7981 which a @ref basic_json value can be constructed.
7982 - **objects**: @ref object_t and all kinds of compatible associative
7983 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
7984 and `std::unordered_multimap` with a `key_type` compatible to
7985 @ref string_t and a `value_type` from which a @ref basic_json value can
7986 be constructed.
7987 - **strings**: @ref string_t, string literals, and all compatible string
7988 containers can be used.
7989 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
7990 @ref number_float_t, and all convertible number types such as `int`,
7991 `size_t`, `int64_t`, `float` or `double` can be used.
7992 - **boolean**: @ref boolean_t / `bool` can be used.
7993 See the examples below.
7994 @tparam CompatibleType a type such that:
7995 - @a CompatibleType is not derived from `std::istream`,
7996 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
7997 constructors),
7998 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
7999 @ref json_pointer, @ref iterator, etc ...)
8000 - @ref @ref json_serializer<U> has a
8001 `to_json(basic_json_t&, CompatibleType&&)` method
8002 @tparam U = `uncvref_t<CompatibleType>`
8003 @param[in] val the value to be forwarded to the respective constructor
8004 @complexity Usually linear in the size of the passed @a val, also
8005 depending on the implementation of the called `to_json()`
8006 method.
8007 @exceptionsafety Depends on the called constructor. For types directly
8008 supported by the library (i.e., all types for which no `to_json()` function
8009 was provided), strong guarantee holds: if an exception is thrown, there are
8010 no changes to any JSON value.
8011 @liveexample{The following code shows the constructor with several
8012 compatible types.,basic_json__CompatibleType}
8013 @since version 2.1.0
8014 */
8015 template<typename CompatibleType, typename U = detail::uncvref_t<CompatibleType>,
8016 detail::enable_if_t<not std::is_base_of<std::istream, U>::value and
8017 not std::is_same<U, basic_json_t>::value and
8018 not detail::is_basic_json_nested_type<
8019 basic_json_t, U>::value and
8020 detail::has_to_json<basic_json, U>::value,
8021 int> = 0>
basic_json(CompatibleType && val)8022 basic_json(CompatibleType && val) noexcept(noexcept(JSONSerializer<U>::to_json(
8023 std::declval<basic_json_t&>(), std::forward<CompatibleType>(val))))
8024 {
8025 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
8026 assert_invariant();
8027 }
8028
8029 /*!
8030 @brief create a container (array or object) from an initializer list
8031 Creates a JSON value of type array or object from the passed initializer
8032 list @a init. In case @a type_deduction is `true` (default), the type of
8033 the JSON value to be created is deducted from the initializer list @a init
8034 according to the following rules:
8035 1. If the list is empty, an empty JSON object value `{}` is created.
8036 2. If the list consists of pairs whose first element is a string, a JSON
8037 object value is created where the first elements of the pairs are
8038 treated as keys and the second elements are as values.
8039 3. In all other cases, an array is created.
8040 The rules aim to create the best fit between a C++ initializer list and
8041 JSON values. The rationale is as follows:
8042 1. The empty initializer list is written as `{}` which is exactly an empty
8043 JSON object.
8044 2. C++ has no way of describing mapped types other than to list a list of
8045 pairs. As JSON requires that keys must be of type string, rule 2 is the
8046 weakest constraint one can pose on initializer lists to interpret them
8047 as an object.
8048 3. In all other cases, the initializer list could not be interpreted as
8049 JSON object type, so interpreting it as JSON array type is safe.
8050 With the rules described above, the following JSON values cannot be
8051 expressed by an initializer list:
8052 - the empty array (`[]`): use @ref array(initializer_list_t)
8053 with an empty initializer list in this case
8054 - arrays whose elements satisfy rule 2: use @ref
8055 array(initializer_list_t) with the same initializer list
8056 in this case
8057 @note When used without parentheses around an empty initializer list, @ref
8058 basic_json() is called instead of this function, yielding the JSON null
8059 value.
8060 @param[in] init initializer list with JSON values
8061 @param[in] type_deduction internal parameter; when set to `true`, the type
8062 of the JSON value is deducted from the initializer list @a init; when set
8063 to `false`, the type provided via @a manual_type is forced. This mode is
8064 used by the functions @ref array(initializer_list_t) and
8065 @ref object(initializer_list_t).
8066 @param[in] manual_type internal parameter; when @a type_deduction is set
8067 to `false`, the created JSON value will use the provided type (only @ref
8068 value_t::array and @ref value_t::object are valid); when @a type_deduction
8069 is set to `true`, this parameter has no effect
8070 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
8071 `value_t::object`, but @a init contains an element which is not a pair
8072 whose first element is a string. In this case, the constructor could not
8073 create an object. If @a type_deduction would have be `true`, an array
8074 would have been created. See @ref object(initializer_list_t)
8075 for an example.
8076 @complexity Linear in the size of the initializer list @a init.
8077 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8078 changes to any JSON value.
8079 @liveexample{The example below shows how JSON values are created from
8080 initializer lists.,basic_json__list_init_t}
8081 @sa @ref array(initializer_list_t) -- create a JSON array
8082 value from an initializer list
8083 @sa @ref object(initializer_list_t) -- create a JSON object
8084 value from an initializer list
8085 @since version 1.0.0
8086 */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)8087 basic_json(initializer_list_t init,
8088 bool type_deduction = true,
8089 value_t manual_type = value_t::array)
8090 {
8091 // check if each element is an array with two elements whose first
8092 // element is a string
8093 bool is_an_object = std::all_of(init.begin(), init.end(),
8094 [](const detail::json_ref<basic_json>& element_ref)
8095 {
8096 return (element_ref->is_array() and element_ref->size() == 2 and (*element_ref)[0].is_string());
8097 });
8098
8099 // adjust type if type deduction is not wanted
8100 if (not type_deduction)
8101 {
8102 // if array is wanted, do not create an object though possible
8103 if (manual_type == value_t::array)
8104 {
8105 is_an_object = false;
8106 }
8107
8108 // if object is wanted but impossible, throw an exception
8109 if (JSON_UNLIKELY(manual_type == value_t::object and not is_an_object))
8110 {
8111 JSON_THROW(type_error::create(301, "cannot create object from initializer list"));
8112 }
8113 }
8114
8115 if (is_an_object)
8116 {
8117 // the initializer list is a list of pairs -> create object
8118 m_type = value_t::object;
8119 m_value = value_t::object;
8120
8121 std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
8122 {
8123 auto element = element_ref.moved_or_copied();
8124 m_value.object->emplace(
8125 std::move(*((*element.m_value.array)[0].m_value.string)),
8126 std::move((*element.m_value.array)[1]));
8127 });
8128 }
8129 else
8130 {
8131 // the initializer list describes an array -> create array
8132 m_type = value_t::array;
8133 m_value.array = create<array_t>(init.begin(), init.end());
8134 }
8135
8136 assert_invariant();
8137 }
8138
8139 /*!
8140 @brief explicitly create an array from an initializer list
8141 Creates a JSON array value from a given initializer list. That is, given a
8142 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
8143 initializer list is empty, the empty array `[]` is created.
8144 @note This function is only needed to express two edge cases that cannot
8145 be realized with the initializer list constructor (@ref
8146 basic_json(initializer_list_t, bool, value_t)). These cases
8147 are:
8148 1. creating an array whose elements are all pairs whose first element is a
8149 string -- in this case, the initializer list constructor would create an
8150 object, taking the first elements as keys
8151 2. creating an empty array -- passing the empty initializer list to the
8152 initializer list constructor yields an empty object
8153 @param[in] init initializer list with JSON values to create an array from
8154 (optional)
8155 @return JSON array value
8156 @complexity Linear in the size of @a init.
8157 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8158 changes to any JSON value.
8159 @liveexample{The following code shows an example for the `array`
8160 function.,array}
8161 @sa @ref basic_json(initializer_list_t, bool, value_t) --
8162 create a JSON value from an initializer list
8163 @sa @ref object(initializer_list_t) -- create a JSON object
8164 value from an initializer list
8165 @since version 1.0.0
8166 */
array(initializer_list_t init={})8167 static basic_json array(initializer_list_t init = {})
8168 {
8169 return basic_json(init, false, value_t::array);
8170 }
8171
8172 /*!
8173 @brief explicitly create an object from an initializer list
8174 Creates a JSON object value from a given initializer list. The initializer
8175 lists elements must be pairs, and their first elements must be strings. If
8176 the initializer list is empty, the empty object `{}` is created.
8177 @note This function is only added for symmetry reasons. In contrast to the
8178 related function @ref array(initializer_list_t), there are
8179 no cases which can only be expressed by this function. That is, any
8180 initializer list @a init can also be passed to the initializer list
8181 constructor @ref basic_json(initializer_list_t, bool, value_t).
8182 @param[in] init initializer list to create an object from (optional)
8183 @return JSON object value
8184 @throw type_error.301 if @a init is not a list of pairs whose first
8185 elements are strings. In this case, no object can be created. When such a
8186 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
8187 an array would have been created from the passed initializer list @a init.
8188 See example below.
8189 @complexity Linear in the size of @a init.
8190 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8191 changes to any JSON value.
8192 @liveexample{The following code shows an example for the `object`
8193 function.,object}
8194 @sa @ref basic_json(initializer_list_t, bool, value_t) --
8195 create a JSON value from an initializer list
8196 @sa @ref array(initializer_list_t) -- create a JSON array
8197 value from an initializer list
8198 @since version 1.0.0
8199 */
object(initializer_list_t init={})8200 static basic_json object(initializer_list_t init = {})
8201 {
8202 return basic_json(init, false, value_t::object);
8203 }
8204
8205 /*!
8206 @brief construct an array with count copies of given value
8207 Constructs a JSON array value by creating @a cnt copies of a passed value.
8208 In case @a cnt is `0`, an empty array is created.
8209 @param[in] cnt the number of JSON copies of @a val to create
8210 @param[in] val the JSON value to copy
8211 @post `std::distance(begin(),end()) == cnt` holds.
8212 @complexity Linear in @a cnt.
8213 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8214 changes to any JSON value.
8215 @liveexample{The following code shows examples for the @ref
8216 basic_json(size_type\, const basic_json&)
8217 constructor.,basic_json__size_type_basic_json}
8218 @since version 1.0.0
8219 */
basic_json(size_type cnt,const basic_json & val)8220 basic_json(size_type cnt, const basic_json& val)
8221 : m_type(value_t::array)
8222 {
8223 m_value.array = create<array_t>(cnt, val);
8224 assert_invariant();
8225 }
8226
8227 /*!
8228 @brief construct a JSON container given an iterator range
8229 Constructs the JSON value with the contents of the range `[first, last)`.
8230 The semantics depends on the different types a JSON value can have:
8231 - In case of a null type, invalid_iterator.206 is thrown.
8232 - In case of other primitive types (number, boolean, or string), @a first
8233 must be `begin()` and @a last must be `end()`. In this case, the value is
8234 copied. Otherwise, invalid_iterator.204 is thrown.
8235 - In case of structured types (array, object), the constructor behaves as
8236 similar versions for `std::vector` or `std::map`; that is, a JSON array
8237 or object is constructed from the values in the range.
8238 @tparam InputIT an input iterator type (@ref iterator or @ref
8239 const_iterator)
8240 @param[in] first begin of the range to copy from (included)
8241 @param[in] last end of the range to copy from (excluded)
8242 @pre Iterators @a first and @a last must be initialized. **This
8243 precondition is enforced with an assertion (see warning).** If
8244 assertions are switched off, a violation of this precondition yields
8245 undefined behavior.
8246 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
8247 checked efficiently. Only certain edge cases are detected; see the
8248 description of the exceptions below. A violation of this precondition
8249 yields undefined behavior.
8250 @warning A precondition is enforced with a runtime assertion that will
8251 result in calling `std::abort` if this precondition is not met.
8252 Assertions can be disabled by defining `NDEBUG` at compile time.
8253 See http://en.cppreference.com/w/cpp/error/assert for more
8254 information.
8255 @throw invalid_iterator.201 if iterators @a first and @a last are not
8256 compatible (i.e., do not belong to the same JSON value). In this case,
8257 the range `[first, last)` is undefined.
8258 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
8259 primitive type (number, boolean, or string), but @a first does not point
8260 to the first element any more. In this case, the range `[first, last)` is
8261 undefined. See example code below.
8262 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
8263 null value. In this case, the range `[first, last)` is undefined.
8264 @complexity Linear in distance between @a first and @a last.
8265 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8266 changes to any JSON value.
8267 @liveexample{The example below shows several ways to create JSON values by
8268 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
8269 @since version 1.0.0
8270 */
8271 template<class InputIT, typename std::enable_if<
8272 std::is_same<InputIT, typename basic_json_t::iterator>::value or
8273 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int>::type = 0>
basic_json(InputIT first,InputIT last)8274 basic_json(InputIT first, InputIT last)
8275 {
8276 assert(first.m_object != nullptr);
8277 assert(last.m_object != nullptr);
8278
8279 // make sure iterator fits the current value
8280 if (JSON_UNLIKELY(first.m_object != last.m_object))
8281 {
8282 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible"));
8283 }
8284
8285 // copy type from first iterator
8286 m_type = first.m_object->m_type;
8287
8288 // check if iterator range is complete for primitive values
8289 switch (m_type)
8290 {
8291 case value_t::boolean:
8292 case value_t::number_float:
8293 case value_t::number_integer:
8294 case value_t::number_unsigned:
8295 case value_t::string:
8296 {
8297 if (JSON_UNLIKELY(not first.m_it.primitive_iterator.is_begin()
8298 or not last.m_it.primitive_iterator.is_end()))
8299 {
8300 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
8301 }
8302 break;
8303 }
8304
8305 default:
8306 break;
8307 }
8308
8309 switch (m_type)
8310 {
8311 case value_t::number_integer:
8312 {
8313 m_value.number_integer = first.m_object->m_value.number_integer;
8314 break;
8315 }
8316
8317 case value_t::number_unsigned:
8318 {
8319 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
8320 break;
8321 }
8322
8323 case value_t::number_float:
8324 {
8325 m_value.number_float = first.m_object->m_value.number_float;
8326 break;
8327 }
8328
8329 case value_t::boolean:
8330 {
8331 m_value.boolean = first.m_object->m_value.boolean;
8332 break;
8333 }
8334
8335 case value_t::string:
8336 {
8337 m_value = *first.m_object->m_value.string;
8338 break;
8339 }
8340
8341 case value_t::object:
8342 {
8343 m_value.object = create<object_t>(first.m_it.object_iterator,
8344 last.m_it.object_iterator);
8345 break;
8346 }
8347
8348 case value_t::array:
8349 {
8350 m_value.array = create<array_t>(first.m_it.array_iterator,
8351 last.m_it.array_iterator);
8352 break;
8353 }
8354
8355 default:
8356 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
8357 std::string(first.m_object->type_name())));
8358 }
8359
8360 assert_invariant();
8361 }
8362
8363
8364 ///////////////////////////////////////
8365 // other constructors and destructor //
8366 ///////////////////////////////////////
8367
8368 /// @private
basic_json(const detail::json_ref<basic_json> & ref)8369 basic_json(const detail::json_ref<basic_json>& ref)
8370 : basic_json(ref.moved_or_copied())
8371 {}
8372
8373 /*!
8374 @brief copy constructor
8375 Creates a copy of a given JSON value.
8376 @param[in] other the JSON value to copy
8377 @post `*this == other`
8378 @complexity Linear in the size of @a other.
8379 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8380 changes to any JSON value.
8381 @requirement This function helps `basic_json` satisfying the
8382 [Container](http://en.cppreference.com/w/cpp/concept/Container)
8383 requirements:
8384 - The complexity is linear.
8385 - As postcondition, it holds: `other == basic_json(other)`.
8386 @liveexample{The following code shows an example for the copy
8387 constructor.,basic_json__basic_json}
8388 @since version 1.0.0
8389 */
basic_json(const basic_json & other)8390 basic_json(const basic_json& other)
8391 : m_type(other.m_type)
8392 {
8393 // check of passed value is valid
8394 other.assert_invariant();
8395
8396 switch (m_type)
8397 {
8398 case value_t::object:
8399 {
8400 m_value = *other.m_value.object;
8401 break;
8402 }
8403
8404 case value_t::array:
8405 {
8406 m_value = *other.m_value.array;
8407 break;
8408 }
8409
8410 case value_t::string:
8411 {
8412 m_value = *other.m_value.string;
8413 break;
8414 }
8415
8416 case value_t::boolean:
8417 {
8418 m_value = other.m_value.boolean;
8419 break;
8420 }
8421
8422 case value_t::number_integer:
8423 {
8424 m_value = other.m_value.number_integer;
8425 break;
8426 }
8427
8428 case value_t::number_unsigned:
8429 {
8430 m_value = other.m_value.number_unsigned;
8431 break;
8432 }
8433
8434 case value_t::number_float:
8435 {
8436 m_value = other.m_value.number_float;
8437 break;
8438 }
8439
8440 default:
8441 break;
8442 }
8443
8444 assert_invariant();
8445 }
8446
8447 /*!
8448 @brief move constructor
8449 Move constructor. Constructs a JSON value with the contents of the given
8450 value @a other using move semantics. It "steals" the resources from @a
8451 other and leaves it as JSON null value.
8452 @param[in,out] other value to move to this object
8453 @post `*this` has the same value as @a other before the call.
8454 @post @a other is a JSON null value.
8455 @complexity Constant.
8456 @exceptionsafety No-throw guarantee: this constructor never throws
8457 exceptions.
8458 @requirement This function helps `basic_json` satisfying the
8459 [MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible)
8460 requirements.
8461 @liveexample{The code below shows the move constructor explicitly called
8462 via std::move.,basic_json__moveconstructor}
8463 @since version 1.0.0
8464 */
basic_json(basic_json && other)8465 basic_json(basic_json&& other) noexcept
8466 : m_type(std::move(other.m_type)),
8467 m_value(std::move(other.m_value))
8468 {
8469 // check that passed value is valid
8470 other.assert_invariant();
8471
8472 // invalidate payload
8473 other.m_type = value_t::null;
8474 other.m_value = {};
8475
8476 assert_invariant();
8477 }
8478
8479 /*!
8480 @brief copy assignment
8481 Copy assignment operator. Copies a JSON value via the "copy and swap"
8482 strategy: It is expressed in terms of the copy constructor, destructor,
8483 and the `swap()` member function.
8484 @param[in] other value to copy from
8485 @complexity Linear.
8486 @requirement This function helps `basic_json` satisfying the
8487 [Container](http://en.cppreference.com/w/cpp/concept/Container)
8488 requirements:
8489 - The complexity is linear.
8490 @liveexample{The code below shows and example for the copy assignment. It
8491 creates a copy of value `a` which is then swapped with `b`. Finally\, the
8492 copy of `a` (which is the null value after the swap) is
8493 destroyed.,basic_json__copyassignment}
8494 @since version 1.0.0
8495 */
operator =(basic_json other)8496 reference& operator=(basic_json other) noexcept (
8497 std::is_nothrow_move_constructible<value_t>::value and
8498 std::is_nothrow_move_assignable<value_t>::value and
8499 std::is_nothrow_move_constructible<json_value>::value and
8500 std::is_nothrow_move_assignable<json_value>::value
8501 )
8502 {
8503 // check that passed value is valid
8504 other.assert_invariant();
8505
8506 using std::swap;
8507 swap(m_type, other.m_type);
8508 swap(m_value, other.m_value);
8509
8510 assert_invariant();
8511 return *this;
8512 }
8513
8514 /*!
8515 @brief destructor
8516 Destroys the JSON value and frees all allocated memory.
8517 @complexity Linear.
8518 @requirement This function helps `basic_json` satisfying the
8519 [Container](http://en.cppreference.com/w/cpp/concept/Container)
8520 requirements:
8521 - The complexity is linear.
8522 - All stored elements are destroyed and all memory is freed.
8523 @since version 1.0.0
8524 */
~basic_json()8525 ~basic_json()
8526 {
8527 assert_invariant();
8528 m_value.destroy(m_type);
8529 }
8530
8531 /// @}
8532
8533 public:
8534 ///////////////////////
8535 // object inspection //
8536 ///////////////////////
8537
8538 /// @name object inspection
8539 /// Functions to inspect the type of a JSON value.
8540 /// @{
8541
8542 /*!
8543 @brief serialization
8544 Serialization function for JSON values. The function tries to mimic
8545 Python's `json.dumps()` function, and currently supports its @a indent
8546 and @a ensure_ascii parameters.
8547 @param[in] indent If indent is nonnegative, then array elements and object
8548 members will be pretty-printed with that indent level. An indent level of
8549 `0` will only insert newlines. `-1` (the default) selects the most compact
8550 representation.
8551 @param[in] indent_char The character to use for indentation if @a indent is
8552 greater than `0`. The default is ` ` (space).
8553 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
8554 in the output are escaped with \uXXXX sequences, and the result consists
8555 of ASCII characters only.
8556 @return string containing the serialization of the JSON value
8557 @complexity Linear.
8558 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
8559 changes in the JSON value.
8560 @liveexample{The following example shows the effect of different @a indent\,
8561 @a indent_char\, and @a ensure_ascii parameters to the result of the
8562 serialization.,dump}
8563 @see https://docs.python.org/2/library/json.html#json.dump
8564 @since version 1.0.0; indentation character @a indent_char and option
8565 @a ensure_ascii added in version 3.0.0
8566 */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false) const8567 string_t dump(const int indent = -1, const char indent_char = ' ',
8568 const bool ensure_ascii = false) const
8569 {
8570 string_t result;
8571 serializer s(detail::output_adapter<char>(result), indent_char);
8572
8573 if (indent >= 0)
8574 {
8575 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
8576 }
8577 else
8578 {
8579 s.dump(*this, false, ensure_ascii, 0);
8580 }
8581
8582 return result;
8583 }
8584
8585 /*!
8586 @brief return the type of the JSON value (explicit)
8587 Return the type of the JSON value as a value from the @ref value_t
8588 enumeration.
8589 @return the type of the JSON value
8590 Value type | return value
8591 ------------------------- | -------------------------
8592 null | value_t::null
8593 boolean | value_t::boolean
8594 string | value_t::string
8595 number (integer) | value_t::number_integer
8596 number (unsigned integer) | value_t::number_unsigned
8597 number (foating-point) | value_t::number_float
8598 object | value_t::object
8599 array | value_t::array
8600 discarded | value_t::discarded
8601 @complexity Constant.
8602 @exceptionsafety No-throw guarantee: this member function never throws
8603 exceptions.
8604 @liveexample{The following code exemplifies `type()` for all JSON
8605 types.,type}
8606 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
8607 @sa @ref type_name() -- return the type as string
8608 @since version 1.0.0
8609 */
type() const8610 constexpr value_t type() const noexcept
8611 {
8612 return m_type;
8613 }
8614
8615 /*!
8616 @brief return whether type is primitive
8617 This function returns true if and only if the JSON type is primitive
8618 (string, number, boolean, or null).
8619 @return `true` if type is primitive (string, number, boolean, or null),
8620 `false` otherwise.
8621 @complexity Constant.
8622 @exceptionsafety No-throw guarantee: this member function never throws
8623 exceptions.
8624 @liveexample{The following code exemplifies `is_primitive()` for all JSON
8625 types.,is_primitive}
8626 @sa @ref is_structured() -- returns whether JSON value is structured
8627 @sa @ref is_null() -- returns whether JSON value is `null`
8628 @sa @ref is_string() -- returns whether JSON value is a string
8629 @sa @ref is_boolean() -- returns whether JSON value is a boolean
8630 @sa @ref is_number() -- returns whether JSON value is a number
8631 @since version 1.0.0
8632 */
is_primitive() const8633 constexpr bool is_primitive() const noexcept
8634 {
8635 return is_null() or is_string() or is_boolean() or is_number();
8636 }
8637
8638 /*!
8639 @brief return whether type is structured
8640 This function returns true if and only if the JSON type is structured
8641 (array or object).
8642 @return `true` if type is structured (array or object), `false` otherwise.
8643 @complexity Constant.
8644 @exceptionsafety No-throw guarantee: this member function never throws
8645 exceptions.
8646 @liveexample{The following code exemplifies `is_structured()` for all JSON
8647 types.,is_structured}
8648 @sa @ref is_primitive() -- returns whether value is primitive
8649 @sa @ref is_array() -- returns whether value is an array
8650 @sa @ref is_object() -- returns whether value is an object
8651 @since version 1.0.0
8652 */
is_structured() const8653 constexpr bool is_structured() const noexcept
8654 {
8655 return is_array() or is_object();
8656 }
8657
8658 /*!
8659 @brief return whether value is null
8660 This function returns true if and only if the JSON value is null.
8661 @return `true` if type is null, `false` otherwise.
8662 @complexity Constant.
8663 @exceptionsafety No-throw guarantee: this member function never throws
8664 exceptions.
8665 @liveexample{The following code exemplifies `is_null()` for all JSON
8666 types.,is_null}
8667 @since version 1.0.0
8668 */
is_null() const8669 constexpr bool is_null() const noexcept
8670 {
8671 return (m_type == value_t::null);
8672 }
8673
8674 /*!
8675 @brief return whether value is a boolean
8676 This function returns true if and only if the JSON value is a boolean.
8677 @return `true` if type is boolean, `false` otherwise.
8678 @complexity Constant.
8679 @exceptionsafety No-throw guarantee: this member function never throws
8680 exceptions.
8681 @liveexample{The following code exemplifies `is_boolean()` for all JSON
8682 types.,is_boolean}
8683 @since version 1.0.0
8684 */
is_boolean() const8685 constexpr bool is_boolean() const noexcept
8686 {
8687 return (m_type == value_t::boolean);
8688 }
8689
8690 /*!
8691 @brief return whether value is a number
8692 This function returns true if and only if the JSON value is a number. This
8693 includes both integer (signed and unsigned) and floating-point values.
8694 @return `true` if type is number (regardless whether integer, unsigned
8695 integer or floating-type), `false` otherwise.
8696 @complexity Constant.
8697 @exceptionsafety No-throw guarantee: this member function never throws
8698 exceptions.
8699 @liveexample{The following code exemplifies `is_number()` for all JSON
8700 types.,is_number}
8701 @sa @ref is_number_integer() -- check if value is an integer or unsigned
8702 integer number
8703 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
8704 number
8705 @sa @ref is_number_float() -- check if value is a floating-point number
8706 @since version 1.0.0
8707 */
is_number() const8708 constexpr bool is_number() const noexcept
8709 {
8710 return is_number_integer() or is_number_float();
8711 }
8712
8713 /*!
8714 @brief return whether value is an integer number
8715 This function returns true if and only if the JSON value is a signed or
8716 unsigned integer number. This excludes floating-point values.
8717 @return `true` if type is an integer or unsigned integer number, `false`
8718 otherwise.
8719 @complexity Constant.
8720 @exceptionsafety No-throw guarantee: this member function never throws
8721 exceptions.
8722 @liveexample{The following code exemplifies `is_number_integer()` for all
8723 JSON types.,is_number_integer}
8724 @sa @ref is_number() -- check if value is a number
8725 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
8726 number
8727 @sa @ref is_number_float() -- check if value is a floating-point number
8728 @since version 1.0.0
8729 */
is_number_integer() const8730 constexpr bool is_number_integer() const noexcept
8731 {
8732 return (m_type == value_t::number_integer or m_type == value_t::number_unsigned);
8733 }
8734
8735 /*!
8736 @brief return whether value is an unsigned integer number
8737 This function returns true if and only if the JSON value is an unsigned
8738 integer number. This excludes floating-point and signed integer values.
8739 @return `true` if type is an unsigned integer number, `false` otherwise.
8740 @complexity Constant.
8741 @exceptionsafety No-throw guarantee: this member function never throws
8742 exceptions.
8743 @liveexample{The following code exemplifies `is_number_unsigned()` for all
8744 JSON types.,is_number_unsigned}
8745 @sa @ref is_number() -- check if value is a number
8746 @sa @ref is_number_integer() -- check if value is an integer or unsigned
8747 integer number
8748 @sa @ref is_number_float() -- check if value is a floating-point number
8749 @since version 2.0.0
8750 */
is_number_unsigned() const8751 constexpr bool is_number_unsigned() const noexcept
8752 {
8753 return (m_type == value_t::number_unsigned);
8754 }
8755
8756 /*!
8757 @brief return whether value is a floating-point number
8758 This function returns true if and only if the JSON value is a
8759 floating-point number. This excludes signed and unsigned integer values.
8760 @return `true` if type is a floating-point number, `false` otherwise.
8761 @complexity Constant.
8762 @exceptionsafety No-throw guarantee: this member function never throws
8763 exceptions.
8764 @liveexample{The following code exemplifies `is_number_float()` for all
8765 JSON types.,is_number_float}
8766 @sa @ref is_number() -- check if value is number
8767 @sa @ref is_number_integer() -- check if value is an integer number
8768 @sa @ref is_number_unsigned() -- check if value is an unsigned integer
8769 number
8770 @since version 1.0.0
8771 */
is_number_float() const8772 constexpr bool is_number_float() const noexcept
8773 {
8774 return (m_type == value_t::number_float);
8775 }
8776
8777 /*!
8778 @brief return whether value is an object
8779 This function returns true if and only if the JSON value is an object.
8780 @return `true` if type is object, `false` otherwise.
8781 @complexity Constant.
8782 @exceptionsafety No-throw guarantee: this member function never throws
8783 exceptions.
8784 @liveexample{The following code exemplifies `is_object()` for all JSON
8785 types.,is_object}
8786 @since version 1.0.0
8787 */
is_object() const8788 constexpr bool is_object() const noexcept
8789 {
8790 return (m_type == value_t::object);
8791 }
8792
8793 /*!
8794 @brief return whether value is an array
8795 This function returns true if and only if the JSON value is an array.
8796 @return `true` if type is array, `false` otherwise.
8797 @complexity Constant.
8798 @exceptionsafety No-throw guarantee: this member function never throws
8799 exceptions.
8800 @liveexample{The following code exemplifies `is_array()` for all JSON
8801 types.,is_array}
8802 @since version 1.0.0
8803 */
is_array() const8804 constexpr bool is_array() const noexcept
8805 {
8806 return (m_type == value_t::array);
8807 }
8808
8809 /*!
8810 @brief return whether value is a string
8811 This function returns true if and only if the JSON value is a string.
8812 @return `true` if type is string, `false` otherwise.
8813 @complexity Constant.
8814 @exceptionsafety No-throw guarantee: this member function never throws
8815 exceptions.
8816 @liveexample{The following code exemplifies `is_string()` for all JSON
8817 types.,is_string}
8818 @since version 1.0.0
8819 */
is_string() const8820 constexpr bool is_string() const noexcept
8821 {
8822 return (m_type == value_t::string);
8823 }
8824
8825 /*!
8826 @brief return whether value is discarded
8827 This function returns true if and only if the JSON value was discarded
8828 during parsing with a callback function (see @ref parser_callback_t).
8829 @note This function will always be `false` for JSON values after parsing.
8830 That is, discarded values can only occur during parsing, but will be
8831 removed when inside a structured value or replaced by null in other cases.
8832 @return `true` if type is discarded, `false` otherwise.
8833 @complexity Constant.
8834 @exceptionsafety No-throw guarantee: this member function never throws
8835 exceptions.
8836 @liveexample{The following code exemplifies `is_discarded()` for all JSON
8837 types.,is_discarded}
8838 @since version 1.0.0
8839 */
is_discarded() const8840 constexpr bool is_discarded() const noexcept
8841 {
8842 return (m_type == value_t::discarded);
8843 }
8844
8845 /*!
8846 @brief return the type of the JSON value (implicit)
8847 Implicitly return the type of the JSON value as a value from the @ref
8848 value_t enumeration.
8849 @return the type of the JSON value
8850 @complexity Constant.
8851 @exceptionsafety No-throw guarantee: this member function never throws
8852 exceptions.
8853 @liveexample{The following code exemplifies the @ref value_t operator for
8854 all JSON types.,operator__value_t}
8855 @sa @ref type() -- return the type of the JSON value (explicit)
8856 @sa @ref type_name() -- return the type as string
8857 @since version 1.0.0
8858 */
operator value_t() const8859 constexpr operator value_t() const noexcept
8860 {
8861 return m_type;
8862 }
8863
8864 /// @}
8865
8866 private:
8867 //////////////////
8868 // value access //
8869 //////////////////
8870
8871 /// get a boolean (explicit)
get_impl(boolean_t *) const8872 boolean_t get_impl(boolean_t* /*unused*/) const
8873 {
8874 if (JSON_LIKELY(is_boolean()))
8875 {
8876 return m_value.boolean;
8877 }
8878
8879 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name())));
8880 }
8881
8882 /// get a pointer to the value (object)
get_impl_ptr(object_t *)8883 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
8884 {
8885 return is_object() ? m_value.object : nullptr;
8886 }
8887
8888 /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const8889 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
8890 {
8891 return is_object() ? m_value.object : nullptr;
8892 }
8893
8894 /// get a pointer to the value (array)
get_impl_ptr(array_t *)8895 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
8896 {
8897 return is_array() ? m_value.array : nullptr;
8898 }
8899
8900 /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const8901 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
8902 {
8903 return is_array() ? m_value.array : nullptr;
8904 }
8905
8906 /// get a pointer to the value (string)
get_impl_ptr(string_t *)8907 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
8908 {
8909 return is_string() ? m_value.string : nullptr;
8910 }
8911
8912 /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const8913 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
8914 {
8915 return is_string() ? m_value.string : nullptr;
8916 }
8917
8918 /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)8919 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
8920 {
8921 return is_boolean() ? &m_value.boolean : nullptr;
8922 }
8923
8924 /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const8925 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
8926 {
8927 return is_boolean() ? &m_value.boolean : nullptr;
8928 }
8929
8930 /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)8931 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
8932 {
8933 return is_number_integer() ? &m_value.number_integer : nullptr;
8934 }
8935
8936 /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const8937 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
8938 {
8939 return is_number_integer() ? &m_value.number_integer : nullptr;
8940 }
8941
8942 /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)8943 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
8944 {
8945 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
8946 }
8947
8948 /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const8949 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
8950 {
8951 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
8952 }
8953
8954 /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)8955 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
8956 {
8957 return is_number_float() ? &m_value.number_float : nullptr;
8958 }
8959
8960 /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const8961 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
8962 {
8963 return is_number_float() ? &m_value.number_float : nullptr;
8964 }
8965
8966 /*!
8967 @brief helper function to implement get_ref()
8968 This function helps to implement get_ref() without code duplication for
8969 const and non-const overloads
8970 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
8971 @throw type_error.303 if ReferenceType does not match underlying value
8972 type of the current JSON
8973 */
8974 template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)8975 static ReferenceType get_ref_impl(ThisType& obj)
8976 {
8977 // delegate the call to get_ptr<>()
8978 auto ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
8979
8980 if (JSON_LIKELY(ptr != nullptr))
8981 {
8982 return *ptr;
8983 }
8984
8985 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name())));
8986 }
8987
8988 public:
8989 /// @name value access
8990 /// Direct access to the stored value of a JSON value.
8991 /// @{
8992
8993 /*!
8994 @brief get special-case overload
8995 This overloads avoids a lot of template boilerplate, it can be seen as the
8996 identity method
8997 @tparam BasicJsonType == @ref basic_json
8998 @return a copy of *this
8999 @complexity Constant.
9000 @since version 2.1.0
9001 */
9002 template <
9003 typename BasicJsonType,
9004 detail::enable_if_t<std::is_same<typename std::remove_const<BasicJsonType>::type,
9005 basic_json_t>::value,
9006 int> = 0 >
get() const9007 basic_json get() const
9008 {
9009 return *this;
9010 }
9011
9012 /*!
9013 @brief get a value (explicit)
9014 Explicit type conversion between the JSON value and a compatible value
9015 which is [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
9016 and [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
9017 The value is converted by calling the @ref json_serializer<ValueType>
9018 `from_json()` method.
9019 The function is equivalent to executing
9020 @code {.cpp}
9021 ValueType ret;
9022 JSONSerializer<ValueType>::from_json(*this, ret);
9023 return ret;
9024 @endcode
9025 This overloads is chosen if:
9026 - @a ValueType is not @ref basic_json,
9027 - @ref json_serializer<ValueType> has a `from_json()` method of the form
9028 `void from_json(const basic_json&, ValueType&)`, and
9029 - @ref json_serializer<ValueType> does not have a `from_json()` method of
9030 the form `ValueType from_json(const basic_json&)`
9031 @tparam ValueTypeCV the provided value type
9032 @tparam ValueType the returned value type
9033 @return copy of the JSON value, converted to @a ValueType
9034 @throw what @ref json_serializer<ValueType> `from_json()` method throws
9035 @liveexample{The example below shows several conversions from JSON values
9036 to other types. There a few things to note: (1) Floating-point numbers can
9037 be converted to integers\, (2) A JSON array can be converted to a standard
9038 `std::vector<short>`\, (3) A JSON object can be converted to C++
9039 associative containers such as `std::unordered_map<std::string\,
9040 json>`.,get__ValueType_const}
9041 @since version 2.1.0
9042 */
9043 template <
9044 typename ValueTypeCV,
9045 typename ValueType = detail::uncvref_t<ValueTypeCV>,
9046 detail::enable_if_t <
9047 not std::is_same<basic_json_t, ValueType>::value and
9048 detail::has_from_json<basic_json_t, ValueType>::value and
9049 not detail::has_non_default_from_json<basic_json_t, ValueType>::value,
9050 int > = 0 >
9051 ValueType get() const noexcept(noexcept(
9052 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
9053 {
9054 // we cannot static_assert on ValueTypeCV being non-const, because
9055 // there is support for get<const basic_json_t>(), which is why we
9056 // still need the uncvref
9057 static_assert(not std::is_reference<ValueTypeCV>::value,
9058 "get() cannot be used with reference types, you might want to use get_ref()");
9059 static_assert(std::is_default_constructible<ValueType>::value,
9060 "types must be DefaultConstructible when used with get()");
9061
9062 ValueType ret;
9063 JSONSerializer<ValueType>::from_json(*this, ret);
9064 return ret;
9065 }
9066
9067 /*!
9068 @brief get a value (explicit); special case
9069 Explicit type conversion between the JSON value and a compatible value
9070 which is **not** [CopyConstructible](http://en.cppreference.com/w/cpp/concept/CopyConstructible)
9071 and **not** [DefaultConstructible](http://en.cppreference.com/w/cpp/concept/DefaultConstructible).
9072 The value is converted by calling the @ref json_serializer<ValueType>
9073 `from_json()` method.
9074 The function is equivalent to executing
9075 @code {.cpp}
9076 return JSONSerializer<ValueTypeCV>::from_json(*this);
9077 @endcode
9078 This overloads is chosen if:
9079 - @a ValueType is not @ref basic_json and
9080 - @ref json_serializer<ValueType> has a `from_json()` method of the form
9081 `ValueType from_json(const basic_json&)`
9082 @note If @ref json_serializer<ValueType> has both overloads of
9083 `from_json()`, this one is chosen.
9084 @tparam ValueTypeCV the provided value type
9085 @tparam ValueType the returned value type
9086 @return copy of the JSON value, converted to @a ValueType
9087 @throw what @ref json_serializer<ValueType> `from_json()` method throws
9088 @since version 2.1.0
9089 */
9090 template <
9091 typename ValueTypeCV,
9092 typename ValueType = detail::uncvref_t<ValueTypeCV>,
9093 detail::enable_if_t<not std::is_same<basic_json_t, ValueType>::value and
9094 detail::has_non_default_from_json<basic_json_t,
9095 ValueType>::value, int> = 0 >
9096 ValueType get() const noexcept(noexcept(
9097 JSONSerializer<ValueTypeCV>::from_json(std::declval<const basic_json_t&>())))
9098 {
9099 static_assert(not std::is_reference<ValueTypeCV>::value,
9100 "get() cannot be used with reference types, you might want to use get_ref()");
9101 return JSONSerializer<ValueTypeCV>::from_json(*this);
9102 }
9103
9104 /*!
9105 @brief get a pointer value (explicit)
9106 Explicit pointer access to the internally stored JSON value. No copies are
9107 made.
9108 @warning The pointer becomes invalid if the underlying JSON object
9109 changes.
9110 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
9111 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
9112 @ref number_unsigned_t, or @ref number_float_t.
9113 @return pointer to the internally stored JSON value if the requested
9114 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
9115 @complexity Constant.
9116 @liveexample{The example below shows how pointers to internal values of a
9117 JSON value can be requested. Note that no type conversions are made and a
9118 `nullptr` is returned if the value and the requested pointer type does not
9119 match.,get__PointerType}
9120 @sa @ref get_ptr() for explicit pointer-member access
9121 @since version 1.0.0
9122 */
9123 template<typename PointerType, typename std::enable_if<
9124 std::is_pointer<PointerType>::value, int>::type = 0>
9125 PointerType get() noexcept
9126 {
9127 // delegate the call to get_ptr
9128 return get_ptr<PointerType>();
9129 }
9130
9131 /*!
9132 @brief get a pointer value (explicit)
9133 @copydoc get()
9134 */
9135 template<typename PointerType, typename std::enable_if<
9136 std::is_pointer<PointerType>::value, int>::type = 0>
get() const9137 constexpr const PointerType get() const noexcept
9138 {
9139 // delegate the call to get_ptr
9140 return get_ptr<PointerType>();
9141 }
9142
9143 /*!
9144 @brief get a pointer value (implicit)
9145 Implicit pointer access to the internally stored JSON value. No copies are
9146 made.
9147 @warning Writing data to the pointee of the result yields an undefined
9148 state.
9149 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
9150 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
9151 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
9152 assertion.
9153 @return pointer to the internally stored JSON value if the requested
9154 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
9155 @complexity Constant.
9156 @liveexample{The example below shows how pointers to internal values of a
9157 JSON value can be requested. Note that no type conversions are made and a
9158 `nullptr` is returned if the value and the requested pointer type does not
9159 match.,get_ptr}
9160 @since version 1.0.0
9161 */
9162 template<typename PointerType, typename std::enable_if<
9163 std::is_pointer<PointerType>::value, int>::type = 0>
9164 PointerType get_ptr() noexcept
9165 {
9166 // get the type of the PointerType (remove pointer and const)
9167 using pointee_t = typename std::remove_const<typename
9168 std::remove_pointer<typename
9169 std::remove_const<PointerType>::type>::type>::type;
9170 // make sure the type matches the allowed types
9171 static_assert(
9172 std::is_same<object_t, pointee_t>::value
9173 or std::is_same<array_t, pointee_t>::value
9174 or std::is_same<string_t, pointee_t>::value
9175 or std::is_same<boolean_t, pointee_t>::value
9176 or std::is_same<number_integer_t, pointee_t>::value
9177 or std::is_same<number_unsigned_t, pointee_t>::value
9178 or std::is_same<number_float_t, pointee_t>::value
9179 , "incompatible pointer type");
9180
9181 // delegate the call to get_impl_ptr<>()
9182 return get_impl_ptr(static_cast<PointerType>(nullptr));
9183 }
9184
9185 /*!
9186 @brief get a pointer value (implicit)
9187 @copydoc get_ptr()
9188 */
9189 template<typename PointerType, typename std::enable_if<
9190 std::is_pointer<PointerType>::value and
9191 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int>::type = 0>
get_ptr() const9192 constexpr const PointerType get_ptr() const noexcept
9193 {
9194 // get the type of the PointerType (remove pointer and const)
9195 using pointee_t = typename std::remove_const<typename
9196 std::remove_pointer<typename
9197 std::remove_const<PointerType>::type>::type>::type;
9198 // make sure the type matches the allowed types
9199 static_assert(
9200 std::is_same<object_t, pointee_t>::value
9201 or std::is_same<array_t, pointee_t>::value
9202 or std::is_same<string_t, pointee_t>::value
9203 or std::is_same<boolean_t, pointee_t>::value
9204 or std::is_same<number_integer_t, pointee_t>::value
9205 or std::is_same<number_unsigned_t, pointee_t>::value
9206 or std::is_same<number_float_t, pointee_t>::value
9207 , "incompatible pointer type");
9208
9209 // delegate the call to get_impl_ptr<>() const
9210 return get_impl_ptr(static_cast<PointerType>(nullptr));
9211 }
9212
9213 /*!
9214 @brief get a reference value (implicit)
9215 Implicit reference access to the internally stored JSON value. No copies
9216 are made.
9217 @warning Writing data to the referee of the result yields an undefined
9218 state.
9219 @tparam ReferenceType reference type; must be a reference to @ref array_t,
9220 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
9221 @ref number_float_t. Enforced by static assertion.
9222 @return reference to the internally stored JSON value if the requested
9223 reference type @a ReferenceType fits to the JSON value; throws
9224 type_error.303 otherwise
9225 @throw type_error.303 in case passed type @a ReferenceType is incompatible
9226 with the stored JSON value; see example below
9227 @complexity Constant.
9228 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
9229 @since version 1.1.0
9230 */
9231 template<typename ReferenceType, typename std::enable_if<
9232 std::is_reference<ReferenceType>::value, int>::type = 0>
9233 ReferenceType get_ref()
9234 {
9235 // delegate call to get_ref_impl
9236 return get_ref_impl<ReferenceType>(*this);
9237 }
9238
9239 /*!
9240 @brief get a reference value (implicit)
9241 @copydoc get_ref()
9242 */
9243 template<typename ReferenceType, typename std::enable_if<
9244 std::is_reference<ReferenceType>::value and
9245 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int>::type = 0>
9246 ReferenceType get_ref() const
9247 {
9248 // delegate call to get_ref_impl
9249 return get_ref_impl<ReferenceType>(*this);
9250 }
9251
9252 /*!
9253 @brief get a value (implicit)
9254 Implicit type conversion between the JSON value and a compatible value.
9255 The call is realized by calling @ref get() const.
9256 @tparam ValueType non-pointer type compatible to the JSON value, for
9257 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
9258 `std::vector` types for JSON arrays. The character type of @ref string_t
9259 as well as an initializer list of this type is excluded to avoid
9260 ambiguities as these types implicitly convert to `std::string`.
9261 @return copy of the JSON value, converted to type @a ValueType
9262 @throw type_error.302 in case passed type @a ValueType is incompatible
9263 to the JSON value type (e.g., the JSON value is of type boolean, but a
9264 string is requested); see example below
9265 @complexity Linear in the size of the JSON value.
9266 @liveexample{The example below shows several conversions from JSON values
9267 to other types. There a few things to note: (1) Floating-point numbers can
9268 be converted to integers\, (2) A JSON array can be converted to a standard
9269 `std::vector<short>`\, (3) A JSON object can be converted to C++
9270 associative containers such as `std::unordered_map<std::string\,
9271 json>`.,operator__ValueType}
9272 @since version 1.0.0
9273 */
9274 template < typename ValueType, typename std::enable_if <
9275 not std::is_pointer<ValueType>::value and
9276 not std::is_same<ValueType, detail::json_ref<basic_json>>::value and
9277 not std::is_same<ValueType, typename string_t::value_type>::value
9278 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
9279 and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
9280 #endif
9281 #if defined(JSON_HAS_CPP_17)
9282 and not std::is_same<ValueType, typename std::string_view>::value
9283 #endif
9284 , int >::type = 0 >
operator ValueType() const9285 operator ValueType() const
9286 {
9287 // delegate the call to get<>() const
9288 return get<ValueType>();
9289 }
9290
9291 /// @}
9292
9293
9294 ////////////////////
9295 // element access //
9296 ////////////////////
9297
9298 /// @name element access
9299 /// Access to the JSON value.
9300 /// @{
9301
9302 /*!
9303 @brief access specified array element with bounds checking
9304 Returns a reference to the element at specified location @a idx, with
9305 bounds checking.
9306 @param[in] idx index of the element to access
9307 @return reference to the element at index @a idx
9308 @throw type_error.304 if the JSON value is not an array; in this case,
9309 calling `at` with an index makes no sense. See example below.
9310 @throw out_of_range.401 if the index @a idx is out of range of the array;
9311 that is, `idx >= size()`. See example below.
9312 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9313 changes in the JSON value.
9314 @complexity Constant.
9315 @since version 1.0.0
9316 @liveexample{The example below shows how array elements can be read and
9317 written using `at()`. It also demonstrates the different exceptions that
9318 can be thrown.,at__size_type}
9319 */
at(size_type idx)9320 reference at(size_type idx)
9321 {
9322 // at only works for arrays
9323 if (JSON_LIKELY(is_array()))
9324 {
9325 JSON_TRY
9326 {
9327 return m_value.array->at(idx);
9328 }
9329 JSON_CATCH (std::out_of_range&)
9330 {
9331 // create better exception explanation
9332 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
9333 }
9334 }
9335 else
9336 {
9337 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9338 }
9339 }
9340
9341 /*!
9342 @brief access specified array element with bounds checking
9343 Returns a const reference to the element at specified location @a idx,
9344 with bounds checking.
9345 @param[in] idx index of the element to access
9346 @return const reference to the element at index @a idx
9347 @throw type_error.304 if the JSON value is not an array; in this case,
9348 calling `at` with an index makes no sense. See example below.
9349 @throw out_of_range.401 if the index @a idx is out of range of the array;
9350 that is, `idx >= size()`. See example below.
9351 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9352 changes in the JSON value.
9353 @complexity Constant.
9354 @since version 1.0.0
9355 @liveexample{The example below shows how array elements can be read using
9356 `at()`. It also demonstrates the different exceptions that can be thrown.,
9357 at__size_type_const}
9358 */
at(size_type idx) const9359 const_reference at(size_type idx) const
9360 {
9361 // at only works for arrays
9362 if (JSON_LIKELY(is_array()))
9363 {
9364 JSON_TRY
9365 {
9366 return m_value.array->at(idx);
9367 }
9368 JSON_CATCH (std::out_of_range&)
9369 {
9370 // create better exception explanation
9371 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
9372 }
9373 }
9374 else
9375 {
9376 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9377 }
9378 }
9379
9380 /*!
9381 @brief access specified object element with bounds checking
9382 Returns a reference to the element at with specified key @a key, with
9383 bounds checking.
9384 @param[in] key key of the element to access
9385 @return reference to the element at key @a key
9386 @throw type_error.304 if the JSON value is not an object; in this case,
9387 calling `at` with a key makes no sense. See example below.
9388 @throw out_of_range.403 if the key @a key is is not stored in the object;
9389 that is, `find(key) == end()`. See example below.
9390 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9391 changes in the JSON value.
9392 @complexity Logarithmic in the size of the container.
9393 @sa @ref operator[](const typename object_t::key_type&) for unchecked
9394 access by reference
9395 @sa @ref value() for access by value with a default value
9396 @since version 1.0.0
9397 @liveexample{The example below shows how object elements can be read and
9398 written using `at()`. It also demonstrates the different exceptions that
9399 can be thrown.,at__object_t_key_type}
9400 */
at(const typename object_t::key_type & key)9401 reference at(const typename object_t::key_type& key)
9402 {
9403 // at only works for objects
9404 if (JSON_LIKELY(is_object()))
9405 {
9406 JSON_TRY
9407 {
9408 return m_value.object->at(key);
9409 }
9410 JSON_CATCH (std::out_of_range&)
9411 {
9412 // create better exception explanation
9413 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
9414 }
9415 }
9416 else
9417 {
9418 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9419 }
9420 }
9421
9422 /*!
9423 @brief access specified object element with bounds checking
9424 Returns a const reference to the element at with specified key @a key,
9425 with bounds checking.
9426 @param[in] key key of the element to access
9427 @return const reference to the element at key @a key
9428 @throw type_error.304 if the JSON value is not an object; in this case,
9429 calling `at` with a key makes no sense. See example below.
9430 @throw out_of_range.403 if the key @a key is is not stored in the object;
9431 that is, `find(key) == end()`. See example below.
9432 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
9433 changes in the JSON value.
9434 @complexity Logarithmic in the size of the container.
9435 @sa @ref operator[](const typename object_t::key_type&) for unchecked
9436 access by reference
9437 @sa @ref value() for access by value with a default value
9438 @since version 1.0.0
9439 @liveexample{The example below shows how object elements can be read using
9440 `at()`. It also demonstrates the different exceptions that can be thrown.,
9441 at__object_t_key_type_const}
9442 */
at(const typename object_t::key_type & key) const9443 const_reference at(const typename object_t::key_type& key) const
9444 {
9445 // at only works for objects
9446 if (JSON_LIKELY(is_object()))
9447 {
9448 JSON_TRY
9449 {
9450 return m_value.object->at(key);
9451 }
9452 JSON_CATCH (std::out_of_range&)
9453 {
9454 // create better exception explanation
9455 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found"));
9456 }
9457 }
9458 else
9459 {
9460 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name())));
9461 }
9462 }
9463
9464 /*!
9465 @brief access specified array element
9466 Returns a reference to the element at specified location @a idx.
9467 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
9468 then the array is silently filled up with `null` values to make `idx` a
9469 valid reference to the last stored element.
9470 @param[in] idx index of the element to access
9471 @return reference to the element at index @a idx
9472 @throw type_error.305 if the JSON value is not an array or null; in that
9473 cases, using the [] operator with an index makes no sense.
9474 @complexity Constant if @a idx is in the range of the array. Otherwise
9475 linear in `idx - size()`.
9476 @liveexample{The example below shows how array elements can be read and
9477 written using `[]` operator. Note the addition of `null`
9478 values.,operatorarray__size_type}
9479 @since version 1.0.0
9480 */
operator [](size_type idx)9481 reference operator[](size_type idx)
9482 {
9483 // implicitly convert null value to an empty array
9484 if (is_null())
9485 {
9486 m_type = value_t::array;
9487 m_value.array = create<array_t>();
9488 assert_invariant();
9489 }
9490
9491 // operator[] only works for arrays
9492 if (JSON_LIKELY(is_array()))
9493 {
9494 // fill up array with null values if given idx is outside range
9495 if (idx >= m_value.array->size())
9496 {
9497 m_value.array->insert(m_value.array->end(),
9498 idx - m_value.array->size() + 1,
9499 basic_json());
9500 }
9501
9502 return m_value.array->operator[](idx);
9503 }
9504
9505 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9506 }
9507
9508 /*!
9509 @brief access specified array element
9510 Returns a const reference to the element at specified location @a idx.
9511 @param[in] idx index of the element to access
9512 @return const reference to the element at index @a idx
9513 @throw type_error.305 if the JSON value is not an array; in that cases,
9514 using the [] operator with an index makes no sense.
9515 @complexity Constant.
9516 @liveexample{The example below shows how array elements can be read using
9517 the `[]` operator.,operatorarray__size_type_const}
9518 @since version 1.0.0
9519 */
operator [](size_type idx) const9520 const_reference operator[](size_type idx) const
9521 {
9522 // const operator[] only works for arrays
9523 if (JSON_LIKELY(is_array()))
9524 {
9525 return m_value.array->operator[](idx);
9526 }
9527
9528 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9529 }
9530
9531 /*!
9532 @brief access specified object element
9533 Returns a reference to the element at with specified key @a key.
9534 @note If @a key is not found in the object, then it is silently added to
9535 the object and filled with a `null` value to make `key` a valid reference.
9536 In case the value was `null` before, it is converted to an object.
9537 @param[in] key key of the element to access
9538 @return reference to the element at key @a key
9539 @throw type_error.305 if the JSON value is not an object or null; in that
9540 cases, using the [] operator with a key makes no sense.
9541 @complexity Logarithmic in the size of the container.
9542 @liveexample{The example below shows how object elements can be read and
9543 written using the `[]` operator.,operatorarray__key_type}
9544 @sa @ref at(const typename object_t::key_type&) for access by reference
9545 with range checking
9546 @sa @ref value() for access by value with a default value
9547 @since version 1.0.0
9548 */
operator [](const typename object_t::key_type & key)9549 reference operator[](const typename object_t::key_type& key)
9550 {
9551 // implicitly convert null value to an empty object
9552 if (is_null())
9553 {
9554 m_type = value_t::object;
9555 m_value.object = create<object_t>();
9556 assert_invariant();
9557 }
9558
9559 // operator[] only works for objects
9560 if (JSON_LIKELY(is_object()))
9561 {
9562 return m_value.object->operator[](key);
9563 }
9564
9565 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9566 }
9567
9568 /*!
9569 @brief read-only access specified object element
9570 Returns a const reference to the element at with specified key @a key. No
9571 bounds checking is performed.
9572 @warning If the element with key @a key does not exist, the behavior is
9573 undefined.
9574 @param[in] key key of the element to access
9575 @return const reference to the element at key @a key
9576 @pre The element with key @a key must exist. **This precondition is
9577 enforced with an assertion.**
9578 @throw type_error.305 if the JSON value is not an object; in that cases,
9579 using the [] operator with a key makes no sense.
9580 @complexity Logarithmic in the size of the container.
9581 @liveexample{The example below shows how object elements can be read using
9582 the `[]` operator.,operatorarray__key_type_const}
9583 @sa @ref at(const typename object_t::key_type&) for access by reference
9584 with range checking
9585 @sa @ref value() for access by value with a default value
9586 @since version 1.0.0
9587 */
operator [](const typename object_t::key_type & key) const9588 const_reference operator[](const typename object_t::key_type& key) const
9589 {
9590 // const operator[] only works for objects
9591 if (JSON_LIKELY(is_object()))
9592 {
9593 assert(m_value.object->find(key) != m_value.object->end());
9594 return m_value.object->find(key)->second;
9595 }
9596
9597 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9598 }
9599
9600 /*!
9601 @brief access specified object element
9602 Returns a reference to the element at with specified key @a key.
9603 @note If @a key is not found in the object, then it is silently added to
9604 the object and filled with a `null` value to make `key` a valid reference.
9605 In case the value was `null` before, it is converted to an object.
9606 @param[in] key key of the element to access
9607 @return reference to the element at key @a key
9608 @throw type_error.305 if the JSON value is not an object or null; in that
9609 cases, using the [] operator with a key makes no sense.
9610 @complexity Logarithmic in the size of the container.
9611 @liveexample{The example below shows how object elements can be read and
9612 written using the `[]` operator.,operatorarray__key_type}
9613 @sa @ref at(const typename object_t::key_type&) for access by reference
9614 with range checking
9615 @sa @ref value() for access by value with a default value
9616 @since version 1.1.0
9617 */
9618 template<typename T>
operator [](T * key)9619 reference operator[](T* key)
9620 {
9621 // implicitly convert null to object
9622 if (is_null())
9623 {
9624 m_type = value_t::object;
9625 m_value = value_t::object;
9626 assert_invariant();
9627 }
9628
9629 // at only works for objects
9630 if (JSON_LIKELY(is_object()))
9631 {
9632 return m_value.object->operator[](key);
9633 }
9634
9635 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9636 }
9637
9638 /*!
9639 @brief read-only access specified object element
9640 Returns a const reference to the element at with specified key @a key. No
9641 bounds checking is performed.
9642 @warning If the element with key @a key does not exist, the behavior is
9643 undefined.
9644 @param[in] key key of the element to access
9645 @return const reference to the element at key @a key
9646 @pre The element with key @a key must exist. **This precondition is
9647 enforced with an assertion.**
9648 @throw type_error.305 if the JSON value is not an object; in that cases,
9649 using the [] operator with a key makes no sense.
9650 @complexity Logarithmic in the size of the container.
9651 @liveexample{The example below shows how object elements can be read using
9652 the `[]` operator.,operatorarray__key_type_const}
9653 @sa @ref at(const typename object_t::key_type&) for access by reference
9654 with range checking
9655 @sa @ref value() for access by value with a default value
9656 @since version 1.1.0
9657 */
9658 template<typename T>
operator [](T * key) const9659 const_reference operator[](T* key) const
9660 {
9661 // at only works for objects
9662 if (JSON_LIKELY(is_object()))
9663 {
9664 assert(m_value.object->find(key) != m_value.object->end());
9665 return m_value.object->find(key)->second;
9666 }
9667
9668 JSON_THROW(type_error::create(305, "cannot use operator[] with " + std::string(type_name())));
9669 }
9670
9671 /*!
9672 @brief access specified object element with default value
9673 Returns either a copy of an object's element at the specified key @a key
9674 or a given default value if no element with key @a key exists.
9675 The function is basically equivalent to executing
9676 @code {.cpp}
9677 try {
9678 return at(key);
9679 } catch(out_of_range) {
9680 return default_value;
9681 }
9682 @endcode
9683 @note Unlike @ref at(const typename object_t::key_type&), this function
9684 does not throw if the given key @a key was not found.
9685 @note Unlike @ref operator[](const typename object_t::key_type& key), this
9686 function does not implicitly add an element to the position defined by @a
9687 key. This function is furthermore also applicable to const objects.
9688 @param[in] key key of the element to access
9689 @param[in] default_value the value to return if @a key is not found
9690 @tparam ValueType type compatible to JSON values, for instance `int` for
9691 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
9692 JSON arrays. Note the type of the expected value at @a key and the default
9693 value @a default_value must be compatible.
9694 @return copy of the element at key @a key or @a default_value if @a key
9695 is not found
9696 @throw type_error.306 if the JSON value is not an objec; in that cases,
9697 using `value()` with a key makes no sense.
9698 @complexity Logarithmic in the size of the container.
9699 @liveexample{The example below shows how object elements can be queried
9700 with a default value.,basic_json__value}
9701 @sa @ref at(const typename object_t::key_type&) for access by reference
9702 with range checking
9703 @sa @ref operator[](const typename object_t::key_type&) for unchecked
9704 access by reference
9705 @since version 1.0.0
9706 */
9707 template<class ValueType, typename std::enable_if<
9708 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
9709 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
9710 {
9711 // at only works for objects
9712 if (JSON_LIKELY(is_object()))
9713 {
9714 // if key is found, return value and given default value otherwise
9715 const auto it = find(key);
9716 if (it != end())
9717 {
9718 return *it;
9719 }
9720
9721 return default_value;
9722 }
9723
9724 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
9725 }
9726
9727 /*!
9728 @brief overload for a default value of type const char*
9729 @copydoc basic_json::value(const typename object_t::key_type&, ValueType) const
9730 */
value(const typename object_t::key_type & key,const char * default_value) const9731 string_t value(const typename object_t::key_type& key, const char* default_value) const
9732 {
9733 return value(key, string_t(default_value));
9734 }
9735
9736 /*!
9737 @brief access specified object element via JSON Pointer with default value
9738 Returns either a copy of an object's element at the specified key @a key
9739 or a given default value if no element with key @a key exists.
9740 The function is basically equivalent to executing
9741 @code {.cpp}
9742 try {
9743 return at(ptr);
9744 } catch(out_of_range) {
9745 return default_value;
9746 }
9747 @endcode
9748 @note Unlike @ref at(const json_pointer&), this function does not throw
9749 if the given key @a key was not found.
9750 @param[in] ptr a JSON pointer to the element to access
9751 @param[in] default_value the value to return if @a ptr found no value
9752 @tparam ValueType type compatible to JSON values, for instance `int` for
9753 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
9754 JSON arrays. Note the type of the expected value at @a key and the default
9755 value @a default_value must be compatible.
9756 @return copy of the element at key @a key or @a default_value if @a key
9757 is not found
9758 @throw type_error.306 if the JSON value is not an objec; in that cases,
9759 using `value()` with a key makes no sense.
9760 @complexity Logarithmic in the size of the container.
9761 @liveexample{The example below shows how object elements can be queried
9762 with a default value.,basic_json__value_ptr}
9763 @sa @ref operator[](const json_pointer&) for unchecked access by reference
9764 @since version 2.0.2
9765 */
9766 template<class ValueType, typename std::enable_if<
9767 std::is_convertible<basic_json_t, ValueType>::value, int>::type = 0>
9768 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
9769 {
9770 // at only works for objects
9771 if (JSON_LIKELY(is_object()))
9772 {
9773 // if pointer resolves a value, return it or use default value
9774 JSON_TRY
9775 {
9776 return ptr.get_checked(this);
9777 }
9778 JSON_CATCH (out_of_range&)
9779 {
9780 return default_value;
9781 }
9782 }
9783
9784 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name())));
9785 }
9786
9787 /*!
9788 @brief overload for a default value of type const char*
9789 @copydoc basic_json::value(const json_pointer&, ValueType) const
9790 */
value(const json_pointer & ptr,const char * default_value) const9791 string_t value(const json_pointer& ptr, const char* default_value) const
9792 {
9793 return value(ptr, string_t(default_value));
9794 }
9795
9796 /*!
9797 @brief access the first element
9798 Returns a reference to the first element in the container. For a JSON
9799 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
9800 @return In case of a structured type (array or object), a reference to the
9801 first element is returned. In case of number, string, or boolean values, a
9802 reference to the value is returned.
9803 @complexity Constant.
9804 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
9805 or an empty array or object (undefined behavior, **guarded by
9806 assertions**).
9807 @post The JSON value remains unchanged.
9808 @throw invalid_iterator.214 when called on `null` value
9809 @liveexample{The following code shows an example for `front()`.,front}
9810 @sa @ref back() -- access the last element
9811 @since version 1.0.0
9812 */
front()9813 reference front()
9814 {
9815 return *begin();
9816 }
9817
9818 /*!
9819 @copydoc basic_json::front()
9820 */
front() const9821 const_reference front() const
9822 {
9823 return *cbegin();
9824 }
9825
9826 /*!
9827 @brief access the last element
9828 Returns a reference to the last element in the container. For a JSON
9829 container `c`, the expression `c.back()` is equivalent to
9830 @code {.cpp}
9831 auto tmp = c.end();
9832 --tmp;
9833 return *tmp;
9834 @endcode
9835 @return In case of a structured type (array or object), a reference to the
9836 last element is returned. In case of number, string, or boolean values, a
9837 reference to the value is returned.
9838 @complexity Constant.
9839 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
9840 or an empty array or object (undefined behavior, **guarded by
9841 assertions**).
9842 @post The JSON value remains unchanged.
9843 @throw invalid_iterator.214 when called on a `null` value. See example
9844 below.
9845 @liveexample{The following code shows an example for `back()`.,back}
9846 @sa @ref front() -- access the first element
9847 @since version 1.0.0
9848 */
back()9849 reference back()
9850 {
9851 auto tmp = end();
9852 --tmp;
9853 return *tmp;
9854 }
9855
9856 /*!
9857 @copydoc basic_json::back()
9858 */
back() const9859 const_reference back() const
9860 {
9861 auto tmp = cend();
9862 --tmp;
9863 return *tmp;
9864 }
9865
9866 /*!
9867 @brief remove element given an iterator
9868 Removes the element specified by iterator @a pos. The iterator @a pos must
9869 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
9870 but is not dereferenceable) cannot be used as a value for @a pos.
9871 If called on a primitive type other than `null`, the resulting JSON value
9872 will be `null`.
9873 @param[in] pos iterator to the element to remove
9874 @return Iterator following the last removed element. If the iterator @a
9875 pos refers to the last element, the `end()` iterator is returned.
9876 @tparam IteratorType an @ref iterator or @ref const_iterator
9877 @post Invalidates iterators and references at or after the point of the
9878 erase, including the `end()` iterator.
9879 @throw type_error.307 if called on a `null` value; example: `"cannot use
9880 erase() with null"`
9881 @throw invalid_iterator.202 if called on an iterator which does not belong
9882 to the current JSON value; example: `"iterator does not fit current
9883 value"`
9884 @throw invalid_iterator.205 if called on a primitive type with invalid
9885 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
9886 out of range"`
9887 @complexity The complexity depends on the type:
9888 - objects: amortized constant
9889 - arrays: linear in distance between @a pos and the end of the container
9890 - strings: linear in the length of the string
9891 - other types: constant
9892 @liveexample{The example shows the result of `erase()` for different JSON
9893 types.,erase__IteratorType}
9894 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
9895 the given range
9896 @sa @ref erase(const typename object_t::key_type&) -- removes the element
9897 from an object at the given key
9898 @sa @ref erase(const size_type) -- removes the element from an array at
9899 the given index
9900 @since version 1.0.0
9901 */
9902 template<class IteratorType, typename std::enable_if<
9903 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
9904 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
9905 = 0>
9906 IteratorType erase(IteratorType pos)
9907 {
9908 // make sure iterator fits the current value
9909 if (JSON_UNLIKELY(this != pos.m_object))
9910 {
9911 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
9912 }
9913
9914 IteratorType result = end();
9915
9916 switch (m_type)
9917 {
9918 case value_t::boolean:
9919 case value_t::number_float:
9920 case value_t::number_integer:
9921 case value_t::number_unsigned:
9922 case value_t::string:
9923 {
9924 if (JSON_UNLIKELY(not pos.m_it.primitive_iterator.is_begin()))
9925 {
9926 JSON_THROW(invalid_iterator::create(205, "iterator out of range"));
9927 }
9928
9929 if (is_string())
9930 {
9931 AllocatorType<string_t> alloc;
9932 alloc.destroy(m_value.string);
9933 alloc.deallocate(m_value.string, 1);
9934 m_value.string = nullptr;
9935 }
9936
9937 m_type = value_t::null;
9938 assert_invariant();
9939 break;
9940 }
9941
9942 case value_t::object:
9943 {
9944 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
9945 break;
9946 }
9947
9948 case value_t::array:
9949 {
9950 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
9951 break;
9952 }
9953
9954 default:
9955 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
9956 }
9957
9958 return result;
9959 }
9960
9961 /*!
9962 @brief remove elements given an iterator range
9963 Removes the element specified by the range `[first; last)`. The iterator
9964 @a first does not need to be dereferenceable if `first == last`: erasing
9965 an empty range is a no-op.
9966 If called on a primitive type other than `null`, the resulting JSON value
9967 will be `null`.
9968 @param[in] first iterator to the beginning of the range to remove
9969 @param[in] last iterator past the end of the range to remove
9970 @return Iterator following the last removed element. If the iterator @a
9971 second refers to the last element, the `end()` iterator is returned.
9972 @tparam IteratorType an @ref iterator or @ref const_iterator
9973 @post Invalidates iterators and references at or after the point of the
9974 erase, including the `end()` iterator.
9975 @throw type_error.307 if called on a `null` value; example: `"cannot use
9976 erase() with null"`
9977 @throw invalid_iterator.203 if called on iterators which does not belong
9978 to the current JSON value; example: `"iterators do not fit current value"`
9979 @throw invalid_iterator.204 if called on a primitive type with invalid
9980 iterators (i.e., if `first != begin()` and `last != end()`); example:
9981 `"iterators out of range"`
9982 @complexity The complexity depends on the type:
9983 - objects: `log(size()) + std::distance(first, last)`
9984 - arrays: linear in the distance between @a first and @a last, plus linear
9985 in the distance between @a last and end of the container
9986 - strings: linear in the length of the string
9987 - other types: constant
9988 @liveexample{The example shows the result of `erase()` for different JSON
9989 types.,erase__IteratorType_IteratorType}
9990 @sa @ref erase(IteratorType) -- removes the element at a given position
9991 @sa @ref erase(const typename object_t::key_type&) -- removes the element
9992 from an object at the given key
9993 @sa @ref erase(const size_type) -- removes the element from an array at
9994 the given index
9995 @since version 1.0.0
9996 */
9997 template<class IteratorType, typename std::enable_if<
9998 std::is_same<IteratorType, typename basic_json_t::iterator>::value or
9999 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int>::type
10000 = 0>
10001 IteratorType erase(IteratorType first, IteratorType last)
10002 {
10003 // make sure iterator fits the current value
10004 if (JSON_UNLIKELY(this != first.m_object or this != last.m_object))
10005 {
10006 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value"));
10007 }
10008
10009 IteratorType result = end();
10010
10011 switch (m_type)
10012 {
10013 case value_t::boolean:
10014 case value_t::number_float:
10015 case value_t::number_integer:
10016 case value_t::number_unsigned:
10017 case value_t::string:
10018 {
10019 if (JSON_LIKELY(not first.m_it.primitive_iterator.is_begin()
10020 or not last.m_it.primitive_iterator.is_end()))
10021 {
10022 JSON_THROW(invalid_iterator::create(204, "iterators out of range"));
10023 }
10024
10025 if (is_string())
10026 {
10027 AllocatorType<string_t> alloc;
10028 alloc.destroy(m_value.string);
10029 alloc.deallocate(m_value.string, 1);
10030 m_value.string = nullptr;
10031 }
10032
10033 m_type = value_t::null;
10034 assert_invariant();
10035 break;
10036 }
10037
10038 case value_t::object:
10039 {
10040 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
10041 last.m_it.object_iterator);
10042 break;
10043 }
10044
10045 case value_t::array:
10046 {
10047 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
10048 last.m_it.array_iterator);
10049 break;
10050 }
10051
10052 default:
10053 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10054 }
10055
10056 return result;
10057 }
10058
10059 /*!
10060 @brief remove element from a JSON object given a key
10061 Removes elements from a JSON object with the key value @a key.
10062 @param[in] key value of the elements to remove
10063 @return Number of elements removed. If @a ObjectType is the default
10064 `std::map` type, the return value will always be `0` (@a key was not
10065 found) or `1` (@a key was found).
10066 @post References and iterators to the erased elements are invalidated.
10067 Other references and iterators are not affected.
10068 @throw type_error.307 when called on a type other than JSON object;
10069 example: `"cannot use erase() with null"`
10070 @complexity `log(size()) + count(key)`
10071 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
10072 @sa @ref erase(IteratorType) -- removes the element at a given position
10073 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10074 the given range
10075 @sa @ref erase(const size_type) -- removes the element from an array at
10076 the given index
10077 @since version 1.0.0
10078 */
erase(const typename object_t::key_type & key)10079 size_type erase(const typename object_t::key_type& key)
10080 {
10081 // this erase only works for objects
10082 if (JSON_LIKELY(is_object()))
10083 {
10084 return m_value.object->erase(key);
10085 }
10086
10087 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10088 }
10089
10090 /*!
10091 @brief remove element from a JSON array given an index
10092 Removes element from a JSON array at the index @a idx.
10093 @param[in] idx index of the element to remove
10094 @throw type_error.307 when called on a type other than JSON object;
10095 example: `"cannot use erase() with null"`
10096 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
10097 is out of range"`
10098 @complexity Linear in distance between @a idx and the end of the container.
10099 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
10100 @sa @ref erase(IteratorType) -- removes the element at a given position
10101 @sa @ref erase(IteratorType, IteratorType) -- removes the elements in
10102 the given range
10103 @sa @ref erase(const typename object_t::key_type&) -- removes the element
10104 from an object at the given key
10105 @since version 1.0.0
10106 */
erase(const size_type idx)10107 void erase(const size_type idx)
10108 {
10109 // this erase only works for arrays
10110 if (JSON_LIKELY(is_array()))
10111 {
10112 if (JSON_UNLIKELY(idx >= size()))
10113 {
10114 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
10115 }
10116
10117 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
10118 }
10119 else
10120 {
10121 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name())));
10122 }
10123 }
10124
10125 /// @}
10126
10127
10128 ////////////
10129 // lookup //
10130 ////////////
10131
10132 /// @name lookup
10133 /// @{
10134
10135 /*!
10136 @brief find an element in a JSON object
10137 Finds an element in a JSON object with key equivalent to @a key. If the
10138 element is not found or the JSON value is not an object, end() is
10139 returned.
10140 @note This method always returns @ref end() when executed on a JSON type
10141 that is not an object.
10142 @param[in] key key value of the element to search for.
10143 @return Iterator to an element with key equivalent to @a key. If no such
10144 element is found or the JSON value is not an object, past-the-end (see
10145 @ref end()) iterator is returned.
10146 @complexity Logarithmic in the size of the JSON object.
10147 @liveexample{The example shows how `find()` is used.,find__key_type}
10148 @since version 1.0.0
10149 */
10150 template<typename KeyT>
find(KeyT && key)10151 iterator find(KeyT&& key)
10152 {
10153 auto result = end();
10154
10155 if (is_object())
10156 {
10157 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10158 }
10159
10160 return result;
10161 }
10162
10163 /*!
10164 @brief find an element in a JSON object
10165 @copydoc find(KeyT&&)
10166 */
10167 template<typename KeyT>
find(KeyT && key) const10168 const_iterator find(KeyT&& key) const
10169 {
10170 auto result = cend();
10171
10172 if (is_object())
10173 {
10174 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
10175 }
10176
10177 return result;
10178 }
10179
10180 /*!
10181 @brief returns the number of occurrences of a key in a JSON object
10182 Returns the number of elements with key @a key. If ObjectType is the
10183 default `std::map` type, the return value will always be `0` (@a key was
10184 not found) or `1` (@a key was found).
10185 @note This method always returns `0` when executed on a JSON type that is
10186 not an object.
10187 @param[in] key key value of the element to count
10188 @return Number of elements with key @a key. If the JSON value is not an
10189 object, the return value will be `0`.
10190 @complexity Logarithmic in the size of the JSON object.
10191 @liveexample{The example shows how `count()` is used.,count}
10192 @since version 1.0.0
10193 */
10194 template<typename KeyT>
count(KeyT && key) const10195 size_type count(KeyT&& key) const
10196 {
10197 // return 0 for all nonobject types
10198 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
10199 }
10200
10201 /// @}
10202
10203
10204 ///////////////
10205 // iterators //
10206 ///////////////
10207
10208 /// @name iterators
10209 /// @{
10210
10211 /*!
10212 @brief returns an iterator to the first element
10213 Returns an iterator to the first element.
10214 @image html range-begin-end.svg "Illustration from cppreference.com"
10215 @return iterator to the first element
10216 @complexity Constant.
10217 @requirement This function helps `basic_json` satisfying the
10218 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10219 requirements:
10220 - The complexity is constant.
10221 @liveexample{The following code shows an example for `begin()`.,begin}
10222 @sa @ref cbegin() -- returns a const iterator to the beginning
10223 @sa @ref end() -- returns an iterator to the end
10224 @sa @ref cend() -- returns a const iterator to the end
10225 @since version 1.0.0
10226 */
begin()10227 iterator begin() noexcept
10228 {
10229 iterator result(this);
10230 result.set_begin();
10231 return result;
10232 }
10233
10234 /*!
10235 @copydoc basic_json::cbegin()
10236 */
begin() const10237 const_iterator begin() const noexcept
10238 {
10239 return cbegin();
10240 }
10241
10242 /*!
10243 @brief returns a const iterator to the first element
10244 Returns a const iterator to the first element.
10245 @image html range-begin-end.svg "Illustration from cppreference.com"
10246 @return const iterator to the first element
10247 @complexity Constant.
10248 @requirement This function helps `basic_json` satisfying the
10249 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10250 requirements:
10251 - The complexity is constant.
10252 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
10253 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
10254 @sa @ref begin() -- returns an iterator to the beginning
10255 @sa @ref end() -- returns an iterator to the end
10256 @sa @ref cend() -- returns a const iterator to the end
10257 @since version 1.0.0
10258 */
cbegin() const10259 const_iterator cbegin() const noexcept
10260 {
10261 const_iterator result(this);
10262 result.set_begin();
10263 return result;
10264 }
10265
10266 /*!
10267 @brief returns an iterator to one past the last element
10268 Returns an iterator to one past the last element.
10269 @image html range-begin-end.svg "Illustration from cppreference.com"
10270 @return iterator one past the last element
10271 @complexity Constant.
10272 @requirement This function helps `basic_json` satisfying the
10273 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10274 requirements:
10275 - The complexity is constant.
10276 @liveexample{The following code shows an example for `end()`.,end}
10277 @sa @ref cend() -- returns a const iterator to the end
10278 @sa @ref begin() -- returns an iterator to the beginning
10279 @sa @ref cbegin() -- returns a const iterator to the beginning
10280 @since version 1.0.0
10281 */
end()10282 iterator end() noexcept
10283 {
10284 iterator result(this);
10285 result.set_end();
10286 return result;
10287 }
10288
10289 /*!
10290 @copydoc basic_json::cend()
10291 */
end() const10292 const_iterator end() const noexcept
10293 {
10294 return cend();
10295 }
10296
10297 /*!
10298 @brief returns a const iterator to one past the last element
10299 Returns a const iterator to one past the last element.
10300 @image html range-begin-end.svg "Illustration from cppreference.com"
10301 @return const iterator one past the last element
10302 @complexity Constant.
10303 @requirement This function helps `basic_json` satisfying the
10304 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10305 requirements:
10306 - The complexity is constant.
10307 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
10308 @liveexample{The following code shows an example for `cend()`.,cend}
10309 @sa @ref end() -- returns an iterator to the end
10310 @sa @ref begin() -- returns an iterator to the beginning
10311 @sa @ref cbegin() -- returns a const iterator to the beginning
10312 @since version 1.0.0
10313 */
cend() const10314 const_iterator cend() const noexcept
10315 {
10316 const_iterator result(this);
10317 result.set_end();
10318 return result;
10319 }
10320
10321 /*!
10322 @brief returns an iterator to the reverse-beginning
10323 Returns an iterator to the reverse-beginning; that is, the last element.
10324 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10325 @complexity Constant.
10326 @requirement This function helps `basic_json` satisfying the
10327 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10328 requirements:
10329 - The complexity is constant.
10330 - Has the semantics of `reverse_iterator(end())`.
10331 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
10332 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
10333 @sa @ref rend() -- returns a reverse iterator to the end
10334 @sa @ref crend() -- returns a const reverse iterator to the end
10335 @since version 1.0.0
10336 */
rbegin()10337 reverse_iterator rbegin() noexcept
10338 {
10339 return reverse_iterator(end());
10340 }
10341
10342 /*!
10343 @copydoc basic_json::crbegin()
10344 */
rbegin() const10345 const_reverse_iterator rbegin() const noexcept
10346 {
10347 return crbegin();
10348 }
10349
10350 /*!
10351 @brief returns an iterator to the reverse-end
10352 Returns an iterator to the reverse-end; that is, one before the first
10353 element.
10354 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10355 @complexity Constant.
10356 @requirement This function helps `basic_json` satisfying the
10357 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10358 requirements:
10359 - The complexity is constant.
10360 - Has the semantics of `reverse_iterator(begin())`.
10361 @liveexample{The following code shows an example for `rend()`.,rend}
10362 @sa @ref crend() -- returns a const reverse iterator to the end
10363 @sa @ref rbegin() -- returns a reverse iterator to the beginning
10364 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
10365 @since version 1.0.0
10366 */
rend()10367 reverse_iterator rend() noexcept
10368 {
10369 return reverse_iterator(begin());
10370 }
10371
10372 /*!
10373 @copydoc basic_json::crend()
10374 */
rend() const10375 const_reverse_iterator rend() const noexcept
10376 {
10377 return crend();
10378 }
10379
10380 /*!
10381 @brief returns a const reverse iterator to the last element
10382 Returns a const iterator to the reverse-beginning; that is, the last
10383 element.
10384 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10385 @complexity Constant.
10386 @requirement This function helps `basic_json` satisfying the
10387 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10388 requirements:
10389 - The complexity is constant.
10390 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
10391 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
10392 @sa @ref rbegin() -- returns a reverse iterator to the beginning
10393 @sa @ref rend() -- returns a reverse iterator to the end
10394 @sa @ref crend() -- returns a const reverse iterator to the end
10395 @since version 1.0.0
10396 */
crbegin() const10397 const_reverse_iterator crbegin() const noexcept
10398 {
10399 return const_reverse_iterator(cend());
10400 }
10401
10402 /*!
10403 @brief returns a const reverse iterator to one before the first
10404 Returns a const reverse iterator to the reverse-end; that is, one before
10405 the first element.
10406 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
10407 @complexity Constant.
10408 @requirement This function helps `basic_json` satisfying the
10409 [ReversibleContainer](http://en.cppreference.com/w/cpp/concept/ReversibleContainer)
10410 requirements:
10411 - The complexity is constant.
10412 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
10413 @liveexample{The following code shows an example for `crend()`.,crend}
10414 @sa @ref rend() -- returns a reverse iterator to the end
10415 @sa @ref rbegin() -- returns a reverse iterator to the beginning
10416 @sa @ref crbegin() -- returns a const reverse iterator to the beginning
10417 @since version 1.0.0
10418 */
crend() const10419 const_reverse_iterator crend() const noexcept
10420 {
10421 return const_reverse_iterator(cbegin());
10422 }
10423
10424 public:
10425 /*!
10426 @brief wrapper to access iterator member functions in range-based for
10427 This function allows to access @ref iterator::key() and @ref
10428 iterator::value() during range-based for loops. In these loops, a
10429 reference to the JSON values is returned, so there is no access to the
10430 underlying iterator.
10431 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
10432 @note The name of this function is not yet final and may change in the
10433 future.
10434 */
iterator_wrapper(reference cont)10435 static iteration_proxy<iterator> iterator_wrapper(reference cont)
10436 {
10437 return iteration_proxy<iterator>(cont);
10438 }
10439
10440 /*!
10441 @copydoc iterator_wrapper(reference)
10442 */
iterator_wrapper(const_reference cont)10443 static iteration_proxy<const_iterator> iterator_wrapper(const_reference cont)
10444 {
10445 return iteration_proxy<const_iterator>(cont);
10446 }
10447
10448 /// @}
10449
10450
10451 //////////////
10452 // capacity //
10453 //////////////
10454
10455 /// @name capacity
10456 /// @{
10457
10458 /*!
10459 @brief checks whether the container is empty.
10460 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
10461 @return The return value depends on the different types and is
10462 defined as follows:
10463 Value type | return value
10464 ----------- | -------------
10465 null | `true`
10466 boolean | `false`
10467 string | `false`
10468 number | `false`
10469 object | result of function `object_t::empty()`
10470 array | result of function `array_t::empty()`
10471 @liveexample{The following code uses `empty()` to check if a JSON
10472 object contains any elements.,empty}
10473 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
10474 the Container concept; that is, their `empty()` functions have constant
10475 complexity.
10476 @iterators No changes.
10477 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10478 @note This function does not return whether a string stored as JSON value
10479 is empty - it returns whether the JSON container itself is empty which is
10480 false in the case of a string.
10481 @requirement This function helps `basic_json` satisfying the
10482 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10483 requirements:
10484 - The complexity is constant.
10485 - Has the semantics of `begin() == end()`.
10486 @sa @ref size() -- returns the number of elements
10487 @since version 1.0.0
10488 */
empty() const10489 bool empty() const noexcept
10490 {
10491 switch (m_type)
10492 {
10493 case value_t::null:
10494 {
10495 // null values are empty
10496 return true;
10497 }
10498
10499 case value_t::array:
10500 {
10501 // delegate call to array_t::empty()
10502 return m_value.array->empty();
10503 }
10504
10505 case value_t::object:
10506 {
10507 // delegate call to object_t::empty()
10508 return m_value.object->empty();
10509 }
10510
10511 default:
10512 {
10513 // all other types are nonempty
10514 return false;
10515 }
10516 }
10517 }
10518
10519 /*!
10520 @brief returns the number of elements
10521 Returns the number of elements in a JSON value.
10522 @return The return value depends on the different types and is
10523 defined as follows:
10524 Value type | return value
10525 ----------- | -------------
10526 null | `0`
10527 boolean | `1`
10528 string | `1`
10529 number | `1`
10530 object | result of function object_t::size()
10531 array | result of function array_t::size()
10532 @liveexample{The following code calls `size()` on the different value
10533 types.,size}
10534 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
10535 the Container concept; that is, their size() functions have constant
10536 complexity.
10537 @iterators No changes.
10538 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10539 @note This function does not return the length of a string stored as JSON
10540 value - it returns the number of elements in the JSON value which is 1 in
10541 the case of a string.
10542 @requirement This function helps `basic_json` satisfying the
10543 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10544 requirements:
10545 - The complexity is constant.
10546 - Has the semantics of `std::distance(begin(), end())`.
10547 @sa @ref empty() -- checks whether the container is empty
10548 @sa @ref max_size() -- returns the maximal number of elements
10549 @since version 1.0.0
10550 */
size() const10551 size_type size() const noexcept
10552 {
10553 switch (m_type)
10554 {
10555 case value_t::null:
10556 {
10557 // null values are empty
10558 return 0;
10559 }
10560
10561 case value_t::array:
10562 {
10563 // delegate call to array_t::size()
10564 return m_value.array->size();
10565 }
10566
10567 case value_t::object:
10568 {
10569 // delegate call to object_t::size()
10570 return m_value.object->size();
10571 }
10572
10573 default:
10574 {
10575 // all other types have size 1
10576 return 1;
10577 }
10578 }
10579 }
10580
10581 /*!
10582 @brief returns the maximum possible number of elements
10583 Returns the maximum number of elements a JSON value is able to hold due to
10584 system or library implementation limitations, i.e. `std::distance(begin(),
10585 end())` for the JSON value.
10586 @return The return value depends on the different types and is
10587 defined as follows:
10588 Value type | return value
10589 ----------- | -------------
10590 null | `0` (same as `size()`)
10591 boolean | `1` (same as `size()`)
10592 string | `1` (same as `size()`)
10593 number | `1` (same as `size()`)
10594 object | result of function `object_t::max_size()`
10595 array | result of function `array_t::max_size()`
10596 @liveexample{The following code calls `max_size()` on the different value
10597 types. Note the output is implementation specific.,max_size}
10598 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
10599 the Container concept; that is, their `max_size()` functions have constant
10600 complexity.
10601 @iterators No changes.
10602 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10603 @requirement This function helps `basic_json` satisfying the
10604 [Container](http://en.cppreference.com/w/cpp/concept/Container)
10605 requirements:
10606 - The complexity is constant.
10607 - Has the semantics of returning `b.size()` where `b` is the largest
10608 possible JSON value.
10609 @sa @ref size() -- returns the number of elements
10610 @since version 1.0.0
10611 */
max_size() const10612 size_type max_size() const noexcept
10613 {
10614 switch (m_type)
10615 {
10616 case value_t::array:
10617 {
10618 // delegate call to array_t::max_size()
10619 return m_value.array->max_size();
10620 }
10621
10622 case value_t::object:
10623 {
10624 // delegate call to object_t::max_size()
10625 return m_value.object->max_size();
10626 }
10627
10628 default:
10629 {
10630 // all other types have max_size() == size()
10631 return size();
10632 }
10633 }
10634 }
10635
10636 /// @}
10637
10638
10639 ///////////////
10640 // modifiers //
10641 ///////////////
10642
10643 /// @name modifiers
10644 /// @{
10645
10646 /*!
10647 @brief clears the contents
10648 Clears the content of a JSON value and resets it to the default value as
10649 if @ref basic_json(value_t) would have been called with the current value
10650 type from @ref type():
10651 Value type | initial value
10652 ----------- | -------------
10653 null | `null`
10654 boolean | `false`
10655 string | `""`
10656 number | `0`
10657 object | `{}`
10658 array | `[]`
10659 @post Has the same effect as calling
10660 @code {.cpp}
10661 *this = basic_json(type());
10662 @endcode
10663 @liveexample{The example below shows the effect of `clear()` to different
10664 JSON types.,clear}
10665 @complexity Linear in the size of the JSON value.
10666 @iterators All iterators, pointers and references related to this container
10667 are invalidated.
10668 @exceptionsafety No-throw guarantee: this function never throws exceptions.
10669 @sa @ref basic_json(value_t) -- constructor that creates an object with the
10670 same value than calling `clear()`
10671 @since version 1.0.0
10672 */
clear()10673 void clear() noexcept
10674 {
10675 switch (m_type)
10676 {
10677 case value_t::number_integer:
10678 {
10679 m_value.number_integer = 0;
10680 break;
10681 }
10682
10683 case value_t::number_unsigned:
10684 {
10685 m_value.number_unsigned = 0;
10686 break;
10687 }
10688
10689 case value_t::number_float:
10690 {
10691 m_value.number_float = 0.0;
10692 break;
10693 }
10694
10695 case value_t::boolean:
10696 {
10697 m_value.boolean = false;
10698 break;
10699 }
10700
10701 case value_t::string:
10702 {
10703 m_value.string->clear();
10704 break;
10705 }
10706
10707 case value_t::array:
10708 {
10709 m_value.array->clear();
10710 break;
10711 }
10712
10713 case value_t::object:
10714 {
10715 m_value.object->clear();
10716 break;
10717 }
10718
10719 default:
10720 break;
10721 }
10722 }
10723
10724 /*!
10725 @brief add an object to an array
10726 Appends the given element @a val to the end of the JSON value. If the
10727 function is called on a JSON null value, an empty array is created before
10728 appending @a val.
10729 @param[in] val the value to add to the JSON array
10730 @throw type_error.308 when called on a type other than JSON array or
10731 null; example: `"cannot use push_back() with number"`
10732 @complexity Amortized constant.
10733 @liveexample{The example shows how `push_back()` and `+=` can be used to
10734 add elements to a JSON array. Note how the `null` value was silently
10735 converted to a JSON array.,push_back}
10736 @since version 1.0.0
10737 */
push_back(basic_json && val)10738 void push_back(basic_json&& val)
10739 {
10740 // push_back only works for null objects or arrays
10741 if (JSON_UNLIKELY(not(is_null() or is_array())))
10742 {
10743 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
10744 }
10745
10746 // transform null object into an array
10747 if (is_null())
10748 {
10749 m_type = value_t::array;
10750 m_value = value_t::array;
10751 assert_invariant();
10752 }
10753
10754 // add element to array (move semantics)
10755 m_value.array->push_back(std::move(val));
10756 // invalidate object
10757 val.m_type = value_t::null;
10758 }
10759
10760 /*!
10761 @brief add an object to an array
10762 @copydoc push_back(basic_json&&)
10763 */
operator +=(basic_json && val)10764 reference operator+=(basic_json&& val)
10765 {
10766 push_back(std::move(val));
10767 return *this;
10768 }
10769
10770 /*!
10771 @brief add an object to an array
10772 @copydoc push_back(basic_json&&)
10773 */
push_back(const basic_json & val)10774 void push_back(const basic_json& val)
10775 {
10776 // push_back only works for null objects or arrays
10777 if (JSON_UNLIKELY(not(is_null() or is_array())))
10778 {
10779 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
10780 }
10781
10782 // transform null object into an array
10783 if (is_null())
10784 {
10785 m_type = value_t::array;
10786 m_value = value_t::array;
10787 assert_invariant();
10788 }
10789
10790 // add element to array
10791 m_value.array->push_back(val);
10792 }
10793
10794 /*!
10795 @brief add an object to an array
10796 @copydoc push_back(basic_json&&)
10797 */
operator +=(const basic_json & val)10798 reference operator+=(const basic_json& val)
10799 {
10800 push_back(val);
10801 return *this;
10802 }
10803
10804 /*!
10805 @brief add an object to an object
10806 Inserts the given element @a val to the JSON object. If the function is
10807 called on a JSON null value, an empty object is created before inserting
10808 @a val.
10809 @param[in] val the value to add to the JSON object
10810 @throw type_error.308 when called on a type other than JSON object or
10811 null; example: `"cannot use push_back() with number"`
10812 @complexity Logarithmic in the size of the container, O(log(`size()`)).
10813 @liveexample{The example shows how `push_back()` and `+=` can be used to
10814 add elements to a JSON object. Note how the `null` value was silently
10815 converted to a JSON object.,push_back__object_t__value}
10816 @since version 1.0.0
10817 */
push_back(const typename object_t::value_type & val)10818 void push_back(const typename object_t::value_type& val)
10819 {
10820 // push_back only works for null objects or objects
10821 if (JSON_UNLIKELY(not(is_null() or is_object())))
10822 {
10823 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name())));
10824 }
10825
10826 // transform null object into an object
10827 if (is_null())
10828 {
10829 m_type = value_t::object;
10830 m_value = value_t::object;
10831 assert_invariant();
10832 }
10833
10834 // add element to array
10835 m_value.object->insert(val);
10836 }
10837
10838 /*!
10839 @brief add an object to an object
10840 @copydoc push_back(const typename object_t::value_type&)
10841 */
operator +=(const typename object_t::value_type & val)10842 reference operator+=(const typename object_t::value_type& val)
10843 {
10844 push_back(val);
10845 return *this;
10846 }
10847
10848 /*!
10849 @brief add an object to an object
10850 This function allows to use `push_back` with an initializer list. In case
10851 1. the current value is an object,
10852 2. the initializer list @a init contains only two elements, and
10853 3. the first element of @a init is a string,
10854 @a init is converted into an object element and added using
10855 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
10856 is converted to a JSON value and added using @ref push_back(basic_json&&).
10857 @param[in] init an initializer list
10858 @complexity Linear in the size of the initializer list @a init.
10859 @note This function is required to resolve an ambiguous overload error,
10860 because pairs like `{"key", "value"}` can be both interpreted as
10861 `object_t::value_type` or `std::initializer_list<basic_json>`, see
10862 https://github.com/nlohmann/json/issues/235 for more information.
10863 @liveexample{The example shows how initializer lists are treated as
10864 objects when possible.,push_back__initializer_list}
10865 */
push_back(initializer_list_t init)10866 void push_back(initializer_list_t init)
10867 {
10868 if (is_object() and init.size() == 2 and (*init.begin())->is_string())
10869 {
10870 basic_json&& key = init.begin()->moved_or_copied();
10871 push_back(typename object_t::value_type(
10872 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
10873 }
10874 else
10875 {
10876 push_back(basic_json(init));
10877 }
10878 }
10879
10880 /*!
10881 @brief add an object to an object
10882 @copydoc push_back(initializer_list_t)
10883 */
operator +=(initializer_list_t init)10884 reference operator+=(initializer_list_t init)
10885 {
10886 push_back(init);
10887 return *this;
10888 }
10889
10890 /*!
10891 @brief add an object to an array
10892 Creates a JSON value from the passed parameters @a args to the end of the
10893 JSON value. If the function is called on a JSON null value, an empty array
10894 is created before appending the value created from @a args.
10895 @param[in] args arguments to forward to a constructor of @ref basic_json
10896 @tparam Args compatible types to create a @ref basic_json object
10897 @throw type_error.311 when called on a type other than JSON array or
10898 null; example: `"cannot use emplace_back() with number"`
10899 @complexity Amortized constant.
10900 @liveexample{The example shows how `push_back()` can be used to add
10901 elements to a JSON array. Note how the `null` value was silently converted
10902 to a JSON array.,emplace_back}
10903 @since version 2.0.8
10904 */
10905 template<class... Args>
emplace_back(Args &&...args)10906 void emplace_back(Args&& ... args)
10907 {
10908 // emplace_back only works for null objects or arrays
10909 if (JSON_UNLIKELY(not(is_null() or is_array())))
10910 {
10911 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name())));
10912 }
10913
10914 // transform null object into an array
10915 if (is_null())
10916 {
10917 m_type = value_t::array;
10918 m_value = value_t::array;
10919 assert_invariant();
10920 }
10921
10922 // add element to array (perfect forwarding)
10923 m_value.array->emplace_back(std::forward<Args>(args)...);
10924 }
10925
10926 /*!
10927 @brief add an object to an object if key does not exist
10928 Inserts a new element into a JSON object constructed in-place with the
10929 given @a args if there is no element with the key in the container. If the
10930 function is called on a JSON null value, an empty object is created before
10931 appending the value created from @a args.
10932 @param[in] args arguments to forward to a constructor of @ref basic_json
10933 @tparam Args compatible types to create a @ref basic_json object
10934 @return a pair consisting of an iterator to the inserted element, or the
10935 already-existing element if no insertion happened, and a bool
10936 denoting whether the insertion took place.
10937 @throw type_error.311 when called on a type other than JSON object or
10938 null; example: `"cannot use emplace() with number"`
10939 @complexity Logarithmic in the size of the container, O(log(`size()`)).
10940 @liveexample{The example shows how `emplace()` can be used to add elements
10941 to a JSON object. Note how the `null` value was silently converted to a
10942 JSON object. Further note how no value is added if there was already one
10943 value stored with the same key.,emplace}
10944 @since version 2.0.8
10945 */
10946 template<class... Args>
emplace(Args &&...args)10947 std::pair<iterator, bool> emplace(Args&& ... args)
10948 {
10949 // emplace only works for null objects or arrays
10950 if (JSON_UNLIKELY(not(is_null() or is_object())))
10951 {
10952 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name())));
10953 }
10954
10955 // transform null object into an object
10956 if (is_null())
10957 {
10958 m_type = value_t::object;
10959 m_value = value_t::object;
10960 assert_invariant();
10961 }
10962
10963 // add element to array (perfect forwarding)
10964 auto res = m_value.object->emplace(std::forward<Args>(args)...);
10965 // create result iterator and set iterator to the result of emplace
10966 auto it = begin();
10967 it.m_it.object_iterator = res.first;
10968
10969 // return pair of iterator and boolean
10970 return {it, res.second};
10971 }
10972
10973 /*!
10974 @brief inserts element
10975 Inserts element @a val before iterator @a pos.
10976 @param[in] pos iterator before which the content will be inserted; may be
10977 the end() iterator
10978 @param[in] val element to insert
10979 @return iterator pointing to the inserted @a val.
10980 @throw type_error.309 if called on JSON values other than arrays;
10981 example: `"cannot use insert() with string"`
10982 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
10983 example: `"iterator does not fit current value"`
10984 @complexity Constant plus linear in the distance between @a pos and end of
10985 the container.
10986 @liveexample{The example shows how `insert()` is used.,insert}
10987 @since version 1.0.0
10988 */
insert(const_iterator pos,const basic_json & val)10989 iterator insert(const_iterator pos, const basic_json& val)
10990 {
10991 // insert only works for arrays
10992 if (JSON_LIKELY(is_array()))
10993 {
10994 // check if iterator pos fits to this JSON value
10995 if (JSON_UNLIKELY(pos.m_object != this))
10996 {
10997 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
10998 }
10999
11000 // insert to array and return iterator
11001 iterator result(this);
11002 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, val);
11003 return result;
11004 }
11005
11006 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11007 }
11008
11009 /*!
11010 @brief inserts element
11011 @copydoc insert(const_iterator, const basic_json&)
11012 */
insert(const_iterator pos,basic_json && val)11013 iterator insert(const_iterator pos, basic_json&& val)
11014 {
11015 return insert(pos, val);
11016 }
11017
11018 /*!
11019 @brief inserts elements
11020 Inserts @a cnt copies of @a val before iterator @a pos.
11021 @param[in] pos iterator before which the content will be inserted; may be
11022 the end() iterator
11023 @param[in] cnt number of copies of @a val to insert
11024 @param[in] val element to insert
11025 @return iterator pointing to the first element inserted, or @a pos if
11026 `cnt==0`
11027 @throw type_error.309 if called on JSON values other than arrays; example:
11028 `"cannot use insert() with string"`
11029 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11030 example: `"iterator does not fit current value"`
11031 @complexity Linear in @a cnt plus linear in the distance between @a pos
11032 and end of the container.
11033 @liveexample{The example shows how `insert()` is used.,insert__count}
11034 @since version 1.0.0
11035 */
insert(const_iterator pos,size_type cnt,const basic_json & val)11036 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
11037 {
11038 // insert only works for arrays
11039 if (JSON_LIKELY(is_array()))
11040 {
11041 // check if iterator pos fits to this JSON value
11042 if (JSON_UNLIKELY(pos.m_object != this))
11043 {
11044 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11045 }
11046
11047 // insert to array and return iterator
11048 iterator result(this);
11049 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
11050 return result;
11051 }
11052
11053 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11054 }
11055
11056 /*!
11057 @brief inserts elements
11058 Inserts elements from range `[first, last)` before iterator @a pos.
11059 @param[in] pos iterator before which the content will be inserted; may be
11060 the end() iterator
11061 @param[in] first begin of the range of elements to insert
11062 @param[in] last end of the range of elements to insert
11063 @throw type_error.309 if called on JSON values other than arrays; example:
11064 `"cannot use insert() with string"`
11065 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11066 example: `"iterator does not fit current value"`
11067 @throw invalid_iterator.210 if @a first and @a last do not belong to the
11068 same JSON value; example: `"iterators do not fit"`
11069 @throw invalid_iterator.211 if @a first or @a last are iterators into
11070 container for which insert is called; example: `"passed iterators may not
11071 belong to container"`
11072 @return iterator pointing to the first element inserted, or @a pos if
11073 `first==last`
11074 @complexity Linear in `std::distance(first, last)` plus linear in the
11075 distance between @a pos and end of the container.
11076 @liveexample{The example shows how `insert()` is used.,insert__range}
11077 @since version 1.0.0
11078 */
insert(const_iterator pos,const_iterator first,const_iterator last)11079 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
11080 {
11081 // insert only works for arrays
11082 if (JSON_UNLIKELY(not is_array()))
11083 {
11084 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11085 }
11086
11087 // check if iterator pos fits to this JSON value
11088 if (JSON_UNLIKELY(pos.m_object != this))
11089 {
11090 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11091 }
11092
11093 // check if range iterators belong to the same JSON object
11094 if (JSON_UNLIKELY(first.m_object != last.m_object))
11095 {
11096 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11097 }
11098
11099 if (JSON_UNLIKELY(first.m_object == this))
11100 {
11101 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container"));
11102 }
11103
11104 // insert to array and return iterator
11105 iterator result(this);
11106 result.m_it.array_iterator = m_value.array->insert(
11107 pos.m_it.array_iterator,
11108 first.m_it.array_iterator,
11109 last.m_it.array_iterator);
11110 return result;
11111 }
11112
11113 /*!
11114 @brief inserts elements
11115 Inserts elements from initializer list @a ilist before iterator @a pos.
11116 @param[in] pos iterator before which the content will be inserted; may be
11117 the end() iterator
11118 @param[in] ilist initializer list to insert the values from
11119 @throw type_error.309 if called on JSON values other than arrays; example:
11120 `"cannot use insert() with string"`
11121 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
11122 example: `"iterator does not fit current value"`
11123 @return iterator pointing to the first element inserted, or @a pos if
11124 `ilist` is empty
11125 @complexity Linear in `ilist.size()` plus linear in the distance between
11126 @a pos and end of the container.
11127 @liveexample{The example shows how `insert()` is used.,insert__ilist}
11128 @since version 1.0.0
11129 */
insert(const_iterator pos,initializer_list_t ilist)11130 iterator insert(const_iterator pos, initializer_list_t ilist)
11131 {
11132 // insert only works for arrays
11133 if (JSON_UNLIKELY(not is_array()))
11134 {
11135 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11136 }
11137
11138 // check if iterator pos fits to this JSON value
11139 if (JSON_UNLIKELY(pos.m_object != this))
11140 {
11141 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value"));
11142 }
11143
11144 // insert to array and return iterator
11145 iterator result(this);
11146 result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, ilist.begin(), ilist.end());
11147 return result;
11148 }
11149
11150 /*!
11151 @brief inserts elements
11152 Inserts elements from range `[first, last)`.
11153 @param[in] first begin of the range of elements to insert
11154 @param[in] last end of the range of elements to insert
11155 @throw type_error.309 if called on JSON values other than objects; example:
11156 `"cannot use insert() with string"`
11157 @throw invalid_iterator.202 if iterator @a first or @a last does does not
11158 point to an object; example: `"iterators first and last must point to
11159 objects"`
11160 @throw invalid_iterator.210 if @a first and @a last do not belong to the
11161 same JSON value; example: `"iterators do not fit"`
11162 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
11163 of elements to insert.
11164 @liveexample{The example shows how `insert()` is used.,insert__range_object}
11165 @since version 3.0.0
11166 */
insert(const_iterator first,const_iterator last)11167 void insert(const_iterator first, const_iterator last)
11168 {
11169 // insert only works for objects
11170 if (JSON_UNLIKELY(not is_object()))
11171 {
11172 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name())));
11173 }
11174
11175 // check if range iterators belong to the same JSON object
11176 if (JSON_UNLIKELY(first.m_object != last.m_object))
11177 {
11178 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11179 }
11180
11181 // passed iterators must belong to objects
11182 if (JSON_UNLIKELY(not first.m_object->is_object()))
11183 {
11184 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
11185 }
11186
11187 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
11188 }
11189
11190 /*!
11191 @brief updates a JSON object from another object, overwriting existing keys
11192 Inserts all values from JSON object @a j and overwrites existing keys.
11193 @param[in] j JSON object to read values from
11194 @throw type_error.312 if called on JSON values other than objects; example:
11195 `"cannot use update() with string"`
11196 @complexity O(N*log(size() + N)), where N is the number of elements to
11197 insert.
11198 @liveexample{The example shows how `update()` is used.,update}
11199 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
11200 @since version 3.0.0
11201 */
update(const_reference j)11202 void update(const_reference j)
11203 {
11204 // implicitly convert null value to an empty object
11205 if (is_null())
11206 {
11207 m_type = value_t::object;
11208 m_value.object = create<object_t>();
11209 assert_invariant();
11210 }
11211
11212 if (JSON_UNLIKELY(not is_object()))
11213 {
11214 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
11215 }
11216 if (JSON_UNLIKELY(not j.is_object()))
11217 {
11218 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
11219 }
11220
11221 for (auto it = j.begin(); it != j.end(); ++it)
11222 {
11223 m_value.object->operator[](it.key()) = it.value();
11224 }
11225 }
11226
11227 /*!
11228 @brief updates a JSON object from another object, overwriting existing keys
11229 Inserts all values from from range `[first, last)` and overwrites existing
11230 keys.
11231 @param[in] first begin of the range of elements to insert
11232 @param[in] last end of the range of elements to insert
11233 @throw type_error.312 if called on JSON values other than objects; example:
11234 `"cannot use update() with string"`
11235 @throw invalid_iterator.202 if iterator @a first or @a last does does not
11236 point to an object; example: `"iterators first and last must point to
11237 objects"`
11238 @throw invalid_iterator.210 if @a first and @a last do not belong to the
11239 same JSON value; example: `"iterators do not fit"`
11240 @complexity O(N*log(size() + N)), where N is the number of elements to
11241 insert.
11242 @liveexample{The example shows how `update()` is used__range.,update}
11243 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
11244 @since version 3.0.0
11245 */
update(const_iterator first,const_iterator last)11246 void update(const_iterator first, const_iterator last)
11247 {
11248 // implicitly convert null value to an empty object
11249 if (is_null())
11250 {
11251 m_type = value_t::object;
11252 m_value.object = create<object_t>();
11253 assert_invariant();
11254 }
11255
11256 if (JSON_UNLIKELY(not is_object()))
11257 {
11258 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name())));
11259 }
11260
11261 // check if range iterators belong to the same JSON object
11262 if (JSON_UNLIKELY(first.m_object != last.m_object))
11263 {
11264 JSON_THROW(invalid_iterator::create(210, "iterators do not fit"));
11265 }
11266
11267 // passed iterators must belong to objects
11268 if (JSON_UNLIKELY(not first.m_object->is_object()
11269 or not first.m_object->is_object()))
11270 {
11271 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects"));
11272 }
11273
11274 for (auto it = first; it != last; ++it)
11275 {
11276 m_value.object->operator[](it.key()) = it.value();
11277 }
11278 }
11279
11280 /*!
11281 @brief exchanges the values
11282 Exchanges the contents of the JSON value with those of @a other. Does not
11283 invoke any move, copy, or swap operations on individual elements. All
11284 iterators and references remain valid. The past-the-end iterator is
11285 invalidated.
11286 @param[in,out] other JSON value to exchange the contents with
11287 @complexity Constant.
11288 @liveexample{The example below shows how JSON values can be swapped with
11289 `swap()`.,swap__reference}
11290 @since version 1.0.0
11291 */
swap(reference other)11292 void swap(reference other) noexcept (
11293 std::is_nothrow_move_constructible<value_t>::value and
11294 std::is_nothrow_move_assignable<value_t>::value and
11295 std::is_nothrow_move_constructible<json_value>::value and
11296 std::is_nothrow_move_assignable<json_value>::value
11297 )
11298 {
11299 std::swap(m_type, other.m_type);
11300 std::swap(m_value, other.m_value);
11301 assert_invariant();
11302 }
11303
11304 /*!
11305 @brief exchanges the values
11306 Exchanges the contents of a JSON array with those of @a other. Does not
11307 invoke any move, copy, or swap operations on individual elements. All
11308 iterators and references remain valid. The past-the-end iterator is
11309 invalidated.
11310 @param[in,out] other array to exchange the contents with
11311 @throw type_error.310 when JSON value is not an array; example: `"cannot
11312 use swap() with string"`
11313 @complexity Constant.
11314 @liveexample{The example below shows how arrays can be swapped with
11315 `swap()`.,swap__array_t}
11316 @since version 1.0.0
11317 */
swap(array_t & other)11318 void swap(array_t& other)
11319 {
11320 // swap only works for arrays
11321 if (JSON_LIKELY(is_array()))
11322 {
11323 std::swap(*(m_value.array), other);
11324 }
11325 else
11326 {
11327 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
11328 }
11329 }
11330
11331 /*!
11332 @brief exchanges the values
11333 Exchanges the contents of a JSON object with those of @a other. Does not
11334 invoke any move, copy, or swap operations on individual elements. All
11335 iterators and references remain valid. The past-the-end iterator is
11336 invalidated.
11337 @param[in,out] other object to exchange the contents with
11338 @throw type_error.310 when JSON value is not an object; example:
11339 `"cannot use swap() with string"`
11340 @complexity Constant.
11341 @liveexample{The example below shows how objects can be swapped with
11342 `swap()`.,swap__object_t}
11343 @since version 1.0.0
11344 */
swap(object_t & other)11345 void swap(object_t& other)
11346 {
11347 // swap only works for objects
11348 if (JSON_LIKELY(is_object()))
11349 {
11350 std::swap(*(m_value.object), other);
11351 }
11352 else
11353 {
11354 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
11355 }
11356 }
11357
11358 /*!
11359 @brief exchanges the values
11360 Exchanges the contents of a JSON string with those of @a other. Does not
11361 invoke any move, copy, or swap operations on individual elements. All
11362 iterators and references remain valid. The past-the-end iterator is
11363 invalidated.
11364 @param[in,out] other string to exchange the contents with
11365 @throw type_error.310 when JSON value is not a string; example: `"cannot
11366 use swap() with boolean"`
11367 @complexity Constant.
11368 @liveexample{The example below shows how strings can be swapped with
11369 `swap()`.,swap__string_t}
11370 @since version 1.0.0
11371 */
swap(string_t & other)11372 void swap(string_t& other)
11373 {
11374 // swap only works for strings
11375 if (JSON_LIKELY(is_string()))
11376 {
11377 std::swap(*(m_value.string), other);
11378 }
11379 else
11380 {
11381 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name())));
11382 }
11383 }
11384
11385 /// @}
11386
11387 public:
11388 //////////////////////////////////////////
11389 // lexicographical comparison operators //
11390 //////////////////////////////////////////
11391
11392 /// @name lexicographical comparison operators
11393 /// @{
11394
11395 /*!
11396 @brief comparison: equal
11397 Compares two JSON values for equality according to the following rules:
11398 - Two JSON values are equal if (1) they are from the same type and (2)
11399 their stored values are the same according to their respective
11400 `operator==`.
11401 - Integer and floating-point numbers are automatically converted before
11402 comparison. Note than two NaN values are always treated as unequal.
11403 - Two JSON null values are equal.
11404 @note Floating-point inside JSON values numbers are compared with
11405 `json::number_float_t::operator==` which is `double::operator==` by
11406 default. To compare floating-point while respecting an epsilon, an alternative
11407 [comparison function](https://github.com/mariokonrad/marnav/blob/master/src/marnav/math/floatingpoint.hpp#L34-#L39)
11408 could be used, for instance
11409 @code {.cpp}
11410 template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
11411 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
11412 {
11413 return std::abs(a - b) <= epsilon;
11414 }
11415 @endcode
11416 @note NaN values never compare equal to themselves or to other NaN values.
11417 @param[in] lhs first JSON value to consider
11418 @param[in] rhs second JSON value to consider
11419 @return whether the values @a lhs and @a rhs are equal
11420 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11421 @complexity Linear.
11422 @liveexample{The example demonstrates comparing several JSON
11423 types.,operator__equal}
11424 @since version 1.0.0
11425 */
operator ==(const_reference lhs,const_reference rhs)11426 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
11427 {
11428 const auto lhs_type = lhs.type();
11429 const auto rhs_type = rhs.type();
11430
11431 if (lhs_type == rhs_type)
11432 {
11433 switch (lhs_type)
11434 {
11435 case value_t::array:
11436 return (*lhs.m_value.array == *rhs.m_value.array);
11437
11438 case value_t::object:
11439 return (*lhs.m_value.object == *rhs.m_value.object);
11440
11441 case value_t::null:
11442 return true;
11443
11444 case value_t::string:
11445 return (*lhs.m_value.string == *rhs.m_value.string);
11446
11447 case value_t::boolean:
11448 return (lhs.m_value.boolean == rhs.m_value.boolean);
11449
11450 case value_t::number_integer:
11451 return (lhs.m_value.number_integer == rhs.m_value.number_integer);
11452
11453 case value_t::number_unsigned:
11454 return (lhs.m_value.number_unsigned == rhs.m_value.number_unsigned);
11455
11456 case value_t::number_float:
11457 return (lhs.m_value.number_float == rhs.m_value.number_float);
11458
11459 default:
11460 return false;
11461 }
11462 }
11463 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
11464 {
11465 return (static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float);
11466 }
11467 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
11468 {
11469 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer));
11470 }
11471 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
11472 {
11473 return (static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float);
11474 }
11475 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
11476 {
11477 return (lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned));
11478 }
11479 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
11480 {
11481 return (static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer);
11482 }
11483 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
11484 {
11485 return (lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned));
11486 }
11487
11488 return false;
11489 }
11490
11491 /*!
11492 @brief comparison: equal
11493 @copydoc operator==(const_reference, const_reference)
11494 */
11495 template<typename ScalarType, typename std::enable_if<
11496 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,const ScalarType rhs)11497 friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
11498 {
11499 return (lhs == basic_json(rhs));
11500 }
11501
11502 /*!
11503 @brief comparison: equal
11504 @copydoc operator==(const_reference, const_reference)
11505 */
11506 template<typename ScalarType, typename std::enable_if<
11507 std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const ScalarType lhs,const_reference rhs)11508 friend bool operator==(const ScalarType lhs, const_reference rhs) noexcept
11509 {
11510 return (basic_json(lhs) == rhs);
11511 }
11512
11513 /*!
11514 @brief comparison: not equal
11515 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
11516 @param[in] lhs first JSON value to consider
11517 @param[in] rhs second JSON value to consider
11518 @return whether the values @a lhs and @a rhs are not equal
11519 @complexity Linear.
11520 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11521 @liveexample{The example demonstrates comparing several JSON
11522 types.,operator__notequal}
11523 @since version 1.0.0
11524 */
operator !=(const_reference lhs,const_reference rhs)11525 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
11526 {
11527 return not (lhs == rhs);
11528 }
11529
11530 /*!
11531 @brief comparison: not equal
11532 @copydoc operator!=(const_reference, const_reference)
11533 */
11534 template<typename ScalarType, typename std::enable_if<
11535 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,const ScalarType rhs)11536 friend bool operator!=(const_reference lhs, const ScalarType rhs) noexcept
11537 {
11538 return (lhs != basic_json(rhs));
11539 }
11540
11541 /*!
11542 @brief comparison: not equal
11543 @copydoc operator!=(const_reference, const_reference)
11544 */
11545 template<typename ScalarType, typename std::enable_if<
11546 std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const ScalarType lhs,const_reference rhs)11547 friend bool operator!=(const ScalarType lhs, const_reference rhs) noexcept
11548 {
11549 return (basic_json(lhs) != rhs);
11550 }
11551
11552 /*!
11553 @brief comparison: less than
11554 Compares whether one JSON value @a lhs is less than another JSON value @a
11555 rhs according to the following rules:
11556 - If @a lhs and @a rhs have the same type, the values are compared using
11557 the default `<` operator.
11558 - Integer and floating-point numbers are automatically converted before
11559 comparison
11560 - In case @a lhs and @a rhs have different types, the values are ignored
11561 and the order of the types is considered, see
11562 @ref operator<(const value_t, const value_t).
11563 @param[in] lhs first JSON value to consider
11564 @param[in] rhs second JSON value to consider
11565 @return whether @a lhs is less than @a rhs
11566 @complexity Linear.
11567 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11568 @liveexample{The example demonstrates comparing several JSON
11569 types.,operator__less}
11570 @since version 1.0.0
11571 */
operator <(const_reference lhs,const_reference rhs)11572 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
11573 {
11574 const auto lhs_type = lhs.type();
11575 const auto rhs_type = rhs.type();
11576
11577 if (lhs_type == rhs_type)
11578 {
11579 switch (lhs_type)
11580 {
11581 case value_t::array:
11582 return (*lhs.m_value.array) < (*rhs.m_value.array);
11583
11584 case value_t::object:
11585 return *lhs.m_value.object < *rhs.m_value.object;
11586
11587 case value_t::null:
11588 return false;
11589
11590 case value_t::string:
11591 return *lhs.m_value.string < *rhs.m_value.string;
11592
11593 case value_t::boolean:
11594 return lhs.m_value.boolean < rhs.m_value.boolean;
11595
11596 case value_t::number_integer:
11597 return lhs.m_value.number_integer < rhs.m_value.number_integer;
11598
11599 case value_t::number_unsigned:
11600 return lhs.m_value.number_unsigned < rhs.m_value.number_unsigned;
11601
11602 case value_t::number_float:
11603 return lhs.m_value.number_float < rhs.m_value.number_float;
11604
11605 default:
11606 return false;
11607 }
11608 }
11609 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_float)
11610 {
11611 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
11612 }
11613 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_integer)
11614 {
11615 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
11616 }
11617 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_float)
11618 {
11619 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
11620 }
11621 else if (lhs_type == value_t::number_float and rhs_type == value_t::number_unsigned)
11622 {
11623 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
11624 }
11625 else if (lhs_type == value_t::number_integer and rhs_type == value_t::number_unsigned)
11626 {
11627 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
11628 }
11629 else if (lhs_type == value_t::number_unsigned and rhs_type == value_t::number_integer)
11630 {
11631 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
11632 }
11633
11634 // We only reach this line if we cannot compare values. In that case,
11635 // we compare types. Note we have to call the operator explicitly,
11636 // because MSVC has problems otherwise.
11637 return operator<(lhs_type, rhs_type);
11638 }
11639
11640 /*!
11641 @brief comparison: less than
11642 @copydoc operator<(const_reference, const_reference)
11643 */
11644 template<typename ScalarType, typename std::enable_if<
11645 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,const ScalarType rhs)11646 friend bool operator<(const_reference lhs, const ScalarType rhs) noexcept
11647 {
11648 return (lhs < basic_json(rhs));
11649 }
11650
11651 /*!
11652 @brief comparison: less than
11653 @copydoc operator<(const_reference, const_reference)
11654 */
11655 template<typename ScalarType, typename std::enable_if<
11656 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const ScalarType lhs,const_reference rhs)11657 friend bool operator<(const ScalarType lhs, const_reference rhs) noexcept
11658 {
11659 return (basic_json(lhs) < rhs);
11660 }
11661
11662 /*!
11663 @brief comparison: less than or equal
11664 Compares whether one JSON value @a lhs is less than or equal to another
11665 JSON value by calculating `not (rhs < lhs)`.
11666 @param[in] lhs first JSON value to consider
11667 @param[in] rhs second JSON value to consider
11668 @return whether @a lhs is less than or equal to @a rhs
11669 @complexity Linear.
11670 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11671 @liveexample{The example demonstrates comparing several JSON
11672 types.,operator__greater}
11673 @since version 1.0.0
11674 */
operator <=(const_reference lhs,const_reference rhs)11675 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
11676 {
11677 return not (rhs < lhs);
11678 }
11679
11680 /*!
11681 @brief comparison: less than or equal
11682 @copydoc operator<=(const_reference, const_reference)
11683 */
11684 template<typename ScalarType, typename std::enable_if<
11685 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,const ScalarType rhs)11686 friend bool operator<=(const_reference lhs, const ScalarType rhs) noexcept
11687 {
11688 return (lhs <= basic_json(rhs));
11689 }
11690
11691 /*!
11692 @brief comparison: less than or equal
11693 @copydoc operator<=(const_reference, const_reference)
11694 */
11695 template<typename ScalarType, typename std::enable_if<
11696 std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const ScalarType lhs,const_reference rhs)11697 friend bool operator<=(const ScalarType lhs, const_reference rhs) noexcept
11698 {
11699 return (basic_json(lhs) <= rhs);
11700 }
11701
11702 /*!
11703 @brief comparison: greater than
11704 Compares whether one JSON value @a lhs is greater than another
11705 JSON value by calculating `not (lhs <= rhs)`.
11706 @param[in] lhs first JSON value to consider
11707 @param[in] rhs second JSON value to consider
11708 @return whether @a lhs is greater than to @a rhs
11709 @complexity Linear.
11710 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11711 @liveexample{The example demonstrates comparing several JSON
11712 types.,operator__lessequal}
11713 @since version 1.0.0
11714 */
operator >(const_reference lhs,const_reference rhs)11715 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
11716 {
11717 return not (lhs <= rhs);
11718 }
11719
11720 /*!
11721 @brief comparison: greater than
11722 @copydoc operator>(const_reference, const_reference)
11723 */
11724 template<typename ScalarType, typename std::enable_if<
11725 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,const ScalarType rhs)11726 friend bool operator>(const_reference lhs, const ScalarType rhs) noexcept
11727 {
11728 return (lhs > basic_json(rhs));
11729 }
11730
11731 /*!
11732 @brief comparison: greater than
11733 @copydoc operator>(const_reference, const_reference)
11734 */
11735 template<typename ScalarType, typename std::enable_if<
11736 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const ScalarType lhs,const_reference rhs)11737 friend bool operator>(const ScalarType lhs, const_reference rhs) noexcept
11738 {
11739 return (basic_json(lhs) > rhs);
11740 }
11741
11742 /*!
11743 @brief comparison: greater than or equal
11744 Compares whether one JSON value @a lhs is greater than or equal to another
11745 JSON value by calculating `not (lhs < rhs)`.
11746 @param[in] lhs first JSON value to consider
11747 @param[in] rhs second JSON value to consider
11748 @return whether @a lhs is greater than or equal to @a rhs
11749 @complexity Linear.
11750 @exceptionsafety No-throw guarantee: this function never throws exceptions.
11751 @liveexample{The example demonstrates comparing several JSON
11752 types.,operator__greaterequal}
11753 @since version 1.0.0
11754 */
operator >=(const_reference lhs,const_reference rhs)11755 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
11756 {
11757 return not (lhs < rhs);
11758 }
11759
11760 /*!
11761 @brief comparison: greater than or equal
11762 @copydoc operator>=(const_reference, const_reference)
11763 */
11764 template<typename ScalarType, typename std::enable_if<
11765 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,const ScalarType rhs)11766 friend bool operator>=(const_reference lhs, const ScalarType rhs) noexcept
11767 {
11768 return (lhs >= basic_json(rhs));
11769 }
11770
11771 /*!
11772 @brief comparison: greater than or equal
11773 @copydoc operator>=(const_reference, const_reference)
11774 */
11775 template<typename ScalarType, typename std::enable_if<
11776 std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const ScalarType lhs,const_reference rhs)11777 friend bool operator>=(const ScalarType lhs, const_reference rhs) noexcept
11778 {
11779 return (basic_json(lhs) >= rhs);
11780 }
11781
11782 /// @}
11783
11784 ///////////////////
11785 // serialization //
11786 ///////////////////
11787
11788 /// @name serialization
11789 /// @{
11790
11791 /*!
11792 @brief serialize to stream
11793 Serialize the given JSON value @a j to the output stream @a o. The JSON
11794 value will be serialized using the @ref dump member function.
11795 - The indentation of the output can be controlled with the member variable
11796 `width` of the output stream @a o. For instance, using the manipulator
11797 `std::setw(4)` on @a o sets the indentation level to `4` and the
11798 serialization result is the same as calling `dump(4)`.
11799 - The indentation characrer can be controlled with the member variable
11800 `fill` of the output stream @a o. For instance, the manipulator
11801 `std::setfill('\\t')` sets indentation to use a tab character rather than
11802 the default space character.
11803 @param[in,out] o stream to serialize to
11804 @param[in] j JSON value to serialize
11805 @return the stream @a o
11806 @complexity Linear.
11807 @liveexample{The example below shows the serialization with different
11808 parameters to `width` to adjust the indentation level.,operator_serialize}
11809 @since version 1.0.0; indentaction character added in version 3.0.0
11810 */
operator <<(std::ostream & o,const basic_json & j)11811 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
11812 {
11813 // read width member and use it as indentation parameter if nonzero
11814 const bool pretty_print = (o.width() > 0);
11815 const auto indentation = (pretty_print ? o.width() : 0);
11816
11817 // reset width to 0 for subsequent calls to this stream
11818 o.width(0);
11819
11820 // do the actual serialization
11821 serializer s(detail::output_adapter<char>(o), o.fill());
11822 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
11823 return o;
11824 }
11825
11826 /*!
11827 @brief serialize to stream
11828 @deprecated This stream operator is deprecated and will be removed in a
11829 future version of the library. Please use
11830 @ref operator<<(std::ostream&, const basic_json&)
11831 instead; that is, replace calls like `j >> o;` with `o << j;`.
11832 @since version 1.0.0; deprecated since version 3.0.0
11833 */
11834 JSON_DEPRECATED
operator >>(const basic_json & j,std::ostream & o)11835 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
11836 {
11837 return o << j;
11838 }
11839
11840 /// @}
11841
11842
11843 /////////////////////
11844 // deserialization //
11845 /////////////////////
11846
11847 /// @name deserialization
11848 /// @{
11849
11850 /*!
11851 @brief deserialize from a compatible input
11852 This function reads from a compatible input. Examples are:
11853 - an array of 1-byte values
11854 - strings with character/literal type with size of 1 byte
11855 - input streams
11856 - container with contiguous storage of 1-byte values. Compatible container
11857 types include `std::vector`, `std::string`, `std::array`,
11858 `std::valarray`, and `std::initializer_list`. Furthermore, C-style
11859 arrays can be used with `std::begin()`/`std::end()`. User-defined
11860 containers can be used as long as they implement random-access iterators
11861 and a contiguous storage.
11862 @pre Each element of the container has a size of 1 byte. Violating this
11863 precondition yields undefined behavior. **This precondition is enforced
11864 with a static assertion.**
11865 @pre The container storage is contiguous. Violating this precondition
11866 yields undefined behavior. **This precondition is enforced with an
11867 assertion.**
11868 @pre Each element of the container has a size of 1 byte. Violating this
11869 precondition yields undefined behavior. **This precondition is enforced
11870 with a static assertion.**
11871 @warning There is no way to enforce all preconditions at compile-time. If
11872 the function is called with a noncompliant container and with
11873 assertions switched off, the behavior is undefined and will most
11874 likely yield segmentation violation.
11875 @param[in] i input to read from
11876 @param[in] cb a parser callback function of type @ref parser_callback_t
11877 which is used to control the deserialization by filtering unwanted values
11878 (optional)
11879 @return result of the deserialization
11880 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
11881 of input; expected string literal""`
11882 @throw parse_error.102 if to_unicode fails or surrogate error
11883 @throw parse_error.103 if to_unicode fails
11884 @complexity Linear in the length of the input. The parser is a predictive
11885 LL(1) parser. The complexity can be higher if the parser callback function
11886 @a cb has a super-linear complexity.
11887 @note A UTF-8 byte order mark is silently ignored.
11888 @liveexample{The example below demonstrates the `parse()` function reading
11889 from an array.,parse__array__parser_callback_t}
11890 @liveexample{The example below demonstrates the `parse()` function with
11891 and without callback function.,parse__string__parser_callback_t}
11892 @liveexample{The example below demonstrates the `parse()` function with
11893 and without callback function.,parse__istream__parser_callback_t}
11894 @liveexample{The example below demonstrates the `parse()` function reading
11895 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
11896 @since version 2.0.3 (contiguous containers)
11897 */
parse(detail::input_adapter i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)11898 static basic_json parse(detail::input_adapter i,
11899 const parser_callback_t cb = nullptr,
11900 const bool allow_exceptions = true)
11901 {
11902 basic_json result;
11903 parser(i, cb, allow_exceptions).parse(true, result);
11904 return result;
11905 }
11906
11907 /*!
11908 @copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
11909 */
parse(detail::input_adapter & i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true)11910 static basic_json parse(detail::input_adapter& i,
11911 const parser_callback_t cb = nullptr,
11912 const bool allow_exceptions = true)
11913 {
11914 basic_json result;
11915 parser(i, cb, allow_exceptions).parse(true, result);
11916 return result;
11917 }
11918
accept(detail::input_adapter i)11919 static bool accept(detail::input_adapter i)
11920 {
11921 return parser(i).accept(true);
11922 }
11923
accept(detail::input_adapter & i)11924 static bool accept(detail::input_adapter& i)
11925 {
11926 return parser(i).accept(true);
11927 }
11928
11929 /*!
11930 @brief deserialize from an iterator range with contiguous storage
11931 This function reads from an iterator range of a container with contiguous
11932 storage of 1-byte values. Compatible container types include
11933 `std::vector`, `std::string`, `std::array`, `std::valarray`, and
11934 `std::initializer_list`. Furthermore, C-style arrays can be used with
11935 `std::begin()`/`std::end()`. User-defined containers can be used as long
11936 as they implement random-access iterators and a contiguous storage.
11937 @pre The iterator range is contiguous. Violating this precondition yields
11938 undefined behavior. **This precondition is enforced with an assertion.**
11939 @pre Each element in the range has a size of 1 byte. Violating this
11940 precondition yields undefined behavior. **This precondition is enforced
11941 with a static assertion.**
11942 @warning There is no way to enforce all preconditions at compile-time. If
11943 the function is called with noncompliant iterators and with
11944 assertions switched off, the behavior is undefined and will most
11945 likely yield segmentation violation.
11946 @tparam IteratorType iterator of container with contiguous storage
11947 @param[in] first begin of the range to parse (included)
11948 @param[in] last end of the range to parse (excluded)
11949 @param[in] cb a parser callback function of type @ref parser_callback_t
11950 which is used to control the deserialization by filtering unwanted values
11951 (optional)
11952 @param[in] allow_exceptions whether to throw exceptions in case of a
11953 parse error (optional, true by default)
11954 @return result of the deserialization
11955 @throw parse_error.101 in case of an unexpected token
11956 @throw parse_error.102 if to_unicode fails or surrogate error
11957 @throw parse_error.103 if to_unicode fails
11958 @complexity Linear in the length of the input. The parser is a predictive
11959 LL(1) parser. The complexity can be higher if the parser callback function
11960 @a cb has a super-linear complexity.
11961 @note A UTF-8 byte order mark is silently ignored.
11962 @liveexample{The example below demonstrates the `parse()` function reading
11963 from an iterator range.,parse__iteratortype__parser_callback_t}
11964 @since version 2.0.3
11965 */
11966 template<class IteratorType, typename std::enable_if<
11967 std::is_base_of<
11968 std::random_access_iterator_tag,
11969 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)11970 static basic_json parse(IteratorType first, IteratorType last,
11971 const parser_callback_t cb = nullptr,
11972 const bool allow_exceptions = true)
11973 {
11974 basic_json result;
11975 parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
11976 return result;
11977 }
11978
11979 template<class IteratorType, typename std::enable_if<
11980 std::is_base_of<
11981 std::random_access_iterator_tag,
11982 typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
accept(IteratorType first,IteratorType last)11983 static bool accept(IteratorType first, IteratorType last)
11984 {
11985 return parser(detail::input_adapter(first, last)).accept(true);
11986 }
11987
11988 /*!
11989 @brief deserialize from stream
11990 @deprecated This stream operator is deprecated and will be removed in a
11991 future version of the library. Please use
11992 @ref operator>>(std::istream&, basic_json&)
11993 instead; that is, replace calls like `j << i;` with `i >> j;`.
11994 @since version 1.0.0; deprecated since version 3.0.0
11995 */
11996 JSON_DEPRECATED
operator <<(basic_json & j,std::istream & i)11997 friend std::istream& operator<<(basic_json& j, std::istream& i)
11998 {
11999 return operator>>(i, j);
12000 }
12001
12002 /*!
12003 @brief deserialize from stream
12004 Deserializes an input stream to a JSON value.
12005 @param[in,out] i input stream to read a serialized JSON value from
12006 @param[in,out] j JSON value to write the deserialized input to
12007 @throw parse_error.101 in case of an unexpected token
12008 @throw parse_error.102 if to_unicode fails or surrogate error
12009 @throw parse_error.103 if to_unicode fails
12010 @complexity Linear in the length of the input. The parser is a predictive
12011 LL(1) parser.
12012 @note A UTF-8 byte order mark is silently ignored.
12013 @liveexample{The example below shows how a JSON value is constructed by
12014 reading a serialization from a stream.,operator_deserialize}
12015 @sa parse(std::istream&, const parser_callback_t) for a variant with a
12016 parser callback function to filter values while parsing
12017 @since version 1.0.0
12018 */
operator >>(std::istream & i,basic_json & j)12019 friend std::istream& operator>>(std::istream& i, basic_json& j)
12020 {
12021 parser(detail::input_adapter(i)).parse(false, j);
12022 return i;
12023 }
12024
12025 /// @}
12026
12027 ///////////////////////////
12028 // convenience functions //
12029 ///////////////////////////
12030
12031 /*!
12032 @brief return the type as string
12033 Returns the type name as string to be used in error messages - usually to
12034 indicate that a function was called on a wrong JSON type.
12035 @return a string representation of a the @a m_type member:
12036 Value type | return value
12037 ----------- | -------------
12038 null | `"null"`
12039 boolean | `"boolean"`
12040 string | `"string"`
12041 number | `"number"` (for all number types)
12042 object | `"object"`
12043 array | `"array"`
12044 discarded | `"discarded"`
12045 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12046 @complexity Constant.
12047 @liveexample{The following code exemplifies `type_name()` for all JSON
12048 types.,type_name}
12049 @sa @ref type() -- return the type of the JSON value
12050 @sa @ref operator value_t() -- return the type of the JSON value (implicit)
12051 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
12052 since 3.0.0
12053 */
type_name() const12054 const char* type_name() const noexcept
12055 {
12056 {
12057 switch (m_type)
12058 {
12059 case value_t::null:
12060 return "null";
12061 case value_t::object:
12062 return "object";
12063 case value_t::array:
12064 return "array";
12065 case value_t::string:
12066 return "string";
12067 case value_t::boolean:
12068 return "boolean";
12069 case value_t::discarded:
12070 return "discarded";
12071 default:
12072 return "number";
12073 }
12074 }
12075 }
12076
12077
12078 private:
12079 //////////////////////
12080 // member variables //
12081 //////////////////////
12082
12083 /// the type of the current element
12084 value_t m_type = value_t::null;
12085
12086 /// the value of the current element
12087 json_value m_value = {};
12088
12089 //////////////////////////////////////////
12090 // binary serialization/deserialization //
12091 //////////////////////////////////////////
12092
12093 /// @name binary serialization/deserialization support
12094 /// @{
12095
12096 public:
12097 /*!
12098 @brief create a CBOR serialization of a given JSON value
12099 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
12100 Binary Object Representation) serialization format. CBOR is a binary
12101 serialization format which aims to be more compact than JSON itself, yet
12102 more efficient to parse.
12103 The library uses the following mapping from JSON values types to
12104 CBOR types according to the CBOR specification (RFC 7049):
12105 JSON value type | value/range | CBOR type | first byte
12106 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
12107 null | `null` | Null | 0xf6
12108 boolean | `true` | True | 0xf5
12109 boolean | `false` | False | 0xf4
12110 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3b
12111 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3a
12112 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
12113 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
12114 number_integer | -24..-1 | Negative integer | 0x20..0x37
12115 number_integer | 0..23 | Integer | 0x00..0x17
12116 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
12117 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
12118 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1a
12119 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1b
12120 number_unsigned | 0..23 | Integer | 0x00..0x17
12121 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
12122 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
12123 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1a
12124 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1b
12125 number_float | *any value* | Double-Precision Float | 0xfb
12126 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
12127 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
12128 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
12129 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7a
12130 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7b
12131 array | *size*: 0..23 | array | 0x80..0x97
12132 array | *size*: 23..255 | array (1 byte follow) | 0x98
12133 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
12134 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9a
12135 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9b
12136 object | *size*: 0..23 | map | 0xa0..0xb7
12137 object | *size*: 23..255 | map (1 byte follow) | 0xb8
12138 object | *size*: 256..65535 | map (2 bytes follow) | 0xb9
12139 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xba
12140 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xbb
12141 @note The mapping is **complete** in the sense that any JSON value type
12142 can be converted to a CBOR value.
12143 @note If NaN or Infinity are stored inside a JSON number, they are
12144 serialized properly. This behavior differs from the @ref dump()
12145 function which serializes NaN or Infinity to `null`.
12146 @note The following CBOR types are not used in the conversion:
12147 - byte strings (0x40..0x5f)
12148 - UTF-8 strings terminated by "break" (0x7f)
12149 - arrays terminated by "break" (0x9f)
12150 - maps terminated by "break" (0xbf)
12151 - date/time (0xc0..0xc1)
12152 - bignum (0xc2..0xc3)
12153 - decimal fraction (0xc4)
12154 - bigfloat (0xc5)
12155 - tagged items (0xc6..0xd4, 0xd8..0xdb)
12156 - expected conversions (0xd5..0xd7)
12157 - simple values (0xe0..0xf3, 0xf8)
12158 - undefined (0xf7)
12159 - half and single-precision floats (0xf9-0xfa)
12160 - break (0xff)
12161 @param[in] j JSON value to serialize
12162 @return MessagePack serialization as byte vector
12163 @complexity Linear in the size of the JSON value @a j.
12164 @liveexample{The example shows the serialization of a JSON value to a byte
12165 vector in CBOR format.,to_cbor}
12166 @sa http://cbor.io
12167 @sa @ref from_cbor(const std::vector<uint8_t>&, const size_t) for the
12168 analogous deserialization
12169 @sa @ref to_msgpack(const basic_json&) for the related MessagePack format
12170 @since version 2.0.9
12171 */
to_cbor(const basic_json & j)12172 static std::vector<uint8_t> to_cbor(const basic_json& j)
12173 {
12174 std::vector<uint8_t> result;
12175 to_cbor(j, result);
12176 return result;
12177 }
12178
to_cbor(const basic_json & j,detail::output_adapter<uint8_t> o)12179 static void to_cbor(const basic_json& j, detail::output_adapter<uint8_t> o)
12180 {
12181 binary_writer<uint8_t>(o).write_cbor(j);
12182 }
12183
to_cbor(const basic_json & j,detail::output_adapter<char> o)12184 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
12185 {
12186 binary_writer<char>(o).write_cbor(j);
12187 }
12188
12189 /*!
12190 @brief create a MessagePack serialization of a given JSON value
12191 Serializes a given JSON value @a j to a byte vector using the MessagePack
12192 serialization format. MessagePack is a binary serialization format which
12193 aims to be more compact than JSON itself, yet more efficient to parse.
12194 The library uses the following mapping from JSON values types to
12195 MessagePack types according to the MessagePack specification:
12196 JSON value type | value/range | MessagePack type | first byte
12197 --------------- | --------------------------------- | ---------------- | ----------
12198 null | `null` | nil | 0xc0
12199 boolean | `true` | true | 0xc3
12200 boolean | `false` | false | 0xc2
12201 number_integer | -9223372036854775808..-2147483649 | int64 | 0xd3
12202 number_integer | -2147483648..-32769 | int32 | 0xd2
12203 number_integer | -32768..-129 | int16 | 0xd1
12204 number_integer | -128..-33 | int8 | 0xd0
12205 number_integer | -32..-1 | negative fixint | 0xe0..0xff
12206 number_integer | 0..127 | positive fixint | 0x00..0x7f
12207 number_integer | 128..255 | uint 8 | 0xcc
12208 number_integer | 256..65535 | uint 16 | 0xcd
12209 number_integer | 65536..4294967295 | uint 32 | 0xce
12210 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xcf
12211 number_unsigned | 0..127 | positive fixint | 0x00..0x7f
12212 number_unsigned | 128..255 | uint 8 | 0xcc
12213 number_unsigned | 256..65535 | uint 16 | 0xcd
12214 number_unsigned | 65536..4294967295 | uint 32 | 0xce
12215 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xcf
12216 number_float | *any value* | float 64 | 0xcb
12217 string | *length*: 0..31 | fixstr | 0xa0..0xbf
12218 string | *length*: 32..255 | str 8 | 0xd9
12219 string | *length*: 256..65535 | str 16 | 0xda
12220 string | *length*: 65536..4294967295 | str 32 | 0xdb
12221 array | *size*: 0..15 | fixarray | 0x90..0x9f
12222 array | *size*: 16..65535 | array 16 | 0xdc
12223 array | *size*: 65536..4294967295 | array 32 | 0xdd
12224 object | *size*: 0..15 | fix map | 0x80..0x8f
12225 object | *size*: 16..65535 | map 16 | 0xde
12226 object | *size*: 65536..4294967295 | map 32 | 0xdf
12227 @note The mapping is **complete** in the sense that any JSON value type
12228 can be converted to a MessagePack value.
12229 @note The following values can **not** be converted to a MessagePack value:
12230 - strings with more than 4294967295 bytes
12231 - arrays with more than 4294967295 elements
12232 - objects with more than 4294967295 elements
12233 @note The following MessagePack types are not used in the conversion:
12234 - bin 8 - bin 32 (0xc4..0xc6)
12235 - ext 8 - ext 32 (0xc7..0xc9)
12236 - float 32 (0xca)
12237 - fixext 1 - fixext 16 (0xd4..0xd8)
12238 @note Any MessagePack output created @ref to_msgpack can be successfully
12239 parsed by @ref from_msgpack.
12240 @note If NaN or Infinity are stored inside a JSON number, they are
12241 serialized properly. This behavior differs from the @ref dump()
12242 function which serializes NaN or Infinity to `null`.
12243 @param[in] j JSON value to serialize
12244 @return MessagePack serialization as byte vector
12245 @complexity Linear in the size of the JSON value @a j.
12246 @liveexample{The example shows the serialization of a JSON value to a byte
12247 vector in MessagePack format.,to_msgpack}
12248 @sa http://msgpack.org
12249 @sa @ref from_msgpack(const std::vector<uint8_t>&, const size_t) for the
12250 analogous deserialization
12251 @sa @ref to_cbor(const basic_json& for the related CBOR format
12252 @since version 2.0.9
12253 */
to_msgpack(const basic_json & j)12254 static std::vector<uint8_t> to_msgpack(const basic_json& j)
12255 {
12256 std::vector<uint8_t> result;
12257 to_msgpack(j, result);
12258 return result;
12259 }
12260
to_msgpack(const basic_json & j,detail::output_adapter<uint8_t> o)12261 static void to_msgpack(const basic_json& j, detail::output_adapter<uint8_t> o)
12262 {
12263 binary_writer<uint8_t>(o).write_msgpack(j);
12264 }
12265
to_msgpack(const basic_json & j,detail::output_adapter<char> o)12266 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
12267 {
12268 binary_writer<char>(o).write_msgpack(j);
12269 }
12270
12271 /*!
12272 @brief create a JSON value from an input in CBOR format
12273 Deserializes a given input @a i to a JSON value using the CBOR (Concise
12274 Binary Object Representation) serialization format.
12275 The library maps CBOR types to JSON value types as follows:
12276 CBOR type | JSON value type | first byte
12277 ---------------------- | --------------- | ----------
12278 Integer | number_unsigned | 0x00..0x17
12279 Unsigned integer | number_unsigned | 0x18
12280 Unsigned integer | number_unsigned | 0x19
12281 Unsigned integer | number_unsigned | 0x1a
12282 Unsigned integer | number_unsigned | 0x1b
12283 Negative integer | number_integer | 0x20..0x37
12284 Negative integer | number_integer | 0x38
12285 Negative integer | number_integer | 0x39
12286 Negative integer | number_integer | 0x3a
12287 Negative integer | number_integer | 0x3b
12288 Negative integer | number_integer | 0x40..0x57
12289 UTF-8 string | string | 0x60..0x77
12290 UTF-8 string | string | 0x78
12291 UTF-8 string | string | 0x79
12292 UTF-8 string | string | 0x7a
12293 UTF-8 string | string | 0x7b
12294 UTF-8 string | string | 0x7f
12295 array | array | 0x80..0x97
12296 array | array | 0x98
12297 array | array | 0x99
12298 array | array | 0x9a
12299 array | array | 0x9b
12300 array | array | 0x9f
12301 map | object | 0xa0..0xb7
12302 map | object | 0xb8
12303 map | object | 0xb9
12304 map | object | 0xba
12305 map | object | 0xbb
12306 map | object | 0xbf
12307 False | `false` | 0xf4
12308 True | `true` | 0xf5
12309 Nill | `null` | 0xf6
12310 Half-Precision Float | number_float | 0xf9
12311 Single-Precision Float | number_float | 0xfa
12312 Double-Precision Float | number_float | 0xfb
12313 @warning The mapping is **incomplete** in the sense that not all CBOR
12314 types can be converted to a JSON value. The following CBOR types
12315 are not supported and will yield parse errors (parse_error.112):
12316 - byte strings (0x40..0x5f)
12317 - date/time (0xc0..0xc1)
12318 - bignum (0xc2..0xc3)
12319 - decimal fraction (0xc4)
12320 - bigfloat (0xc5)
12321 - tagged items (0xc6..0xd4, 0xd8..0xdb)
12322 - expected conversions (0xd5..0xd7)
12323 - simple values (0xe0..0xf3, 0xf8)
12324 - undefined (0xf7)
12325 @warning CBOR allows map keys of any type, whereas JSON only allows
12326 strings as keys in object values. Therefore, CBOR maps with keys
12327 other than UTF-8 strings are rejected (parse_error.113).
12328 @note Any CBOR output created @ref to_cbor can be successfully parsed by
12329 @ref from_cbor.
12330 @param[in] i an input in CBOR format convertible to an input adapter
12331 @param[in] strict whether to expect the input to be consumed until EOF
12332 (true by default)
12333 @return deserialized JSON value
12334 @throw parse_error.110 if the given input ends prematurely or the end of
12335 file was not reached when @a strict was set to true
12336 @throw parse_error.112 if unsupported features from CBOR were
12337 used in the given input @a v or if the input is not valid CBOR
12338 @throw parse_error.113 if a string was expected as map key, but not found
12339 @complexity Linear in the size of the input @a i.
12340 @liveexample{The example shows the deserialization of a byte vector in CBOR
12341 format to a JSON value.,from_cbor}
12342 @sa http://cbor.io
12343 @sa @ref to_cbor(const basic_json&) for the analogous serialization
12344 @sa @ref from_msgpack(detail::input_adapter, const bool) for the
12345 related MessagePack format
12346 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
12347 consume input adapters, removed start_index parameter, and added
12348 @a strict parameter since 3.0.0
12349 */
from_cbor(detail::input_adapter i,const bool strict=true)12350 static basic_json from_cbor(detail::input_adapter i,
12351 const bool strict = true)
12352 {
12353 return binary_reader(i).parse_cbor(strict);
12354 }
12355
12356 /*!
12357 @copydoc from_cbor(detail::input_adapter, const bool)
12358 */
12359 template<typename A1, typename A2,
12360 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)12361 static basic_json from_cbor(A1 && a1, A2 && a2, const bool strict = true)
12362 {
12363 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_cbor(strict);
12364 }
12365
12366 /*!
12367 @brief create a JSON value from an input in MessagePack format
12368 Deserializes a given input @a i to a JSON value using the MessagePack
12369 serialization format.
12370 The library maps MessagePack types to JSON value types as follows:
12371 MessagePack type | JSON value type | first byte
12372 ---------------- | --------------- | ----------
12373 positive fixint | number_unsigned | 0x00..0x7f
12374 fixmap | object | 0x80..0x8f
12375 fixarray | array | 0x90..0x9f
12376 fixstr | string | 0xa0..0xbf
12377 nil | `null` | 0xc0
12378 false | `false` | 0xc2
12379 true | `true` | 0xc3
12380 float 32 | number_float | 0xca
12381 float 64 | number_float | 0xcb
12382 uint 8 | number_unsigned | 0xcc
12383 uint 16 | number_unsigned | 0xcd
12384 uint 32 | number_unsigned | 0xce
12385 uint 64 | number_unsigned | 0xcf
12386 int 8 | number_integer | 0xd0
12387 int 16 | number_integer | 0xd1
12388 int 32 | number_integer | 0xd2
12389 int 64 | number_integer | 0xd3
12390 str 8 | string | 0xd9
12391 str 16 | string | 0xda
12392 str 32 | string | 0xdb
12393 array 16 | array | 0xdc
12394 array 32 | array | 0xdd
12395 map 16 | object | 0xde
12396 map 32 | object | 0xdf
12397 negative fixint | number_integer | 0xe0-0xff
12398 @warning The mapping is **incomplete** in the sense that not all
12399 MessagePack types can be converted to a JSON value. The following
12400 MessagePack types are not supported and will yield parse errors:
12401 - bin 8 - bin 32 (0xc4..0xc6)
12402 - ext 8 - ext 32 (0xc7..0xc9)
12403 - fixext 1 - fixext 16 (0xd4..0xd8)
12404 @note Any MessagePack output created @ref to_msgpack can be successfully
12405 parsed by @ref from_msgpack.
12406 @param[in] i an input in MessagePack format convertible to an input
12407 adapter
12408 @param[in] strict whether to expect the input to be consumed until EOF
12409 (true by default)
12410 @throw parse_error.110 if the given input ends prematurely or the end of
12411 file was not reached when @a strict was set to true
12412 @throw parse_error.112 if unsupported features from MessagePack were
12413 used in the given input @a i or if the input is not valid MessagePack
12414 @throw parse_error.113 if a string was expected as map key, but not found
12415 @complexity Linear in the size of the input @a i.
12416 @liveexample{The example shows the deserialization of a byte vector in
12417 MessagePack format to a JSON value.,from_msgpack}
12418 @sa http://msgpack.org
12419 @sa @ref to_msgpack(const basic_json&) for the analogous serialization
12420 @sa @ref from_cbor(detail::input_adapter, const bool) for the related CBOR
12421 format
12422 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
12423 consume input adapters, removed start_index parameter, and added
12424 @a strict parameter since 3.0.0
12425 */
from_msgpack(detail::input_adapter i,const bool strict=true)12426 static basic_json from_msgpack(detail::input_adapter i,
12427 const bool strict = true)
12428 {
12429 return binary_reader(i).parse_msgpack(strict);
12430 }
12431
12432 /*!
12433 @copydoc from_msgpack(detail::input_adapter, const bool)
12434 */
12435 template<typename A1, typename A2,
12436 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)12437 static basic_json from_msgpack(A1 && a1, A2 && a2, const bool strict = true)
12438 {
12439 return binary_reader(detail::input_adapter(std::forward<A1>(a1), std::forward<A2>(a2))).parse_msgpack(strict);
12440 }
12441
12442 /// @}
12443
12444 //////////////////////////
12445 // JSON Pointer support //
12446 //////////////////////////
12447
12448 /// @name JSON Pointer functions
12449 /// @{
12450
12451 /*!
12452 @brief access specified element via JSON Pointer
12453 Uses a JSON pointer to retrieve a reference to the respective JSON value.
12454 No bound checking is performed. Similar to @ref operator[](const typename
12455 object_t::key_type&), `null` values are created in arrays and objects if
12456 necessary.
12457 In particular:
12458 - If the JSON pointer points to an object key that does not exist, it
12459 is created an filled with a `null` value before a reference to it
12460 is returned.
12461 - If the JSON pointer points to an array index that does not exist, it
12462 is created an filled with a `null` value before a reference to it
12463 is returned. All indices between the current maximum and the given
12464 index are also filled with `null`.
12465 - The special value `-` is treated as a synonym for the index past the
12466 end.
12467 @param[in] ptr a JSON pointer
12468 @return reference to the element pointed to by @a ptr
12469 @complexity Constant.
12470 @throw parse_error.106 if an array index begins with '0'
12471 @throw parse_error.109 if an array index was not a number
12472 @throw out_of_range.404 if the JSON pointer can not be resolved
12473 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
12474 @since version 2.0.0
12475 */
operator [](const json_pointer & ptr)12476 reference operator[](const json_pointer& ptr)
12477 {
12478 return ptr.get_unchecked(this);
12479 }
12480
12481 /*!
12482 @brief access specified element via JSON Pointer
12483 Uses a JSON pointer to retrieve a reference to the respective JSON value.
12484 No bound checking is performed. The function does not change the JSON
12485 value; no `null` values are created. In particular, the the special value
12486 `-` yields an exception.
12487 @param[in] ptr JSON pointer to the desired element
12488 @return const reference to the element pointed to by @a ptr
12489 @complexity Constant.
12490 @throw parse_error.106 if an array index begins with '0'
12491 @throw parse_error.109 if an array index was not a number
12492 @throw out_of_range.402 if the array index '-' is used
12493 @throw out_of_range.404 if the JSON pointer can not be resolved
12494 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
12495 @since version 2.0.0
12496 */
operator [](const json_pointer & ptr) const12497 const_reference operator[](const json_pointer& ptr) const
12498 {
12499 return ptr.get_unchecked(this);
12500 }
12501
12502 /*!
12503 @brief access specified element via JSON Pointer
12504 Returns a reference to the element at with specified JSON pointer @a ptr,
12505 with bounds checking.
12506 @param[in] ptr JSON pointer to the desired element
12507 @return reference to the element pointed to by @a ptr
12508 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
12509 begins with '0'. See example below.
12510 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
12511 is not a number. See example below.
12512 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
12513 is out of range. See example below.
12514 @throw out_of_range.402 if the array index '-' is used in the passed JSON
12515 pointer @a ptr. As `at` provides checked access (and no elements are
12516 implicitly inserted), the index '-' is always invalid. See example below.
12517 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
12518 See example below.
12519 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12520 changes in the JSON value.
12521 @complexity Constant.
12522 @since version 2.0.0
12523 @liveexample{The behavior is shown in the example.,at_json_pointer}
12524 */
at(const json_pointer & ptr)12525 reference at(const json_pointer& ptr)
12526 {
12527 return ptr.get_checked(this);
12528 }
12529
12530 /*!
12531 @brief access specified element via JSON Pointer
12532 Returns a const reference to the element at with specified JSON pointer @a
12533 ptr, with bounds checking.
12534 @param[in] ptr JSON pointer to the desired element
12535 @return reference to the element pointed to by @a ptr
12536 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
12537 begins with '0'. See example below.
12538 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
12539 is not a number. See example below.
12540 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
12541 is out of range. See example below.
12542 @throw out_of_range.402 if the array index '-' is used in the passed JSON
12543 pointer @a ptr. As `at` provides checked access (and no elements are
12544 implicitly inserted), the index '-' is always invalid. See example below.
12545 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
12546 See example below.
12547 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
12548 changes in the JSON value.
12549 @complexity Constant.
12550 @since version 2.0.0
12551 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
12552 */
at(const json_pointer & ptr) const12553 const_reference at(const json_pointer& ptr) const
12554 {
12555 return ptr.get_checked(this);
12556 }
12557
12558 /*!
12559 @brief return flattened JSON value
12560 The function creates a JSON object whose keys are JSON pointers (see [RFC
12561 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
12562 primitive. The original JSON value can be restored using the @ref
12563 unflatten() function.
12564 @return an object that maps JSON pointers to primitive values
12565 @note Empty objects and arrays are flattened to `null` and will not be
12566 reconstructed correctly by the @ref unflatten() function.
12567 @complexity Linear in the size the JSON value.
12568 @liveexample{The following code shows how a JSON object is flattened to an
12569 object whose keys consist of JSON pointers.,flatten}
12570 @sa @ref unflatten() for the reverse function
12571 @since version 2.0.0
12572 */
flatten() const12573 basic_json flatten() const
12574 {
12575 basic_json result(value_t::object);
12576 json_pointer::flatten("", *this, result);
12577 return result;
12578 }
12579
12580 /*!
12581 @brief unflatten a previously flattened JSON value
12582 The function restores the arbitrary nesting of a JSON value that has been
12583 flattened before using the @ref flatten() function. The JSON value must
12584 meet certain constraints:
12585 1. The value must be an object.
12586 2. The keys must be JSON pointers (see
12587 [RFC 6901](https://tools.ietf.org/html/rfc6901))
12588 3. The mapped values must be primitive JSON types.
12589 @return the original JSON from a flattened version
12590 @note Empty objects and arrays are flattened by @ref flatten() to `null`
12591 values and can not unflattened to their original type. Apart from
12592 this example, for a JSON value `j`, the following is always true:
12593 `j == j.flatten().unflatten()`.
12594 @complexity Linear in the size the JSON value.
12595 @throw type_error.314 if value is not an object
12596 @throw type_error.315 if object values are not primitive
12597 @liveexample{The following code shows how a flattened JSON object is
12598 unflattened into the original nested JSON object.,unflatten}
12599 @sa @ref flatten() for the reverse function
12600 @since version 2.0.0
12601 */
unflatten() const12602 basic_json unflatten() const
12603 {
12604 return json_pointer::unflatten(*this);
12605 }
12606
12607 /// @}
12608
12609 //////////////////////////
12610 // JSON Patch functions //
12611 //////////////////////////
12612
12613 /// @name JSON Patch functions
12614 /// @{
12615
12616 /*!
12617 @brief applies a JSON patch
12618 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
12619 expressing a sequence of operations to apply to a JSON) document. With
12620 this function, a JSON Patch is applied to the current JSON value by
12621 executing all operations from the patch.
12622 @param[in] json_patch JSON patch document
12623 @return patched document
12624 @note The application of a patch is atomic: Either all operations succeed
12625 and the patched document is returned or an exception is thrown. In
12626 any case, the original value is not changed: the patch is applied
12627 to a copy of the value.
12628 @throw parse_error.104 if the JSON patch does not consist of an array of
12629 objects
12630 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
12631 attributes are missing); example: `"operation add must have member path"`
12632 @throw out_of_range.401 if an array index is out of range.
12633 @throw out_of_range.403 if a JSON pointer inside the patch could not be
12634 resolved successfully in the current JSON value; example: `"key baz not
12635 found"`
12636 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
12637 "move")
12638 @throw other_error.501 if "test" operation was unsuccessful
12639 @complexity Linear in the size of the JSON value and the length of the
12640 JSON patch. As usually only a fraction of the JSON value is affected by
12641 the patch, the complexity can usually be neglected.
12642 @liveexample{The following code shows how a JSON patch is applied to a
12643 value.,patch}
12644 @sa @ref diff -- create a JSON patch by comparing two JSON values
12645 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
12646 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
12647 @since version 2.0.0
12648 */
patch(const basic_json & json_patch) const12649 basic_json patch(const basic_json& json_patch) const
12650 {
12651 // make a working copy to apply the patch to
12652 basic_json result = *this;
12653
12654 // the valid JSON Patch operations
12655 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
12656
12657 const auto get_op = [](const std::string & op)
12658 {
12659 if (op == "add")
12660 {
12661 return patch_operations::add;
12662 }
12663 if (op == "remove")
12664 {
12665 return patch_operations::remove;
12666 }
12667 if (op == "replace")
12668 {
12669 return patch_operations::replace;
12670 }
12671 if (op == "move")
12672 {
12673 return patch_operations::move;
12674 }
12675 if (op == "copy")
12676 {
12677 return patch_operations::copy;
12678 }
12679 if (op == "test")
12680 {
12681 return patch_operations::test;
12682 }
12683
12684 return patch_operations::invalid;
12685 };
12686
12687 // wrapper for "add" operation; add value at ptr
12688 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
12689 {
12690 // adding to the root of the target document means replacing it
12691 if (ptr.is_root())
12692 {
12693 result = val;
12694 }
12695 else
12696 {
12697 // make sure the top element of the pointer exists
12698 json_pointer top_pointer = ptr.top();
12699 if (top_pointer != ptr)
12700 {
12701 result.at(top_pointer);
12702 }
12703
12704 // get reference to parent of JSON pointer ptr
12705 const auto last_path = ptr.pop_back();
12706 basic_json& parent = result[ptr];
12707
12708 switch (parent.m_type)
12709 {
12710 case value_t::null:
12711 case value_t::object:
12712 {
12713 // use operator[] to add value
12714 parent[last_path] = val;
12715 break;
12716 }
12717
12718 case value_t::array:
12719 {
12720 if (last_path == "-")
12721 {
12722 // special case: append to back
12723 parent.push_back(val);
12724 }
12725 else
12726 {
12727 const auto idx = std::stoi(last_path);
12728 if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
12729 {
12730 // avoid undefined behavior
12731 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range"));
12732 }
12733 else
12734 {
12735 // default case: insert add offset
12736 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
12737 }
12738 }
12739 break;
12740 }
12741
12742 default:
12743 {
12744 // if there exists a parent it cannot be primitive
12745 assert(false); // LCOV_EXCL_LINE
12746 }
12747 }
12748 }
12749 };
12750
12751 // wrapper for "remove" operation; remove value at ptr
12752 const auto operation_remove = [&result](json_pointer & ptr)
12753 {
12754 // get reference to parent of JSON pointer ptr
12755 const auto last_path = ptr.pop_back();
12756 basic_json& parent = result.at(ptr);
12757
12758 // remove child
12759 if (parent.is_object())
12760 {
12761 // perform range check
12762 auto it = parent.find(last_path);
12763 if (JSON_LIKELY(it != parent.end()))
12764 {
12765 parent.erase(it);
12766 }
12767 else
12768 {
12769 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found"));
12770 }
12771 }
12772 else if (parent.is_array())
12773 {
12774 // note erase performs range check
12775 parent.erase(static_cast<size_type>(std::stoi(last_path)));
12776 }
12777 };
12778
12779 // type check: top level value must be an array
12780 if (JSON_UNLIKELY(not json_patch.is_array()))
12781 {
12782 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
12783 }
12784
12785 // iterate and apply the operations
12786 for (const auto& val : json_patch)
12787 {
12788 // wrapper to get a value for an operation
12789 const auto get_value = [&val](const std::string & op,
12790 const std::string & member,
12791 bool string_type) -> basic_json&
12792 {
12793 // find value
12794 auto it = val.m_value.object->find(member);
12795
12796 // context-sensitive error message
12797 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
12798
12799 // check if desired value is present
12800 if (JSON_UNLIKELY(it == val.m_value.object->end()))
12801 {
12802 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'"));
12803 }
12804
12805 // check if result is of type string
12806 if (JSON_UNLIKELY(string_type and not it->second.is_string()))
12807 {
12808 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'"));
12809 }
12810
12811 // no error: return value
12812 return it->second;
12813 };
12814
12815 // type check: every element of the array must be an object
12816 if (JSON_UNLIKELY(not val.is_object()))
12817 {
12818 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects"));
12819 }
12820
12821 // collect mandatory members
12822 const std::string op = get_value("op", "op", true);
12823 const std::string path = get_value(op, "path", true);
12824 json_pointer ptr(path);
12825
12826 switch (get_op(op))
12827 {
12828 case patch_operations::add:
12829 {
12830 operation_add(ptr, get_value("add", "value", false));
12831 break;
12832 }
12833
12834 case patch_operations::remove:
12835 {
12836 operation_remove(ptr);
12837 break;
12838 }
12839
12840 case patch_operations::replace:
12841 {
12842 // the "path" location must exist - use at()
12843 result.at(ptr) = get_value("replace", "value", false);
12844 break;
12845 }
12846
12847 case patch_operations::move:
12848 {
12849 const std::string from_path = get_value("move", "from", true);
12850 json_pointer from_ptr(from_path);
12851
12852 // the "from" location must exist - use at()
12853 basic_json v = result.at(from_ptr);
12854
12855 // The move operation is functionally identical to a
12856 // "remove" operation on the "from" location, followed
12857 // immediately by an "add" operation at the target
12858 // location with the value that was just removed.
12859 operation_remove(from_ptr);
12860 operation_add(ptr, v);
12861 break;
12862 }
12863
12864 case patch_operations::copy:
12865 {
12866 const std::string from_path = get_value("copy", "from", true);
12867 const json_pointer from_ptr(from_path);
12868
12869 // the "from" location must exist - use at()
12870 result[ptr] = result.at(from_ptr);
12871 break;
12872 }
12873
12874 case patch_operations::test:
12875 {
12876 bool success = false;
12877 JSON_TRY
12878 {
12879 // check if "value" matches the one at "path"
12880 // the "path" location must exist - use at()
12881 success = (result.at(ptr) == get_value("test", "value", false));
12882 }
12883 JSON_CATCH (out_of_range&)
12884 {
12885 // ignore out of range errors: success remains false
12886 }
12887
12888 // throw an exception if test fails
12889 if (JSON_UNLIKELY(not success))
12890 {
12891 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump()));
12892 }
12893
12894 break;
12895 }
12896
12897 case patch_operations::invalid:
12898 {
12899 // op must be "add", "remove", "replace", "move", "copy", or
12900 // "test"
12901 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid"));
12902 }
12903 }
12904 }
12905
12906 return result;
12907 }
12908
12909 /*!
12910 @brief creates a diff as a JSON patch
12911 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
12912 be changed into the value @a target by calling @ref patch function.
12913 @invariant For two JSON values @a source and @a target, the following code
12914 yields always `true`:
12915 @code {.cpp}
12916 source.patch(diff(source, target)) == target;
12917 @endcode
12918 @note Currently, only `remove`, `add`, and `replace` operations are
12919 generated.
12920 @param[in] source JSON value to compare from
12921 @param[in] target JSON value to compare against
12922 @param[in] path helper value to create JSON pointers
12923 @return a JSON patch to convert the @a source to @a target
12924 @complexity Linear in the lengths of @a source and @a target.
12925 @liveexample{The following code shows how a JSON patch is created as a
12926 diff for two JSON values.,diff}
12927 @sa @ref patch -- apply a JSON patch
12928 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
12929 @since version 2.0.0
12930 */
diff(const basic_json & source,const basic_json & target,const std::string & path="")12931 static basic_json diff(const basic_json& source, const basic_json& target,
12932 const std::string& path = "")
12933 {
12934 // the patch
12935 basic_json result(value_t::array);
12936
12937 // if the values are the same, return empty patch
12938 if (source == target)
12939 {
12940 return result;
12941 }
12942
12943 if (source.type() != target.type())
12944 {
12945 // different types: replace value
12946 result.push_back(
12947 {
12948 {"op", "replace"}, {"path", path}, {"value", target}
12949 });
12950 }
12951 else
12952 {
12953 switch (source.type())
12954 {
12955 case value_t::array:
12956 {
12957 // first pass: traverse common elements
12958 std::size_t i = 0;
12959 while (i < source.size() and i < target.size())
12960 {
12961 // recursive call to compare array values at index i
12962 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
12963 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
12964 ++i;
12965 }
12966
12967 // i now reached the end of at least one array
12968 // in a second pass, traverse the remaining elements
12969
12970 // remove my remaining elements
12971 const auto end_index = static_cast<difference_type>(result.size());
12972 while (i < source.size())
12973 {
12974 // add operations in reverse order to avoid invalid
12975 // indices
12976 result.insert(result.begin() + end_index, object(
12977 {
12978 {"op", "remove"},
12979 {"path", path + "/" + std::to_string(i)}
12980 }));
12981 ++i;
12982 }
12983
12984 // add other remaining elements
12985 while (i < target.size())
12986 {
12987 result.push_back(
12988 {
12989 {"op", "add"},
12990 {"path", path + "/" + std::to_string(i)},
12991 {"value", target[i]}
12992 });
12993 ++i;
12994 }
12995
12996 break;
12997 }
12998
12999 case value_t::object:
13000 {
13001 // first pass: traverse this object's elements
13002 for (auto it = source.begin(); it != source.end(); ++it)
13003 {
13004 // escape the key name to be used in a JSON patch
13005 const auto key = json_pointer::escape(it.key());
13006
13007 if (target.find(it.key()) != target.end())
13008 {
13009 // recursive call to compare object values at key it
13010 auto temp_diff = diff(it.value(), target[it.key()], path + "/" + key);
13011 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
13012 }
13013 else
13014 {
13015 // found a key that is not in o -> remove it
13016 result.push_back(object(
13017 {
13018 {"op", "remove"}, {"path", path + "/" + key}
13019 }));
13020 }
13021 }
13022
13023 // second pass: traverse other object's elements
13024 for (auto it = target.begin(); it != target.end(); ++it)
13025 {
13026 if (source.find(it.key()) == source.end())
13027 {
13028 // found a key that is not in this -> add it
13029 const auto key = json_pointer::escape(it.key());
13030 result.push_back(
13031 {
13032 {"op", "add"}, {"path", path + "/" + key},
13033 {"value", it.value()}
13034 });
13035 }
13036 }
13037
13038 break;
13039 }
13040
13041 default:
13042 {
13043 // both primitive type: replace value
13044 result.push_back(
13045 {
13046 {"op", "replace"}, {"path", path}, {"value", target}
13047 });
13048 break;
13049 }
13050 }
13051 }
13052
13053 return result;
13054 }
13055
13056 /// @}
13057 };
13058
13059 /////////////
13060 // presets //
13061 /////////////
13062
13063 /*!
13064 @brief default JSON class
13065 This type is the default specialization of the @ref basic_json class which
13066 uses the standard template types.
13067 @since version 1.0.0
13068 */
13069 using json = basic_json<>;
13070
13071 //////////////////
13072 // json_pointer //
13073 //////////////////
13074
13075 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13076 NLOHMANN_BASIC_JSON_TPL&
get_and_create(NLOHMANN_BASIC_JSON_TPL & j) const13077 json_pointer::get_and_create(NLOHMANN_BASIC_JSON_TPL& j) const
13078 {
13079 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13080 auto result = &j;
13081
13082 // in case no reference tokens exist, return a reference to the JSON value
13083 // j which will be overwritten by a primitive value
13084 for (const auto& reference_token : reference_tokens)
13085 {
13086 switch (result->m_type)
13087 {
13088 case detail::value_t::null:
13089 {
13090 if (reference_token == "0")
13091 {
13092 // start a new array if reference token is 0
13093 result = &result->operator[](0);
13094 }
13095 else
13096 {
13097 // start a new object otherwise
13098 result = &result->operator[](reference_token);
13099 }
13100 break;
13101 }
13102
13103 case detail::value_t::object:
13104 {
13105 // create an entry in the object
13106 result = &result->operator[](reference_token);
13107 break;
13108 }
13109
13110 case detail::value_t::array:
13111 {
13112 // create an entry in the array
13113 JSON_TRY
13114 {
13115 result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
13116 }
13117 JSON_CATCH(std::invalid_argument&)
13118 {
13119 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13120 }
13121 break;
13122 }
13123
13124 /*
13125 The following code is only reached if there exists a reference
13126 token _and_ the current value is primitive. In this case, we have
13127 an error situation, because primitive values may only occur as
13128 single value; that is, with an empty list of reference tokens.
13129 */
13130 default:
13131 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten"));
13132 }
13133 }
13134
13135 return *result;
13136 }
13137
13138 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13139 NLOHMANN_BASIC_JSON_TPL&
get_unchecked(NLOHMANN_BASIC_JSON_TPL * ptr) const13140 json_pointer::get_unchecked(NLOHMANN_BASIC_JSON_TPL* ptr) const
13141 {
13142 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13143 for (const auto& reference_token : reference_tokens)
13144 {
13145 // convert null values to arrays or objects before continuing
13146 if (ptr->m_type == detail::value_t::null)
13147 {
13148 // check if reference token is a number
13149 const bool nums =
13150 std::all_of(reference_token.begin(), reference_token.end(),
13151 [](const char x)
13152 {
13153 return (x >= '0' and x <= '9');
13154 });
13155
13156 // change value to array for numbers or "-" or to object otherwise
13157 *ptr = (nums or reference_token == "-")
13158 ? detail::value_t::array
13159 : detail::value_t::object;
13160 }
13161
13162 switch (ptr->m_type)
13163 {
13164 case detail::value_t::object:
13165 {
13166 // use unchecked object access
13167 ptr = &ptr->operator[](reference_token);
13168 break;
13169 }
13170
13171 case detail::value_t::array:
13172 {
13173 // error condition (cf. RFC 6901, Sect. 4)
13174 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13175 {
13176 JSON_THROW(detail::parse_error::create(106, 0,
13177 "array index '" + reference_token +
13178 "' must not begin with '0'"));
13179 }
13180
13181 if (reference_token == "-")
13182 {
13183 // explicitly treat "-" as index beyond the end
13184 ptr = &ptr->operator[](ptr->m_value.array->size());
13185 }
13186 else
13187 {
13188 // convert array index to number; unchecked access
13189 JSON_TRY
13190 {
13191 ptr = &ptr->operator[](
13192 static_cast<size_type>(std::stoi(reference_token)));
13193 }
13194 JSON_CATCH(std::invalid_argument&)
13195 {
13196 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13197 }
13198 }
13199 break;
13200 }
13201
13202 default:
13203 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13204 }
13205 }
13206
13207 return *ptr;
13208 }
13209
13210 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13211 NLOHMANN_BASIC_JSON_TPL&
get_checked(NLOHMANN_BASIC_JSON_TPL * ptr) const13212 json_pointer::get_checked(NLOHMANN_BASIC_JSON_TPL* ptr) const
13213 {
13214 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13215 for (const auto& reference_token : reference_tokens)
13216 {
13217 switch (ptr->m_type)
13218 {
13219 case detail::value_t::object:
13220 {
13221 // note: at performs range check
13222 ptr = &ptr->at(reference_token);
13223 break;
13224 }
13225
13226 case detail::value_t::array:
13227 {
13228 if (JSON_UNLIKELY(reference_token == "-"))
13229 {
13230 // "-" always fails the range check
13231 JSON_THROW(detail::out_of_range::create(402,
13232 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13233 ") is out of range"));
13234 }
13235
13236 // error condition (cf. RFC 6901, Sect. 4)
13237 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13238 {
13239 JSON_THROW(detail::parse_error::create(106, 0,
13240 "array index '" + reference_token +
13241 "' must not begin with '0'"));
13242 }
13243
13244 // note: at performs range check
13245 JSON_TRY
13246 {
13247 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
13248 }
13249 JSON_CATCH(std::invalid_argument&)
13250 {
13251 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13252 }
13253 break;
13254 }
13255
13256 default:
13257 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13258 }
13259 }
13260
13261 return *ptr;
13262 }
13263
13264 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13265 const NLOHMANN_BASIC_JSON_TPL&
get_unchecked(const NLOHMANN_BASIC_JSON_TPL * ptr) const13266 json_pointer::get_unchecked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
13267 {
13268 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13269 for (const auto& reference_token : reference_tokens)
13270 {
13271 switch (ptr->m_type)
13272 {
13273 case detail::value_t::object:
13274 {
13275 // use unchecked object access
13276 ptr = &ptr->operator[](reference_token);
13277 break;
13278 }
13279
13280 case detail::value_t::array:
13281 {
13282 if (JSON_UNLIKELY(reference_token == "-"))
13283 {
13284 // "-" cannot be used for const access
13285 JSON_THROW(detail::out_of_range::create(402,
13286 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13287 ") is out of range"));
13288 }
13289
13290 // error condition (cf. RFC 6901, Sect. 4)
13291 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13292 {
13293 JSON_THROW(detail::parse_error::create(106, 0,
13294 "array index '" + reference_token +
13295 "' must not begin with '0'"));
13296 }
13297
13298 // use unchecked array access
13299 JSON_TRY
13300 {
13301 ptr = &ptr->operator[](
13302 static_cast<size_type>(std::stoi(reference_token)));
13303 }
13304 JSON_CATCH(std::invalid_argument&)
13305 {
13306 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13307 }
13308 break;
13309 }
13310
13311 default:
13312 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13313 }
13314 }
13315
13316 return *ptr;
13317 }
13318
13319 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13320 const NLOHMANN_BASIC_JSON_TPL&
get_checked(const NLOHMANN_BASIC_JSON_TPL * ptr) const13321 json_pointer::get_checked(const NLOHMANN_BASIC_JSON_TPL* ptr) const
13322 {
13323 using size_type = typename NLOHMANN_BASIC_JSON_TPL::size_type;
13324 for (const auto& reference_token : reference_tokens)
13325 {
13326 switch (ptr->m_type)
13327 {
13328 case detail::value_t::object:
13329 {
13330 // note: at performs range check
13331 ptr = &ptr->at(reference_token);
13332 break;
13333 }
13334
13335 case detail::value_t::array:
13336 {
13337 if (JSON_UNLIKELY(reference_token == "-"))
13338 {
13339 // "-" always fails the range check
13340 JSON_THROW(detail::out_of_range::create(402,
13341 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13342 ") is out of range"));
13343 }
13344
13345 // error condition (cf. RFC 6901, Sect. 4)
13346 if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
13347 {
13348 JSON_THROW(detail::parse_error::create(106, 0,
13349 "array index '" + reference_token +
13350 "' must not begin with '0'"));
13351 }
13352
13353 // note: at performs range check
13354 JSON_TRY
13355 {
13356 ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
13357 }
13358 JSON_CATCH(std::invalid_argument&)
13359 {
13360 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
13361 }
13362 break;
13363 }
13364
13365 default:
13366 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
13367 }
13368 }
13369
13370 return *ptr;
13371 }
13372
13373 NLOHMANN_BASIC_JSON_TPL_DECLARATION
flatten(const std::string & reference_string,const NLOHMANN_BASIC_JSON_TPL & value,NLOHMANN_BASIC_JSON_TPL & result)13374 void json_pointer::flatten(const std::string& reference_string,
13375 const NLOHMANN_BASIC_JSON_TPL& value,
13376 NLOHMANN_BASIC_JSON_TPL& result)
13377 {
13378 switch (value.m_type)
13379 {
13380 case detail::value_t::array:
13381 {
13382 if (value.m_value.array->empty())
13383 {
13384 // flatten empty array as null
13385 result[reference_string] = nullptr;
13386 }
13387 else
13388 {
13389 // iterate array and use index as reference string
13390 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13391 {
13392 flatten(reference_string + "/" + std::to_string(i),
13393 value.m_value.array->operator[](i), result);
13394 }
13395 }
13396 break;
13397 }
13398
13399 case detail::value_t::object:
13400 {
13401 if (value.m_value.object->empty())
13402 {
13403 // flatten empty object as null
13404 result[reference_string] = nullptr;
13405 }
13406 else
13407 {
13408 // iterate object and use keys as reference string
13409 for (const auto& element : *value.m_value.object)
13410 {
13411 flatten(reference_string + "/" + escape(element.first), element.second, result);
13412 }
13413 }
13414 break;
13415 }
13416
13417 default:
13418 {
13419 // add primitive value with its reference string
13420 result[reference_string] = value;
13421 break;
13422 }
13423 }
13424 }
13425
13426 NLOHMANN_BASIC_JSON_TPL_DECLARATION
13427 NLOHMANN_BASIC_JSON_TPL
unflatten(const NLOHMANN_BASIC_JSON_TPL & value)13428 json_pointer::unflatten(const NLOHMANN_BASIC_JSON_TPL& value)
13429 {
13430 if (JSON_UNLIKELY(not value.is_object()))
13431 {
13432 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened"));
13433 }
13434
13435 NLOHMANN_BASIC_JSON_TPL result;
13436
13437 // iterate the JSON object values
13438 for (const auto& element : *value.m_value.object)
13439 {
13440 if (JSON_UNLIKELY(not element.second.is_primitive()))
13441 {
13442 JSON_THROW(detail::type_error::create(315, "values in object must be primitive"));
13443 }
13444
13445 // assign value to reference pointed to by JSON pointer; Note that if
13446 // the JSON pointer is "" (i.e., points to the whole value), function
13447 // get_and_create returns a reference to result itself. An assignment
13448 // will then create a primitive value.
13449 json_pointer(element.first).get_and_create(result) = element.second;
13450 }
13451
13452 return result;
13453 }
13454
operator ==(json_pointer const & lhs,json_pointer const & rhs)13455 inline bool operator==(json_pointer const& lhs, json_pointer const& rhs) noexcept
13456 {
13457 return (lhs.reference_tokens == rhs.reference_tokens);
13458 }
13459
operator !=(json_pointer const & lhs,json_pointer const & rhs)13460 inline bool operator!=(json_pointer const& lhs, json_pointer const& rhs) noexcept
13461 {
13462 return not (lhs == rhs);
13463 }
13464 } // namespace nlohmann
13465
13466
13467 ///////////////////////
13468 // nonmember support //
13469 ///////////////////////
13470
13471 // specialization of std::swap, and std::hash
13472 namespace std
13473 {
13474 /*!
13475 @brief exchanges the values of two JSON objects
13476 @since version 1.0.0
13477 */
13478 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)13479 inline void swap(nlohmann::json& j1,
13480 nlohmann::json& j2) noexcept(
13481 is_nothrow_move_constructible<nlohmann::json>::value and
13482 is_nothrow_move_assignable<nlohmann::json>::value
13483 )
13484 {
13485 j1.swap(j2);
13486 }
13487
13488 /// hash value for JSON objects
13489 template<>
13490 struct hash<nlohmann::json>
13491 {
13492 /*!
13493 @brief return a hash value for a JSON object
13494 @since version 1.0.0
13495 */
operator ()std::hash13496 std::size_t operator()(const nlohmann::json& j) const
13497 {
13498 // a naive hashing via the string representation
13499 const auto& h = hash<nlohmann::json::string_t>();
13500 return h(j.dump());
13501 }
13502 };
13503
13504 /// specialization for std::less<value_t>
13505 /// @note: do not remove the space after '<',
13506 /// see https://github.com/nlohmann/json/pull/679
13507 template<>
13508 struct less< ::nlohmann::detail::value_t>
13509 {
13510 /*!
13511 @brief compare two value_t enum values
13512 @since version 3.0.0
13513 */
operator ()std::less13514 bool operator()(nlohmann::detail::value_t lhs,
13515 nlohmann::detail::value_t rhs) const noexcept
13516 {
13517 return nlohmann::detail::operator<(lhs, rhs);
13518 }
13519 };
13520
13521 } // namespace std
13522
13523 /*!
13524 @brief user-defined string literal for JSON values
13525 This operator implements a user-defined string literal for JSON objects. It
13526 can be used by adding `"_json"` to a string literal and returns a JSON object
13527 if no parse error occurred.
13528 @param[in] s a string representation of a JSON object
13529 @param[in] n the length of string @a s
13530 @return a JSON object
13531 @since version 1.0.0
13532 */
operator ""_json(const char * s,std::size_t n)13533 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
13534 {
13535 return nlohmann::json::parse(s, s + n);
13536 }
13537
13538 /*!
13539 @brief user-defined string literal for JSON pointer
13540 This operator implements a user-defined string literal for JSON Pointers. It
13541 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
13542 object if no parse error occurred.
13543 @param[in] s a string representation of a JSON Pointer
13544 @param[in] n the length of string @a s
13545 @return a JSON pointer object
13546 @since version 2.0.0
13547 */
operator ""_json_pointer(const char * s,std::size_t n)13548 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
13549 {
13550 return nlohmann::json::json_pointer(std::string(s, n));
13551 }
13552
13553 // restore GCC/clang diagnostic settings
13554 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
13555 #pragma GCC diagnostic pop
13556 #endif
13557 #if defined(__clang__)
13558 #pragma GCC diagnostic pop
13559 #endif
13560
13561 // clean up
13562 #undef JSON_CATCH
13563 #undef JSON_THROW
13564 #undef JSON_TRY
13565 #undef JSON_LIKELY
13566 #undef JSON_UNLIKELY
13567 #undef JSON_DEPRECATED
13568 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
13569 #undef NLOHMANN_BASIC_JSON_TPL
13570
13571 #endif
13572